Compare commits

..

23 Commits

Author SHA1 Message Date
Andrew Welker
7fe2d04d31 fix: add removal of RouteRequest when calling ReleaseRoute 2022-09-01 12:29:19 -06:00
Andrew Welker
358f44cfe5 refactor: remove completed request from dictionary 2022-09-01 11:57:40 -06:00
Andrew Welker
d7cccc0709 feat: add cooldown logic to Magic Routing
In some cases, a route can be requested while a sink is cooling down.
In those cases, the routing logic should keep track of requests for a
destination and wait until cooling is complete to request the new
route.
2022-09-01 11:47:52 -06:00
Andrew Welker
81b1117310 Merge pull request #988 from PepperDash/feature/cen-io-ir-104
Add Support for CEN-IO devices
2022-08-31 14:47:58 -06:00
jdevito
fb689c4484 fix: updated CEN-IO classes inheriting from EssentialsDevice to CrestronGenericBaseDevice to resolve activation issues 2022-08-31 14:43:58 -05:00
jdevito
40cb1b0fcf Merge remote-tracking branch 'origin/hotfix/huddle-room-interfaces' into feature/cen-io-ir-104 2022-08-31 11:55:15 -05:00
Jason DeVito
4574941288 fix: updated debug statement for DinCenCnController class referencing building a temp sensor device 2022-08-30 22:11:33 -05:00
Jason DeVito
122abc56e5 fix: added null checks in BuildDevice with debug statements if null 2022-08-30 22:02:47 -05:00
Jason DeVito
074ee190ad feat: added cen-io-ir-104 device and factory 2022-08-30 21:53:41 -05:00
Andrew Welker
68a0157fbe fix: add missing interface 2022-08-30 13:57:53 -06:00
Andrew Welker
e5393deea8 Merge pull request #980 from PepperDash/hotfix/zoomroom-bridge-updates
Hotfix/zoomroom bridge updates
2022-08-10 16:28:16 -06:00
Jason DeVito
c446c3a976 fix: updates to resolve directory display issues on touch panel when bridged 2022-08-10 17:12:30 -05:00
Jason DeVito
49e44ec850 fix: updated VideoCodecBase UpdateDirectoryXSig to handle directory results that are greater than 1023, XSig maximimum index 2022-08-10 15:49:41 -05:00
Andrew Welker
0ec42f8de2 Merge pull request #976 from PepperDash/hotfix/fix-lightingScene-scene-select-index
Lighting and Display Base updates to support extending joinMaps
2022-08-08 13:29:01 -06:00
Jason DeVito
008c82edb9 fix: updated lighting and display base; fix: lightingBase scene recall link to api index out of range exception 2022-08-08 13:54:17 -05:00
Neil Dorin
3033322212 Merge pull request #973 from PepperDash/hotfix/multiple-display-routing-support
Fix interface type check for routing
2022-08-01 12:34:16 -06:00
Neil Dorin
5b350c7a0c Updates interface type for other condition 2022-08-01 12:19:43 -06:00
Neil Dorin
afd2198eef Uses a less specific interface type for routing 2022-08-01 12:19:28 -06:00
Neil Dorin
05dadbe8ee Merge pull request #963 from PepperDash/hotfix/typo-in-RoutingPort-constructor
Hotfix/typo in routing port constructor
2022-06-22 09:54:43 -06:00
Neil Dorin
c39fd231bf Merge pull request #914 from Willis1776/bugfix/routingPort-typo-isInternal-Constructor
Typo in RoutingPort Constructor - isInternal
2022-06-22 09:38:30 -06:00
Neil Dorin
0df587071d Merge branch 'main' into bugfix/routingPort-typo-isInternal-Constructor 2022-06-22 09:14:31 -06:00
Neil Dorin
cd4f2d5edd Merge pull request #952 from PepperDash/hotfix/c2nio-factory-reference-update
fix: corrects issue #951, c2nio incorrect factory reference
2022-06-08 14:29:43 -06:00
Michael Willis
5f668c7173 Typo in RoutingPort Constructor - isInternal 2022-03-08 09:42:53 -07:00
38 changed files with 743 additions and 1307 deletions

View File

@@ -490,17 +490,21 @@ namespace PepperDash.Essentials
} }
} }
AddRoomAndBuildMC(room);
if (room is IEssentialsHuddleSpaceRoom) if (room is IEssentialsHuddleSpaceRoom)
{ {
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey)); DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
CreateMobileControlBridge(room);
} }
else if (room is IEssentialsHuddleVtc1Room) else if (room is IEssentialsHuddleVtc1Room)
{ {
DeviceManager.AddDevice(room);
if (!(room is EssentialsCombinedHuddleVtc1Room)) if (!(room is EssentialsCombinedHuddleVtc1Room))
{ {
@@ -508,15 +512,28 @@ namespace PepperDash.Essentials
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey)); DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
} }
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
CreateMobileControlBridge(room);
} }
else if (room is EssentialsTechRoom) else if (room is EssentialsTechRoom)
{ {
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, Debug.Console(0, Debug.ErrorLogLevel.Notice,
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId); "Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey)); DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
CreateMobileControlBridge(room);
} }
else
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsRoom, attempting to add to DeviceManager w/o Fusion");
DeviceManager.AddDevice(room);
}
fusionIpId += 1; fusionIpId += 1;
} }
else else
@@ -530,15 +547,6 @@ namespace PepperDash.Essentials
} }
private static void AddRoomAndBuildMC(IEssentialsRoom room)
{
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
CreateMobileControlBridge(room);
}
private static void CreateMobileControlBridge(object room) private static void CreateMobileControlBridge(object room)
{ {
var mobileControl = GetMobileControlDevice(); var mobileControl = GetMobileControlDevice();

View File

@@ -19,41 +19,32 @@ namespace PepperDash.Essentials.Room.Config
/// Returns a room object from this config data /// Returns a room object from this config data
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public static IKeyed GetRoomObject(DeviceConfig roomConfig) public static Device GetRoomObject(DeviceConfig roomConfig)
{ {
var typeName = roomConfig.Type.ToLower(); var typeName = roomConfig.Type.ToLower();
switch (typeName) if (typeName == "huddle")
{
return new EssentialsHuddleSpaceRoom(roomConfig);
}
if (typeName == "huddlevtc1")
{ {
case "huddle" : return new EssentialsHuddleVtc1Room(roomConfig);
{
return new EssentialsHuddleSpaceRoom(roomConfig);
}
case "huddlevtc1" :
{
return new EssentialsHuddleVtc1Room(roomConfig);
}
case "ddvc01bridge" :
{
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
}
case "dualdisplay" :
{
return new EssentialsDualDisplayRoom(roomConfig);
}
case "combinedhuddlevtc1" :
{
return new EssentialsCombinedHuddleVtc1Room(roomConfig);
}
case "techroom" :
{
return new EssentialsTechRoom(roomConfig);
}
default :
{
return Core.DeviceFactory.GetDevice(roomConfig);
}
} }
if (typeName == "ddvc01bridge")
{
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
}
if (typeName == "dualdisplay")
{
return new EssentialsDualDisplayRoom(roomConfig);
}
if (typeName == "combinedhuddlevtc1")
{
return new EssentialsCombinedHuddleVtc1Room(roomConfig);
}
return typeName != "techroom" ? null : new EssentialsTechRoom(roomConfig);
} }
/// <summary> /// <summary>

View File

@@ -708,11 +708,12 @@ namespace PepperDash.Essentials
IRoutingSink dest = null; IRoutingSink dest = null;
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase)) if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
dest = DefaultAudioDevice as IRoutingSinkNoSwitching; dest = DefaultAudioDevice as IRoutingSink;
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase)) else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
dest = DefaultDisplay; dest = DefaultDisplay;
else else
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching; dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink;
if (dest == null) if (dest == null)
{ {

View File

@@ -7,7 +7,7 @@ using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials namespace PepperDash.Essentials
{ {
public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay, IHasCurrentVolumeControls
{ {
bool ExcludeFromGlobalFunctions { get; } bool ExcludeFromGlobalFunctions { get; }

View File

@@ -1,60 +0,0 @@
using System;
namespace PepperDash.Essentials.Core.Bridges
{
public class PduJoinMapBase : JoinMapBaseAdvanced
{
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "PDU Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("Online")]
public JoinDataComplete Online = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "PDU Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletCount")]
public JoinDataComplete OutletCount = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Number of COntrolled Outlets", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
[JoinName("OutletName")]
public JoinDataComplete OutletName = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("OutletEnabled")]
public JoinDataComplete OutletEnabled = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Enabled", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletPowerCycle")]
public JoinDataComplete OutletPowerCycle = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Power Cycle", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletPowerOn")]
public JoinDataComplete OutletPowerOn = new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Power On", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletPowerOff")]
public JoinDataComplete OutletPowerOff = new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Power Off", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
/// <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 PduJoinMapBase(uint joinStart)
:base(joinStart, typeof(PduJoinMapBase))
{
}
/// <summary>
/// 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>
public PduJoinMapBase(uint joinStart, Type type)
: base(joinStart, type)
{
}
}
}

View File

@@ -1,4 +1,4 @@
using System; using System;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.Bridges.JoinMaps namespace PepperDash.Essentials.Core.Bridges.JoinMaps
{ {
@@ -1576,36 +1576,6 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Serial JoinType = eJoinType.Serial
}); });
[JoinName("AvailableLayoutsFb")]
public JoinDataComplete AvailableLayoutsFb = new JoinDataComplete(
new JoinData
{
JoinNumber = 142,
JoinSpan = 1
},
new JoinMetadata
{
Description = "xSig of all available layouts",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("SelectLayout")]
public JoinDataComplete SelectLayout = new JoinDataComplete(
new JoinData
{
JoinNumber = 142,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Select Layout by string",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("CurrentParticipants")] [JoinName("CurrentParticipants")]
public JoinDataComplete CurrentParticipants = new JoinDataComplete( public JoinDataComplete CurrentParticipants = new JoinDataComplete(
new JoinData new JoinData
@@ -3044,35 +3014,6 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
JoinType = eJoinType.Serial JoinType = eJoinType.Serial
}); });
[JoinName("AvailableLayoutsFb")]
public JoinDataComplete AvailableLayoutsFb = new JoinDataComplete(
new JoinData
{
JoinNumber = 142,
JoinSpan = 1
},
new JoinMetadata
{
Description = "xSig of all available layouts",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("SelectLayout")]
public JoinDataComplete SelectLayout = new JoinDataComplete(
new JoinData
{
JoinNumber = 142,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Select Layout by string",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("CurrentParticipants")] [JoinName("CurrentParticipants")]
public JoinDataComplete CurrentParticipants = new JoinDataComplete( public JoinDataComplete CurrentParticipants = new JoinDataComplete(
new JoinData new JoinData
@@ -3170,4 +3111,4 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
{ {
} }
} }
} }

View File

@@ -1,35 +1,35 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.Config namespace PepperDash.Essentials.Core.Config
{ {
public class DeviceConfig public class DeviceConfig
{ {
[JsonProperty("key")] [JsonProperty("key")]
public string Key { get; set; } public string Key { get; set; }
[JsonProperty("uid")] [JsonProperty("uid")]
public int Uid { get; set; } public int Uid { get; set; }
[JsonProperty("name")] [JsonProperty("name")]
public string Name { get; set; } public string Name { get; set; }
[JsonProperty("group")] [JsonProperty("group")]
public string Group { get; set; } public string Group { get; set; }
[JsonProperty("type")] [JsonProperty("type")]
public string Type { get; set; } public string Type { get; set; }
[JsonProperty("properties")] [JsonProperty("properties")]
[JsonConverter(typeof(DevicePropertiesConverter))] [JsonConverter(typeof(DevicePropertiesConverter))]
public JToken Properties { get; set; } public JToken Properties { get; set; }
public DeviceConfig(DeviceConfig dc) public DeviceConfig(DeviceConfig dc)
@@ -39,42 +39,39 @@ namespace PepperDash.Essentials.Core.Config
Name = dc.Name; Name = dc.Name;
Group = dc.Group; Group = dc.Group;
Type = dc.Type; Type = dc.Type;
Properties = JToken.FromObject(dc.Properties);
Properties = JToken.Parse(dc.Properties.ToString());
//Properties = JToken.FromObject(dc.Properties);
} }
public DeviceConfig() {} public DeviceConfig() {}
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class DevicePropertiesConverter : JsonConverter public class DevicePropertiesConverter : JsonConverter
{ {
public override bool CanConvert(Type objectType) public override bool CanConvert(Type objectType)
{ {
return objectType == typeof(JToken); return objectType == typeof(JToken);
} }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{ {
return JToken.ReadFrom(reader); return JToken.ReadFrom(reader);
} }
public override bool CanWrite public override bool CanWrite
{ {
get get
{ {
return false; return false;
} }
} }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{ {
throw new NotImplementedException("SOD OFF HOSER"); throw new NotImplementedException("SOD OFF HOSER");
} }
} }
} }

View File

@@ -34,7 +34,7 @@ namespace PepperDash.Essentials.Core
public override EssentialsDevice BuildDevice(DeviceConfig dc) public override EssentialsDevice BuildDevice(DeviceConfig dc)
{ {
Debug.Console(1, "Factory Attempting to create new C2N-RTHS Device"); Debug.Console(1, "Factory Attempting to create new DIN-CEN-CN2 Device");
var control = CommFactory.GetControlPropertiesConfig(dc); var control = CommFactory.GetControlPropertiesConfig(dc);
var ipid = control.IpIdInt; var ipid = control.IpIdInt;

View File

@@ -16,7 +16,7 @@ namespace PepperDash.Essentials.Core
/// Wrapper class for CEN-IO-DIGIN-104 digital input module /// Wrapper class for CEN-IO-DIGIN-104 digital input module
/// </summary> /// </summary>
[Description("Wrapper class for the CEN-IO-DIGIN-104 diginal input module")] [Description("Wrapper class for the CEN-IO-DIGIN-104 diginal input module")]
public class CenIoDigIn104Controller : EssentialsDevice, IDigitalInputPorts public class CenIoDigIn104Controller : CrestronGenericBaseDevice, IDigitalInputPorts
{ {
public CenIoDi104 Di104 { get; private set; } public CenIoDi104 Di104 { get; private set; }
@@ -52,10 +52,17 @@ namespace PepperDash.Essentials.Core
{ {
Debug.Console(1, "Factory Attempting to create new CEN-DIGIN-104 Device"); Debug.Console(1, "Factory Attempting to create new CEN-DIGIN-104 Device");
var control = CommFactory.GetControlPropertiesConfig(dc); var control = CommFactory.GetControlPropertiesConfig(dc);
var ipid = control.IpIdInt; if (control == null)
{
return new CenIoDigIn104Controller(dc.Key, dc.Name, new Crestron.SimplSharpPro.GeneralIO.CenIoDi104(ipid, Global.ControlSystem)); Debug.Console(1, "Factory failed to create a new CEN-DIGIN-104 Device, control properties not found");
return null;
}
var ipid = control.IpIdInt;
if (ipid != 0) return new CenIoDigIn104Controller(dc.Key, dc.Name, new CenIoDi104(ipid, Global.ControlSystem));
Debug.Console(1, "Factory failed to create a new CEN-IO-IR-104 Device using IP-ID-{0}", ipid);
return null;
} }
} }

View File

@@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Essentials.Core.Config;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Wrapper class for CEN-IO-IR-104 module
/// </summary>
[Description("Wrapper class for the CEN-IO-IR-104 module")]
public class CenIoIr104Controller : CrestronGenericBaseDevice, IIROutputPorts
{
private readonly CenIoIr104 _ir104;
/// <summary>
/// Constructor
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="ir104"></param>
public CenIoIr104Controller(string key, string name, CenIoIr104 ir104)
: base(key, name, ir104)
{
_ir104 = ir104;
}
#region IDigitalInputPorts Members
/// <summary>
/// IR port collection
/// </summary>
public CrestronCollection<IROutputPort> IROutputPorts
{
get { return _ir104.IROutputPorts; }
}
/// <summary>
/// Number of relay ports property
/// </summary>
public int NumberOfIROutputPorts
{
get { return _ir104.NumberOfIROutputPorts; }
}
#endregion
}
/// <summary>
/// CEN-IO-IR-104 controller fatory
/// </summary>
public class CenIoIr104ControllerFactory : EssentialsDeviceFactory<CenIoIr104Controller>
{
/// <summary>
/// Constructor
/// </summary>
public CenIoIr104ControllerFactory()
{
TypeNames = new List<string>() { "cenioir104" };
}
/// <summary>
/// Build device CEN-IO-IR-104
/// </summary>
/// <param name="dc"></param>
/// <returns></returns>
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new CEN-IO-IR-104 Device");
var control = CommFactory.GetControlPropertiesConfig(dc);
if (control == null)
{
Debug.Console(1, "Factory failed to create a new CEN-IO-IR-104 Device, control properties not found");
return null;
}
var ipid = control.IpIdInt;
if(ipid != 0) return new CenIoIr104Controller(dc.Key, dc.Name, new CenIoIr104(ipid, Global.ControlSystem));
Debug.Console(1, "Factory failed to create a new CEN-IO-IR-104 Device using IP-ID-{0}", ipid);
return null;
}
}
}

View File

@@ -10,7 +10,7 @@ namespace PepperDash.Essentials.Core
/// Wrapper class for CEN-IO-RY-104 relay module /// Wrapper class for CEN-IO-RY-104 relay module
/// </summary> /// </summary>
[Description("Wrapper class for the CEN-IO-RY-104 relay module")] [Description("Wrapper class for the CEN-IO-RY-104 relay module")]
public class CenIoRy104Controller : EssentialsDevice, IRelayPorts public class CenIoRy104Controller : CrestronGenericBaseDevice, IRelayPorts
{ {
private readonly CenIoRy104 _ry104; private readonly CenIoRy104 _ry104;
@@ -21,7 +21,7 @@ namespace PepperDash.Essentials.Core
/// <param name="name"></param> /// <param name="name"></param>
/// <param name="ry104"></param> /// <param name="ry104"></param>
public CenIoRy104Controller(string key, string name, CenIoRy104 ry104) public CenIoRy104Controller(string key, string name, CenIoRy104 ry104)
: base(key, name) : base(key, name, ry104)
{ {
_ry104 = ry104; _ry104 = ry104;
} }
@@ -62,8 +62,8 @@ namespace PepperDash.Essentials.Core
var controlPropertiesConfig = CommFactory.GetControlPropertiesConfig(dc); var controlPropertiesConfig = CommFactory.GetControlPropertiesConfig(dc);
if (controlPropertiesConfig == null) if (controlPropertiesConfig == null)
{ {
Debug.Console(1, "Factory failed to create a new CEN-IO-RY-104 Device"); Debug.Console(1, "Factory failed to create a new CEN-IO-RY-104 Device, control properties not found");
return null; return null;
} }

View File

@@ -7,61 +7,25 @@ using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core namespace PepperDash.Essentials.Core
{ {
/// <summary> /// <summary>
/// Defines minimal volume and mute control methods /// Defines minimal volume control methods
/// </summary> /// </summary>
public interface IBasicVolumeControls public interface IBasicVolumeControls
{ {
void VolumeUp(bool pressRelease); void VolumeUp(bool pressRelease);
void VolumeDown(bool pressRelease); void VolumeDown(bool pressRelease);
void MuteToggle(); void MuteToggle();
} }
/// <summary>
/// Defines basic volume control methods
/// </summary>
public interface IHasVolumeControl
{
void VolumeUp(bool pressRelease);
void VolumeDown(bool pressRelease);
}
/// <summary>
/// Defines volume control methods and properties with feedback
/// </summary>
public interface IHasVolumeControlWithFeedback : IHasVolumeControl
{
void SetVolume(ushort level);
IntFeedback VolumeLevelFeedback { get; }
}
/// <summary>
/// Defines basic mute control methods
/// </summary>
public interface IHasMuteControl
{
void MuteToggle();
}
/// <summary>
/// Defines mute control methods and properties with feedback
/// </summary>
public interface IHasMuteControlWithFeedback : IHasMuteControl
{
BoolFeedback MuteFeedback { get; }
void MuteOn();
void MuteOff();
}
/// <summary> /// <summary>
/// Adds feedback and direct volume level set to IBasicVolumeControls /// Adds feedback and direct volume level set to IBasicVolumeControls
/// </summary> /// </summary>
public interface IBasicVolumeWithFeedback : IBasicVolumeControls public interface IBasicVolumeWithFeedback : IBasicVolumeControls
{ {
BoolFeedback MuteFeedback { get; }
void MuteOn();
void MuteOff();
void SetVolume(ushort level); void SetVolume(ushort level);
void MuteOn();
void MuteOff();
IntFeedback VolumeLevelFeedback { get; } IntFeedback VolumeLevelFeedback { get; }
BoolFeedback MuteFeedback { get; }
} }
/// <summary> /// <summary>

View File

@@ -1,35 +0,0 @@
using System.Collections.Generic;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash_Essentials_Core.Devices
{
/// <summary>
/// Interface for any device that is able to control it'spower and has a configurable reboot time
/// </summary>
public interface IHasPowerCycle : IKeyName, IHasPowerControlWithFeedback
{
/// <summary>
/// Delay between power off and power on for reboot
/// </summary>
int PowerCycleTimeMs { get;}
/// <summary>
/// Reboot outlet
/// </summary>
void PowerCycle();
}
/// <summary>
/// Interface for any device that contains a collection of IHasPowerReboot Devices
/// </summary>
public interface IHasControlledPowerOutlets : IKeyName
{
/// <summary>
/// Collection of IPduOutlets
/// </summary>
ReadOnlyDictionary<int, IHasPowerCycle> PduOutlets { get; }
}
}

View File

@@ -59,7 +59,7 @@ namespace PepperDash.Essentials.Core.Devices
/// <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>
/// <param name="config"></param> /// <param name="Config"></param>
protected virtual void CustomSetConfig(DeviceConfig config) protected virtual void CustomSetConfig(DeviceConfig config)
{ {
ConfigWriter.UpdateDeviceConfig(config); ConfigWriter.UpdateDeviceConfig(config);

View File

@@ -105,9 +105,6 @@ namespace PepperDash.Essentials.Core
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey, protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
EiscApiAdvanced bridge) EiscApiAdvanced bridge)
{ {
var inputNumber = 0;
var inputKeys = new List<string>();
var joinMap = new DisplayControllerJoinMap(joinStart); var joinMap = new DisplayControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
@@ -124,133 +121,141 @@ namespace PepperDash.Essentials.Core
Debug.Console(0,this,"Please update config to use 'eiscapiadvanced' to get all join map features for this device."); Debug.Console(0,this,"Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
} }
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); LinkDisplayToApi(displayDevice, trilist, joinMap);
Debug.Console(0, "Linking to Display: {0}", displayDevice.Name);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
var commMonitor = displayDevice as ICommunicationMonitor;
if (commMonitor != null)
{
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
}
var inputNumberFeedback = new IntFeedback(() => inputNumber);
// Two way feedbacks
var twoWayDisplay = displayDevice as TwoWayDisplayBase;
if (twoWayDisplay != null)
{
trilist.SetBool(joinMap.IsTwoWayDisplay.JoinNumber, true);
twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => Debug.Console(0, "CurrentInputFeedback_OutputChange {0}", a.StringValue);
inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect.JoinNumber]);
}
// Power Off
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
{
inputNumber = 102;
inputNumberFeedback.FireUpdate();
displayDevice.PowerOff();
});
var twoWayDisplayDevice = displayDevice as TwoWayDisplayBase;
if (twoWayDisplayDevice != null)
{
twoWayDisplayDevice.PowerIsOnFeedback.OutputChange += (o, a) =>
{
if (!a.BoolValue)
{
inputNumber = 102;
inputNumberFeedback.FireUpdate();
}
else
{
inputNumber = 0;
inputNumberFeedback.FireUpdate();
}
};
twoWayDisplayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
twoWayDisplayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
}
// PowerOn
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () =>
{
inputNumber = 0;
inputNumberFeedback.FireUpdate();
displayDevice.PowerOn();
});
for (int i = 0; i < displayDevice.InputPorts.Count; i++)
{
if (i < joinMap.InputNamesOffset.JoinSpan)
{
inputKeys.Add(displayDevice.InputPorts[i].Key);
var tempKey = inputKeys.ElementAt(i);
trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + i),
() => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector));
Debug.Console(2, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}",
joinMap.InputSelectOffset.JoinNumber + i, displayDevice.InputPorts[tempKey].Key.ToString());
trilist.StringInput[(ushort)(joinMap.InputNamesOffset.JoinNumber + i)].StringValue = displayDevice.InputPorts[i].Key.ToString();
}
else
Debug.Console(0, displayDevice, Debug.ErrorLogLevel.Warning, "Device has {0} inputs. The Join Map allows up to {1} inputs. Discarding inputs {2} - {3} from bridge.",
displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, i + 1, displayDevice.InputPorts.Count);
}
Debug.Console(2, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect);
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (a) =>
{
if (a == 0)
{
displayDevice.PowerOff();
inputNumber = 0;
}
else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber)
{
displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector);
inputNumber = a;
}
else if (a == 102)
{
displayDevice.PowerToggle();
}
if (twoWayDisplay != null)
inputNumberFeedback.FireUpdate();
});
var volumeDisplay = displayDevice as IBasicVolumeControls;
if (volumeDisplay == null) return;
trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, volumeDisplay.VolumeUp);
trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, volumeDisplay.VolumeDown);
trilist.SetSigTrueAction(joinMap.VolumeMute.JoinNumber, volumeDisplay.MuteToggle);
var volumeDisplayWithFeedback = volumeDisplay as IBasicVolumeWithFeedback;
if (volumeDisplayWithFeedback == null) return;
trilist.SetSigTrueAction(joinMap.VolumeMuteOn.JoinNumber, volumeDisplayWithFeedback.MuteOn);
trilist.SetSigTrueAction(joinMap.VolumeMuteOff.JoinNumber, volumeDisplayWithFeedback.MuteOff);
trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, volumeDisplayWithFeedback.SetVolume);
volumeDisplayWithFeedback.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMute.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
} }
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, DisplayControllerJoinMap joinMap)
{
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to Display: {0}", displayDevice.Name);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
var commMonitor = displayDevice as ICommunicationMonitor;
if (commMonitor != null)
{
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
}
var inputNumber = 0;
var inputKeys = new List<string>();
var inputNumberFeedback = new IntFeedback(() => inputNumber);
// Two way feedbacks
var twoWayDisplay = displayDevice as TwoWayDisplayBase;
if (twoWayDisplay != null)
{
trilist.SetBool(joinMap.IsTwoWayDisplay.JoinNumber, true);
twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => Debug.Console(0, "CurrentInputFeedback_OutputChange {0}", a.StringValue);
inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect.JoinNumber]);
}
// Power Off
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
{
inputNumber = 102;
inputNumberFeedback.FireUpdate();
displayDevice.PowerOff();
});
var twoWayDisplayDevice = displayDevice as TwoWayDisplayBase;
if (twoWayDisplayDevice != null)
{
twoWayDisplayDevice.PowerIsOnFeedback.OutputChange += (o, a) =>
{
if (!a.BoolValue)
{
inputNumber = 102;
inputNumberFeedback.FireUpdate();
}
else
{
inputNumber = 0;
inputNumberFeedback.FireUpdate();
}
};
twoWayDisplayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
twoWayDisplayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
}
// PowerOn
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () =>
{
inputNumber = 0;
inputNumberFeedback.FireUpdate();
displayDevice.PowerOn();
});
for (int i = 0; i < displayDevice.InputPorts.Count; i++)
{
if (i < joinMap.InputNamesOffset.JoinSpan)
{
inputKeys.Add(displayDevice.InputPorts[i].Key);
var tempKey = inputKeys.ElementAt(i);
trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + i),
() => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector));
Debug.Console(2, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}",
joinMap.InputSelectOffset.JoinNumber + i, displayDevice.InputPorts[tempKey].Key.ToString());
trilist.StringInput[(ushort)(joinMap.InputNamesOffset.JoinNumber + i)].StringValue = displayDevice.InputPorts[i].Key.ToString();
}
else
Debug.Console(0, displayDevice, Debug.ErrorLogLevel.Warning, "Device has {0} inputs. The Join Map allows up to {1} inputs. Discarding inputs {2} - {3} from bridge.",
displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, i + 1, displayDevice.InputPorts.Count);
}
Debug.Console(2, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect);
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (a) =>
{
if (a == 0)
{
displayDevice.PowerOff();
inputNumber = 0;
}
else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber)
{
displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector);
inputNumber = a;
}
else if (a == 102)
{
displayDevice.PowerToggle();
}
if (twoWayDisplay != null)
inputNumberFeedback.FireUpdate();
});
var volumeDisplay = displayDevice as IBasicVolumeControls;
if (volumeDisplay == null) return;
trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, volumeDisplay.VolumeUp);
trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, volumeDisplay.VolumeDown);
trilist.SetSigTrueAction(joinMap.VolumeMute.JoinNumber, volumeDisplay.MuteToggle);
var volumeDisplayWithFeedback = volumeDisplay as IBasicVolumeWithFeedback;
if (volumeDisplayWithFeedback == null) return;
trilist.SetSigTrueAction(joinMap.VolumeMuteOn.JoinNumber, volumeDisplayWithFeedback.MuteOn);
trilist.SetSigTrueAction(joinMap.VolumeMuteOff.JoinNumber, volumeDisplayWithFeedback.MuteOff);
trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, volumeDisplayWithFeedback.SetVolume);
volumeDisplayWithFeedback.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMute.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
}
} }
/// <summary> /// <summary>

View File

@@ -1,278 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using PepperDash.Core;
using Crestron.SimplSharpPro.CrestronThread;
namespace PepperDash.Essentials.Core
{
public static class FileIO
{
static CCriticalSection fileLock = new CCriticalSection();
public delegate void GotFileEventHandler(object sender, FileEventArgs e);
public static event GotFileEventHandler GotFileEvent;
/// <summary>
/// Get the full file info from a path/filename, can include wildcards.
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static FileInfo[] GetFiles(string fileName)
{
DirectoryInfo dirInfo = new DirectoryInfo(Path.GetDirectoryName(fileName));
var files = dirInfo.GetFiles(Path.GetFileName(fileName));
Debug.Console(0, "FileIO found: {0}, {1}", files.Count(), fileName);
if (files.Count() > 0)
{
return files;
}
else
{
return null;
}
}
public static FileInfo GetFile(string fileName)
{
DirectoryInfo dirInfo = new DirectoryInfo(Path.GetDirectoryName(fileName));
var files = dirInfo.GetFiles(Path.GetFileName(fileName));
Debug.Console(0, "FileIO found: {0}, {1}", files.Count(), fileName);
if (files.Count() > 0)
{
return files.FirstOrDefault();
}
else
{
return null;
}
}
/// <summary>
/// Get the data from string path/filename
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string ReadDataFromFile(string fileName)
{
try
{
return ReadDataFromFile(GetFile(fileName));
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
return "";
}
}
/// <summary>
/// Get the data with fileInfo object
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string ReadDataFromFile(FileInfo file)
{
try
{
if (fileLock.TryEnter())
{
DirectoryInfo dirInfo = new DirectoryInfo(file.Name);
Debug.Console(2, "FileIO Getting Data {0}", file.FullName);
if (File.Exists(file.FullName))
{
using (StreamReader r = new StreamReader(file.FullName))
{
return r.ReadToEnd();
}
}
else
{
Debug.Console(2, "File {0} does not exsist", file.FullName);
return "";
}
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "FileIO Unable to enter FileLock");
return "";
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
return "";
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
}
public static void ReadDataFromFileASync(string fileName)
{
try
{
ReadDataFromFileASync(GetFile(fileName));
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
}
}
public static void ReadDataFromFileASync(FileInfo file)
{
try
{
CrestronInvoke.BeginInvoke(o => _ReadDataFromFileASync(file));
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
}
}
private static void _ReadDataFromFileASync(FileInfo file)
{
string data;
try
{
if (fileLock.TryEnter())
{
DirectoryInfo dirInfo = new DirectoryInfo(file.Name);
Debug.Console(2, "FileIO Getting Data {0}", file.FullName);
if (File.Exists(file.FullName))
{
using (StreamReader r = new StreamReader(file.FullName))
{
data = r.ReadToEnd();
}
}
else
{
Debug.Console(2, "File {0} Does not exsist", file.FullName);
data = "";
}
GotFileEvent.Invoke(null, new FileEventArgs(data));
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "FileIO Unable to enter FileLock");
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
data = "";
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
}
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="filePath"></param>
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="filePath"></param>
public static void WriteDataToFile(string data, string filePath)
{
Thread _WriteFileThread;
_WriteFileThread = new Thread((O) => _WriteFileMethod(data, filePath), null, Thread.eThreadStartOptions.CreateSuspended);
_WriteFileThread.Priority = Thread.eThreadPriority.LowestPriority;
_WriteFileThread.Start();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "New WriteFile Thread");
}
static object _WriteFileMethod(string data, string filePath)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write file: '{0}'", filePath);
try
{
if (fileLock.TryEnter())
{
using (StreamWriter sw = new StreamWriter(filePath))
{
sw.Write(data);
sw.Flush();
}
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "FileIO Unable to enter FileLock");
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO write failed: \r{0}", e);
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
return null;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static bool FileIoUnitTest()
{
var testData = "Testing FileIO";
FileIO.WriteDataToFile(testData, "\\user\\FileIOTest.pdt");
var file = FileIO.GetFile("\\user\\*FileIOTest*");
var readData = FileIO.ReadDataFromFile(file);
Debug.Console(0, "Returned {0}", readData);
File.Delete(file.FullName);
if (testData == readData)
{
return true;
}
else
{
return false;
}
}
}
public class FileEventArgs
{
public FileEventArgs(string data) { Data = data; }
public string Data { get; private set; } // readonly
}
}

View File

@@ -70,49 +70,71 @@ namespace PepperDash.Essentials.Core.Lighting
} }
} }
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart, protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart,
string joinMapKey, EiscApiAdvanced bridge) string joinMapKey, EiscApiAdvanced bridge)
{ {
var joinMap = new GenericLightingJoinMap(joinStart); var joinMap = new GenericLightingJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized)) if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<GenericLightingJoinMap>(joinMapSerialized); joinMap = JsonConvert.DeserializeObject<GenericLightingJoinMap>(joinMapSerialized);
if (bridge != null) if (bridge != null)
{ {
bridge.AddJoinMap(Key, joinMap); bridge.AddJoinMap(Key, joinMap);
} }
else else
{ {
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
} }
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); return LinkLightingToApi(lightingDevice, trilist, joinMap);
}
Debug.Console(0, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString()); protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, GenericLightingJoinMap joinMap)
{
// GenericLighitng Actions & FeedBack
trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
var sceneIndex = 0; Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
foreach (var scene in lightingDevice.LightingScenes)
{ Debug.Console(0, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString());
var index1 = sceneIndex;
trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex), () => // GenericLighitng Actions & FeedBack
{ trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
var index = index1;
Debug.Console(2, this, "LightingDevice: sceneIndex: {0} index: {1} > inside action", index1, index); var sceneIndex = 0;
lightingDevice.SelectScene(lightingDevice.LightingScenes[index]); foreach (var scene in lightingDevice.LightingScenes)
}); {
scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex)]); var index = sceneIndex;
trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex)].StringValue = scene.Name;
trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + sceneIndex)].BoolValue = true; trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + index), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[index]));
sceneIndex++; scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)]);
} trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
return joinMap; trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
}
sceneIndex++;
}
trilist.OnlineStatusChange += (sender, args) =>
{
if (!args.DeviceOnLine) return;
sceneIndex = 0;
foreach (var scene in lightingDevice.LightingScenes)
{
var index = sceneIndex;
trilist.StringInput[(uint) (joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
trilist.BooleanInput[(uint) (joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
scene.IsActiveFeedback.FireUpdate();
sceneIndex++;
}
};
return joinMap;
}
} }

View File

@@ -123,7 +123,6 @@
<Compile Include="Bridges\IBridge.cs" /> <Compile Include="Bridges\IBridge.cs" />
<Compile Include="Bridges\JoinMaps\AirMediaControllerJoinMap.cs" /> <Compile Include="Bridges\JoinMaps\AirMediaControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\AppleTvJoinMap.cs" /> <Compile Include="Bridges\JoinMaps\AppleTvJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\PduJoinMapBase.cs" />
<Compile Include="Bridges\JoinMaps\C2nRthsControllerJoinMap.cs" /> <Compile Include="Bridges\JoinMaps\C2nRthsControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\CameraControllerJoinMap.cs" /> <Compile Include="Bridges\JoinMaps\CameraControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\CenOdtOccupancySensorBaseJoinMap.cs" /> <Compile Include="Bridges\JoinMaps\CenOdtOccupancySensorBaseJoinMap.cs" />
@@ -184,6 +183,7 @@
<Compile Include="Crestron IO\Inputs\GenericVersiportInputDevice.cs" /> <Compile Include="Crestron IO\Inputs\GenericVersiportInputDevice.cs" />
<Compile Include="Crestron IO\Inputs\IDigitalInput.cs" /> <Compile Include="Crestron IO\Inputs\IDigitalInput.cs" />
<Compile Include="Crestron IO\IOPortConfig.cs" /> <Compile Include="Crestron IO\IOPortConfig.cs" />
<Compile Include="Crestron IO\Ir\CenIoIr104Controller.cs" />
<Compile Include="Crestron IO\Relay\CenIoRy104Controller.cs" /> <Compile Include="Crestron IO\Relay\CenIoRy104Controller.cs" />
<Compile Include="Crestron IO\Relay\GenericRelayDevice.cs" /> <Compile Include="Crestron IO\Relay\GenericRelayDevice.cs" />
<Compile Include="Crestron IO\Relay\ISwitchedOutput.cs" /> <Compile Include="Crestron IO\Relay\ISwitchedOutput.cs" />
@@ -204,7 +204,6 @@
<Compile Include="Devices\IReconfigurableDevice.cs" /> <Compile Include="Devices\IReconfigurableDevice.cs" />
<Compile Include="Devices\PC\InRoomPc.cs" /> <Compile Include="Devices\PC\InRoomPc.cs" />
<Compile Include="Devices\PC\Laptop.cs" /> <Compile Include="Devices\PC\Laptop.cs" />
<Compile Include="Devices\PduInterfaces.cs" />
<Compile Include="Devices\ReconfigurableDevice.cs" /> <Compile Include="Devices\ReconfigurableDevice.cs" />
<Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" /> <Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" />
<Compile Include="DeviceTypeInterfaces\IPasswordPrompt.cs" /> <Compile Include="DeviceTypeInterfaces\IPasswordPrompt.cs" />
@@ -226,7 +225,6 @@
<Compile Include="Feedbacks\IntFeedback.cs" /> <Compile Include="Feedbacks\IntFeedback.cs" />
<Compile Include="Feedbacks\SerialFeedback.cs" /> <Compile Include="Feedbacks\SerialFeedback.cs" />
<Compile Include="Feedbacks\StringFeedback.cs" /> <Compile Include="Feedbacks\StringFeedback.cs" />
<Compile Include="File\FileIO.cs" />
<Compile Include="Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs" /> <Compile Include="Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs" />
<Compile Include="Fusion\FusionCustomPropertiesBridge.cs" /> <Compile Include="Fusion\FusionCustomPropertiesBridge.cs" />
<Compile Include="Fusion\FusionEventHandlers.cs" /> <Compile Include="Fusion\FusionEventHandlers.cs" />
@@ -338,9 +336,7 @@
<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\CrestronGlobalSecretsProvider.cs" /> <Compile Include="Secrets\CrestronSecretsProvider.cs" />
<Compile Include="Secrets\CrestronLocalSecretsProvider.cs" />
<Compile Include="Secrets\CrestronSecret.cs" />
<Compile Include="Secrets\Interfaces.cs" /> <Compile Include="Secrets\Interfaces.cs" />
<Compile Include="Secrets\SecretsManager.cs" /> <Compile Include="Secrets\SecretsManager.cs" />
<Compile Include="Secrets\SecretsPropertiesConfig.cs" /> <Compile Include="Secrets\SecretsPropertiesConfig.cs" />

View File

@@ -11,12 +11,34 @@ using PepperDash.Core;
namespace PepperDash.Essentials.Core namespace PepperDash.Essentials.Core
{ {
public class RouteRequest
{
public IRoutingSink Destination {get; set;}
public IRoutingOutputs Source {get; set;}
public eRoutingSignalType SignalType {get; set;}
public void HandleCooldown(object sender, FeedbackEventArgs args)
{
var coolingDevice = sender as IWarmingCooling;
if(args.BoolValue == false)
{
Destination.ReleaseAndMakeRoute(Source, SignalType);
if(sender == null) return;
coolingDevice.IsCoolingDownFeedback.OutputChange -= HandleCooldown;
}
}
}
/// <summary> /// <summary>
/// Extensions added to any IRoutingInputs classes to provide discovery-based routing /// Extensions added to any IRoutingInputs classes to provide discovery-based routing
/// on those destinations. /// on those destinations.
/// </summary> /// </summary>
public static class IRoutingInputsExtensions public static class IRoutingInputsExtensions
{ {
private static Dictionary<string, RouteRequest> RouteRequests = new Dictionary<string, RouteRequest>();
/// <summary> /// <summary>
/// Gets any existing RouteDescriptor for a destination, clears it using ReleaseRoute /// Gets any existing RouteDescriptor for a destination, clears it using ReleaseRoute
/// and then attempts a new Route and if sucessful, stores that RouteDescriptor /// and then attempts a new Route and if sucessful, stores that RouteDescriptor
@@ -24,16 +46,58 @@ namespace PepperDash.Essentials.Core
/// </summary> /// </summary>
public static void ReleaseAndMakeRoute(this IRoutingSink destination, IRoutingOutputs source, eRoutingSignalType signalType) public static void ReleaseAndMakeRoute(this IRoutingSink destination, IRoutingOutputs source, eRoutingSignalType signalType)
{ {
destination.ReleaseRoute(); var routeRequest = new RouteRequest {
Destination = destination,
Source = source,
SignalType = signalType
};
if (source == null) return; var coolingDevice = destination as IWarmingCooling;
var newRoute = destination.GetRouteToSource(source, signalType);
if (newRoute == null) return; RouteRequest existingRouteRequest;
RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(newRoute);
Debug.Console(2, destination, "Executing full route"); //We already have a route request for this device, and it's a cooling device and is cooling
newRoute.ExecuteRoutes(); if (RouteRequests.TryGetValue(destination.Key, out existingRouteRequest) && coolingDevice != null && coolingDevice.IsCoolingDownFeedback.BoolValue == true)
{
coolingDevice.IsCoolingDownFeedback.OutputChange -= existingRouteRequest.HandleCooldown;
coolingDevice.IsCoolingDownFeedback.OutputChange += routeRequest.HandleCooldown;
RouteRequests[destination.Key] = routeRequest;
return;
}
//New Request
if (coolingDevice != null && coolingDevice.IsCoolingDownFeedback.BoolValue == true)
{
coolingDevice.IsCoolingDownFeedback.OutputChange -= routeRequest.HandleCooldown;
coolingDevice.IsCoolingDownFeedback.OutputChange += routeRequest.HandleCooldown;
RouteRequests.Add(destination.Key, routeRequest);
return;
}
if (RouteRequests.ContainsKey(destination.Key) && coolingDevice != null && coolingDevice.IsCoolingDownFeedback.BoolValue == false)
{
RouteRequests.Remove(destination.Key);
}
destination.ReleaseRoute();
RunRouteRequest(routeRequest);
} }
public static void RunRouteRequest(RouteRequest request)
{
if (request.Source == null) return;
var newRoute = request.Destination.GetRouteToSource(request.Source, request.SignalType);
if (newRoute == null) return;
RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(newRoute);
Debug.Console(2, request.Destination, "Executing full route");
newRoute.ExecuteRoutes();
}
/// <summary> /// <summary>
/// Will release the existing route on the destination, if it is found in /// Will release the existing route on the destination, if it is found in
/// RouteDescriptorCollection.DefaultCollection /// RouteDescriptorCollection.DefaultCollection
@@ -41,6 +105,17 @@ namespace PepperDash.Essentials.Core
/// <param name="destination"></param> /// <param name="destination"></param>
public static void ReleaseRoute(this IRoutingSink destination) public static void ReleaseRoute(this IRoutingSink destination)
{ {
RouteRequest existingRequest;
if (RouteRequests.TryGetValue(destination.Key, out existingRequest) && destination is IWarmingCooling)
{
var coolingDevice = destination as IWarmingCooling;
coolingDevice.IsCoolingDownFeedback.OutputChange -= existingRequest.HandleCooldown;
}
RouteRequests.Remove(destination.Key);
var current = RouteDescriptorCollection.DefaultCollection.RemoveRouteDescriptor(destination); var current = RouteDescriptorCollection.DefaultCollection.RemoveRouteDescriptor(destination);
if (current != null) if (current != null)
{ {

View File

@@ -25,7 +25,7 @@ namespace PepperDash.Essentials.Core
Type = type; Type = type;
ConnectionType = connType; ConnectionType = connType;
Selector = selector; Selector = selector;
IsInternal = IsInternal; IsInternal = isInternal;
} }
} }

View File

@@ -1,102 +0,0 @@
using System;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronDataStore;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public class CrestronGlobalSecretsProvider : ISecretProvider
{
public string Key { get; set; }
//Added for reference
public string Description { get; private set; }
public CrestronGlobalSecretsProvider(string key)
{
Key = key;
Description = String.Format("Default secret provider serving all local applications");
}
static CrestronGlobalSecretsProvider()
{
//Added for future encrypted reference
var 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;
CrestronDataStore.CDS_ERROR returnCode;
if (String.IsNullOrEmpty(secret))
{
returnCode = CrestronDataStoreStatic.clearGlobal(key);
if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
{
Debug.Console(0, this, "Successfully removed secret \"{0}\"", secret);
return true;
}
}
else
{
returnCode = CrestronDataStoreStatic.SetGlobalStringValue(key, secret);
if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
{
Debug.Console(0, this, "Successfully set secret \"{0}\"", secret);
return true;
}
}
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, returnCode.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.GetGlobalStringValue(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>
/// Determine if a secret is present within the provider without retrieving it
/// </summary>
/// <param name="key">Secret Key</param>
/// <returns>bool if present</returns>
public bool TestSecret(string key)
{
string mySecret;
return CrestronDataStoreStatic.GetGlobalStringValue(key, out mySecret) == CrestronDataStore.CDS_ERROR.CDS_SUCCESS;
}
}
}

View File

@@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
/// <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,103 +1,97 @@
using System; using System;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronDataStore; using Crestron.SimplSharp.CrestronDataStore;
using PepperDash.Core; using PepperDash.Core;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core
namespace PepperDash.Essentials.Core {
{ public class CrestronSecretsProvider : ISecretProvider
public class CrestronLocalSecretsProvider : ISecretProvider {
{ public string Key { get; set; }
public string Key { get; set; } //Added for reference
//Added for reference private static readonly bool SecureSupported;
public string Description { get; private set; } public CrestronSecretsProvider(string key)
{
Key = key;
public CrestronLocalSecretsProvider(string key) }
{
Key = key; static CrestronSecretsProvider()
Description = String.Format("Default secret provider serving Essentials Application {0}", InitialParametersClass.ApplicationNumber); {
} //Added for future encrypted reference
SecureSupported = CrestronSecureStorage.Supported;
static CrestronLocalSecretsProvider()
{ CrestronDataStoreStatic.InitCrestronDataStore();
//Added for future encrypted reference if (SecureSupported)
var secureSupported = CrestronSecureStorage.Supported; {
//doThingsFuture
CrestronDataStoreStatic.InitCrestronDataStore(); }
if (secureSupported) }
{
//doThingsFuture /// <summary>
} /// Set secret for item in the CrestronSecretsProvider
} /// </summary>
/// <param name="key">Secret Key</param>
/// <summary> /// <param name="value">Secret Value</param>
/// Set secret for item in the CrestronSecretsProvider public bool SetSecret(string key, object value)
/// </summary> {
/// <param name="key">Secret Key</param> var secret = value as string;
/// <param name="value">Secret Value</param> if (String.IsNullOrEmpty(secret))
public bool SetSecret(string key, object value) {
{ Debug.Console(2, this, "Unable to set secret for {0}:{1} - value is empty.", Key, key);
var secret = value as string; return false;
CrestronDataStore.CDS_ERROR returnCode; }
var setErrorCode = CrestronDataStoreStatic.SetLocalStringValue(key, secret);
if (String.IsNullOrEmpty(secret)) switch (setErrorCode)
{ {
returnCode = CrestronDataStoreStatic.clearLocal(key); case CrestronDataStore.CDS_ERROR.CDS_SUCCESS:
if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS) Debug.Console(1, this,"Secret Successfully Set for {0}:{1}", Key, key);
{ return true;
Debug.Console(0, this, "Successfully removed secret \"{0}\"", secret); default:
return true; Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, setErrorCode.ToString());
} return false;
} }
}
else
{ /// <summary>
returnCode = CrestronDataStoreStatic.SetLocalStringValue(key, secret); /// Retrieve secret for item in the CrestronSecretsProvider
if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS) /// </summary>
{ /// <param name="key">Secret Key</param>
Debug.Console(0, this, "Successfully set secret \"{0}\"", secret); /// <returns>ISecret Object containing key, provider, and value</returns>
return true; public ISecret GetSecret(string key)
} {
} string mySecret;
var getErrorCode = CrestronDataStoreStatic.GetLocalStringValue(key, out mySecret);
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, returnCode.ToString());
return false; switch (getErrorCode)
} {
case CrestronDataStore.CDS_ERROR.CDS_SUCCESS:
/// <summary> Debug.Console(2, this, "Secret Successfully retrieved for {0}:{1}", Key, key);
/// Retrieve secret for item in the CrestronSecretsProvider return new CrestronSecret(key, mySecret, this);
/// </summary> default:
/// <param name="key">Secret Key</param> Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}",
/// <returns>ISecret Object containing key, provider, and value</returns> Key, key, getErrorCode.ToString());
public ISecret GetSecret(string key) return null;
{ }
string mySecret; }
var getErrorCode = CrestronDataStoreStatic.GetLocalStringValue(key, out mySecret); }
switch (getErrorCode) /// <summary>
{ /// Special container class for CrestronSecret provider
case CrestronDataStore.CDS_ERROR.CDS_SUCCESS: /// </summary>
Debug.Console(2, this, "Secret Successfully retrieved for {0}:{1}", Key, key); public class CrestronSecret : ISecret
return new CrestronSecret(key, mySecret, this); {
default: public ISecretProvider Provider { get; private set; }
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}", public string Key { get; private set; }
Key, key, getErrorCode.ToString());
return null; public object Value { get; private set; }
}
} public CrestronSecret(string key, string value, ISecretProvider provider)
{
/// <summary> Key = key;
/// Determine if a secret is present within the provider without retrieving it Value = value;
/// </summary> Provider = provider;
/// <param name="key">Secret Key</param> }
/// <returns>bool if present</returns>
public bool TestSecret(string key) }
{
string mySecret;
return CrestronDataStoreStatic.GetLocalStringValue(key, out mySecret) == CrestronDataStore.CDS_ERROR.CDS_SUCCESS;
}
}
} }

View File

@@ -7,32 +7,9 @@ namespace PepperDash.Essentials.Core
/// </summary> /// </summary>
public interface ISecretProvider : IKeyed public interface ISecretProvider : IKeyed
{ {
/// <summary>
/// Set secret value for provider by key
/// </summary>
/// <param name="key">key of secret to set</param>
/// <param name="value">value to set secret to</param>
/// <returns></returns>
bool SetSecret(string key, object value); bool SetSecret(string key, object value);
/// <summary>
/// Return object containing secret from provider
/// </summary>
/// <param name="key">key of secret to retrieve</param>
/// <returns></returns>
ISecret GetSecret(string key); ISecret GetSecret(string key);
/// <summary>
/// Verifies presence of secret
/// </summary>
/// <param name="key">key of secret to chek</param>
/// <returns></returns>
bool TestSecret(string key);
/// <summary>
/// Description of the secrets provider
/// </summary>
string Description { get; }
} }
/// <summary> /// <summary>
@@ -40,19 +17,8 @@ namespace PepperDash.Essentials.Core
/// </summary> /// </summary>
public interface ISecret public interface ISecret
{ {
/// <summary>
/// Instance of ISecretProvider that the secret belongs to
/// </summary>
ISecretProvider Provider { get; } ISecretProvider Provider { get; }
/// <summary>
/// Key of the secret in the provider
/// </summary>
string Key { get; } string Key { get; }
/// <summary>
/// Value of the secret
/// </summary>
object Value { get; } object Value { get; }
} }
} }

View File

@@ -1,9 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using PepperDash.Core; using PepperDash.Core;
namespace PepperDash.Essentials.Core namespace PepperDash.Essentials.Core
{ {
public static class SecretsManager public static class SecretsManager
@@ -16,28 +16,18 @@ namespace PepperDash.Essentials.Core
public static void Initialize() public static void Initialize()
{ {
AddSecretProvider("default", new CrestronLocalSecretsProvider("default")); AddSecretProvider("default", new CrestronSecretsProvider("default"));
AddSecretProvider("CrestronGlobalSecrets", new CrestronGlobalSecretsProvider("CrestronGlobalSecrets"));
CrestronConsole.AddNewConsoleCommand(SetSecretProcess, "setsecret", CrestronConsole.AddNewConsoleCommand(SetSecretProcess, "setsecret",
"Adds secret to secrets provider", "Adds secrets to secret provider",
ConsoleAccessLevelEnum.AccessOperator); ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(UpdateSecretProcess, "updatesecret", CrestronConsole.AddNewConsoleCommand(UpdateSecretProcess, "updatesecret",
"Updates secret in secrets provider", "Updates secrets in secret provider",
ConsoleAccessLevelEnum.AccessAdministrator); ConsoleAccessLevelEnum.AccessAdministrator);
CrestronConsole.AddNewConsoleCommand(DeleteSecretProcess, "deletesecret", CrestronConsole.AddNewConsoleCommand(DeleteSecretProcess, "deletesecret",
"Deletes secret from secrest provider", "Deletes secrets in secret provider",
ConsoleAccessLevelEnum.AccessAdministrator);
CrestronConsole.AddNewConsoleCommand(ListProviders, "secretproviderlist",
"Return list of all valid secrets providers",
ConsoleAccessLevelEnum.AccessAdministrator);
CrestronConsole.AddNewConsoleCommand(GetProviderInfo, "secretproviderinfo",
"Return data about secrets provider",
ConsoleAccessLevelEnum.AccessAdministrator); ConsoleAccessLevelEnum.AccessAdministrator);
} }
@@ -64,79 +54,6 @@ namespace PepperDash.Essentials.Core
return secret; return secret;
} }
public static void GetProviderInfo(string cmd)
{
string response;
var args = cmd.Split(' ');
if (cmd.Length == 0 || (args.Length == 1 && args[0] == "?"))
{
response = "Returns data about secrets provider. Format 'secretproviderinfo <provider>'";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
if (args.Length == 1)
{
var provider = GetSecretProviderByKey(args[0]);
if (provider == null)
{
response = "Invalid secrets provider key";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
response = String.Format("{0} : {1}", provider.Key, provider.Description);
CrestronConsole.ConsoleCommandResponse(response);
return;
}
response = "Improper number of arguments";
CrestronConsole.ConsoleCommandResponse(response);
}
/// <summary>
/// Console Command that returns all valid secrets in the essentials program.
/// </summary>
/// <param name="cmd"></param>
public static void ListProviders(string cmd)
{
var response = String.Empty;
var args = cmd.Split(' ');
if (cmd.Length == 0)
{
if (Secrets != null && Secrets.Count > 0)
{
response = Secrets.Aggregate(response,
(current, secretProvider) => current + (secretProvider.Key + "\n\r"));
}
else
{
response = "No Secrets Providers Available";
}
CrestronConsole.ConsoleCommandResponse(response);
return;
}
if (args.Length == 1 && args[0] == "?")
{
response = "Reports all valid and preset Secret providers";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
response = "Improper number of arguments";
CrestronConsole.ConsoleCommandResponse(response);
}
/// <summary> /// <summary>
/// Add secret provider to secrets dictionary /// Add secret provider to secrets dictionary
/// </summary> /// </summary>
@@ -183,14 +100,14 @@ namespace PepperDash.Essentials.Core
if (args.Length == 0) if (args.Length == 0)
{ {
//some Instructional Text //some Instructional Text
response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>'"; response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>";
CrestronConsole.ConsoleCommandResponse(response); CrestronConsole.ConsoleCommandResponse(response);
return; return;
} }
if (args.Length == 1 && args[0] == "?") if (args.Length == 1 && args[0] == "?")
{ {
response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>'"; response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>";
CrestronConsole.ConsoleCommandResponse(response); CrestronConsole.ConsoleCommandResponse(response);
return; return;
} }
@@ -217,7 +134,23 @@ namespace PepperDash.Essentials.Core
var key = args[1]; var key = args[1];
var secret = args[2]; var secret = args[2];
CrestronConsole.ConsoleCommandResponse(SetSecret(provider, key, secret)); 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) private static void UpdateSecretProcess(string cmd)
@@ -228,7 +161,7 @@ namespace PepperDash.Essentials.Core
if (args.Length == 0) if (args.Length == 0)
{ {
//some Instructional Text //some Instructional Text
response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>'"; response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>";
CrestronConsole.ConsoleCommandResponse(response); CrestronConsole.ConsoleCommandResponse(response);
return; return;
@@ -236,7 +169,7 @@ namespace PepperDash.Essentials.Core
if (args.Length == 1 && args[0] == "?") if (args.Length == 1 && args[0] == "?")
{ {
response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>'"; response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>";
CrestronConsole.ConsoleCommandResponse(response); CrestronConsole.ConsoleCommandResponse(response);
return; return;
} }
@@ -265,49 +198,23 @@ namespace PepperDash.Essentials.Core
var key = args[1]; var key = args[1];
var secret = args[2]; var secret = args[2];
CrestronConsole.ConsoleCommandResponse(UpdateSecret(provider, key, secret)); if (provider.GetSecret(key) != null)
{
} response = provider.SetSecret(key, secret)
? String.Format(
private static string UpdateSecret(ISecretProvider provider, string key, string secret) "Secret successfully set for {0}:{1}",
{ provider.Key, key)
var secretPresent = provider.TestSecret(key); : String.Format(
"Unable to set secret for {0}:{1}",
Debug.Console(2, provider, "SecretsProvider {0} {1} contain a secret entry for {2}", provider.Key, secretPresent ? "does" : "does not", key); provider.Key, key);
CrestronConsole.ConsoleCommandResponse(response);
if (!secretPresent) return;
return }
String.Format(
"Unable to update secret for {0}:{1} - Please use the 'SetSecret' command to modify it");
var 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);
return response;
}
private static string SetSecret(ISecretProvider provider, string key, string secret)
{
var secretPresent = provider.TestSecret(key);
Debug.Console(2, provider, "SecretsProvider {0} {1} contain a secret entry for {2}", provider.Key, secretPresent ? "does" : "does not", key);
if (secretPresent)
return
String.Format(
"Unable to set secret for {0}:{1} - Please use the 'UpdateSecret' command to modify it");
var 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);
return response;
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) private static void DeleteSecretProcess(string cmd)
@@ -318,14 +225,14 @@ namespace PepperDash.Essentials.Core
if (args.Length == 0) if (args.Length == 0)
{ {
//some Instructional Text //some Instructional Text
response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>'"; response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>";
CrestronConsole.ConsoleCommandResponse(response); CrestronConsole.ConsoleCommandResponse(response);
return; return;
} }
if (args.Length == 1 && args[0] == "?") if (args.Length == 1 && args[0] == "?")
{ {
response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>'"; response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>";
CrestronConsole.ConsoleCommandResponse(response); CrestronConsole.ConsoleCommandResponse(response);
return; return;
} }

View File

@@ -144,7 +144,7 @@ namespace PepperDash.Essentials.Core
public UShortOutputSig GetUShortOutputSig(uint index, uint sigNum) public UShortOutputSig GetUShortOutputSig(uint index, uint sigNum)
{ {
if (sigNum > UShortIncrement) return null; if (sigNum > UShortIncrement) return null;
return SRL.UShortOutput.FirstOrDefault(s => s.Name.Equals(GetUShortOutputSigName(index, sigNum))); return SRL.UShortOutput.FirstOrDefault(s => s.Name.Equals(GetBoolFeedbackSigName(index, sigNum)));
} }
/// <summary> /// <summary>
@@ -159,7 +159,7 @@ namespace PepperDash.Essentials.Core
public StringOutputSig GetStringOutputSig(uint index, uint sigNum) public StringOutputSig GetStringOutputSig(uint index, uint sigNum)
{ {
if (sigNum > StringIncrement) return null; if (sigNum > StringIncrement) return null;
return SRL.StringOutput.FirstOrDefault(s => s.Name.Equals(GetStringOutputSigName(index, sigNum))); return SRL.StringOutput.FirstOrDefault(s => s.Name.Equals(GetBoolFeedbackSigName(index, sigNum)));
} }
/// <summary> /// <summary>

View File

@@ -308,7 +308,7 @@ namespace PepperDash.Essentials.Devices.Displays
//Send((string)selector); //Send((string)selector);
} }
public void SetVolume(ushort level) void SetVolume(ushort level)
{ {
var levelString = string.Format("{0}{1:X4}\x03", VolumeLevelPartialCmd, level); var levelString = string.Format("{0}{1:X4}\x03", VolumeLevelPartialCmd, level);
AppendChecksumAndSend(levelString); AppendChecksumAndSend(levelString);
@@ -333,13 +333,10 @@ namespace PepperDash.Essentials.Devices.Displays
Send(MuteOnCmd); Send(MuteOnCmd);
} }
void IBasicVolumeWithFeedback.SetVolume(ushort level)
/*
public void IBasicVolumeWithFeedback.SetVolume(ushort level)
{ {
SetVolume(level); SetVolume(level);
} }
*/
#endregion #endregion

View File

@@ -290,7 +290,7 @@ namespace PepperDash.Essentials.Devices.Displays
//Send((string)selector); //Send((string)selector);
} }
public void SetVolume(ushort level) void SetVolume(ushort level)
{ {
var levelString = string.Format("{0}{1:X3}\x03", VolumeLevelPartialCmd, level); var levelString = string.Format("{0}{1:X3}\x03", VolumeLevelPartialCmd, level);
@@ -315,12 +315,11 @@ namespace PepperDash.Essentials.Devices.Displays
Send(MuteOnCmd); Send(MuteOnCmd);
} }
/*
void IBasicVolumeWithFeedback.SetVolume(ushort level) void IBasicVolumeWithFeedback.SetVolume(ushort level)
{ {
SetVolume(level); SetVolume(level);
} }
*/
#endregion #endregion
#region IBasicVolumeControls Members #region IBasicVolumeControls Members

View File

@@ -108,7 +108,6 @@
<Compile Include="Codec\eCodecCallStatus.cs" /> <Compile Include="Codec\eCodecCallStatus.cs" />
<Compile Include="Codec\eMeetingPrivacy.cs" /> <Compile Include="Codec\eMeetingPrivacy.cs" />
<Compile Include="Codec\iCodecAudio.cs" /> <Compile Include="Codec\iCodecAudio.cs" />
<Compile Include="VideoCodec\IConvertiblePreset.cs" />
<Compile Include="Codec\IHasCallHold.cs" /> <Compile Include="Codec\IHasCallHold.cs" />
<Compile Include="Codec\IHasDoNotDisturb.cs" /> <Compile Include="Codec\IHasDoNotDisturb.cs" />
<Compile Include="Codec\IHasExternalSourceSwitching.cs" /> <Compile Include="Codec\IHasExternalSourceSwitching.cs" />

View File

@@ -1023,25 +1023,20 @@ ConnectorID: {2}"
if (tempPresets.Count > 0) if (tempPresets.Count > 0)
{ {
// Create temporary list to store the existing items from the CiscoCodecStatus.RoomPreset collection // Create temporary list to store the existing items from the CiscoCodecStatus.RoomPreset collection
var existingRoomPresets = new List<IConvertiblePreset>(); List<CiscoCodecStatus.RoomPreset> existingRoomPresets = new List<CiscoCodecStatus.RoomPreset>();
// Add the existing items to the temporary list // Add the existing items to the temporary list
existingRoomPresets.AddRange(CodecStatus.Status.RoomPreset); existingRoomPresets.AddRange(CodecStatus.Status.RoomPreset);
// Populate the CodecStatus object (this will append new values to the RoomPreset collection // Populate the CodecStatus object (this will append new values to the RoomPreset collection
JsonConvert.PopulateObject(response, CodecStatus); JsonConvert.PopulateObject(response, CodecStatus);
var jResponse = JObject.Parse(response); JObject jResponse = JObject.Parse(response);
List<CiscoCodecStatus.RoomPreset> convertedRoomPresets =
existingRoomPresets.Select(a => (CiscoCodecStatus.RoomPreset) a).ToList();
IList<JToken> roomPresets = jResponse["Status"]["RoomPreset"].Children().ToList(); IList<JToken> roomPresets = jResponse["Status"]["RoomPreset"].Children().ToList();
// Iterate the new items in this response agains the temporary list. Overwrite any existing items and add new ones. // Iterate the new items in this response agains the temporary list. Overwrite any existing items and add new ones.
foreach (var camPreset in tempPresets) foreach (var preset in tempPresets)
{ {
var preset = camPreset as CiscoCodecStatus.RoomPreset;
if (preset == null) continue;
// First fine the existing preset that matches the id // First fine the existing preset that matches the id
var existingPreset = convertedRoomPresets.FirstOrDefault(p => p.id.Equals(preset.id)); var existingPreset = existingRoomPresets.FirstOrDefault(p => p.id.Equals(preset.id));
if (existingPreset != null) if (existingPreset != null)
{ {
Debug.Console(1, this, "Existing Room Preset with ID: {0} found. Updating.", existingPreset.id); Debug.Console(1, this, "Existing Room Preset with ID: {0} found. Updating.", existingPreset.id);
@@ -1073,7 +1068,7 @@ ConnectorID: {2}"
CodecStatus.Status.RoomPreset = existingRoomPresets; CodecStatus.Status.RoomPreset = existingRoomPresets;
// Generecise the list // Generecise the list
NearEndPresets = existingRoomPresets.GetGenericPresets<CodecRoomPreset>(); NearEndPresets = RoomPresets.GetGenericPresets(CodecStatus.Status.RoomPreset);
var handler = CodecRoomPresetsListHasChanged; var handler = CodecRoomPresetsListHasChanged;
if (handler != null) if (handler != null)
@@ -2470,6 +2465,20 @@ ConnectorID: {2}"
} }
/// <summary>
/// Represents a codec command that might need to have a friendly label applied for UI feedback purposes
/// </summary>
public class CodecCommandWithLabel
{
public string Command { get; set; }
public string Label { get; set; }
public CodecCommandWithLabel(string command, string label)
{
Command = command;
Label = label;
}
}
/// <summary> /// <summary>
/// Tracks the initial sycnronization state of the codec when making a connection /// Tracks the initial sycnronization state of the codec when making a connection

View File

@@ -1,9 +1,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core.Presets; using PepperDash.Essentials.Core.Presets;
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
namespace PepperDash.Essentials.Devices.Common.VideoCodec namespace PepperDash.Essentials.Devices.Common.VideoCodec
{ {
@@ -28,17 +33,39 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
public static class RoomPresets public static class RoomPresets
{ {
/// <summary> /// <summary>
/// Converts non-generic RoomPresets to generic CameraPresets /// Converts Cisco RoomPresets to generic CameraPresets
/// </summary> /// </summary>
/// <param name="presets"></param> /// <param name="presets"></param>
/// <returns></returns> /// <returns></returns>
public static List<T> GetGenericPresets<T>(this List<IConvertiblePreset> presets) public static List<CodecRoomPreset> GetGenericPresets(List<CiscoCodecStatus.RoomPreset> presets)
{ {
return var cameraPresets = new List<CodecRoomPreset>();
presets.Select(preset => preset.ConvertCodecPreset())
.Where(newPreset => newPreset != null) if (Debug.Level > 0)
.Cast<T>() {
.ToList(); Debug.Console(1, "Presets List:");
}
foreach (CiscoCodecStatus.RoomPreset preset in presets)
{
try
{
var cameraPreset = new CodecRoomPreset(UInt16.Parse(preset.id), preset.Description.Value, preset.Defined.BoolValue, true);
cameraPresets.Add(cameraPreset);
if (Debug.Level > 0)
{
Debug.Console(1, "Added Preset ID: {0}, Description: {1}, IsDefined: {2}, isDefinable: {3}", cameraPreset.ID, cameraPreset.Description, cameraPreset.Defined, cameraPreset.IsDefinable);
}
}
catch (Exception e)
{
Debug.Console(2, "Unable to convert preset: {0}. Error: {1}", preset.id, e);
}
}
return cameraPresets;
} }
} }

View File

@@ -9,7 +9,6 @@ using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Devices.Common.VideoCodec.CiscoCodec; using PepperDash.Essentials.Devices.Common.VideoCodec.CiscoCodec;
using PepperDash.Essentials.Core.Presets;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{ {
@@ -2186,7 +2185,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
} }
} }
public class RoomPreset : IConvertiblePreset public class RoomPreset
{ {
public string id { get; set; } public string id { get; set; }
public Defined Defined { get; set; } public Defined Defined { get; set; }
@@ -2199,24 +2198,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
Description = new Description2(); Description = new Description2();
Type = new Type5(); Type = new Type5();
} }
}
public PresetBase ConvertCodecPreset()
{
try
{
var preset = new CodecRoomPreset(UInt16.Parse(id), Description.Value, Defined.BoolValue, true);
Debug.Console(2, "Preset ID {0} Converted from Cisco Codec Preset to Essentials Preset");
return preset;
}
catch (Exception e)
{
Debug.Console(2, "Unable to convert preset: {0}. Error: {1}", id, e);
return null;
}
}
}
@@ -2240,7 +2222,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public Proximity Proximity { get; set; } public Proximity Proximity { get; set; }
public RoomAnalytics RoomAnalytics { get; set; } public RoomAnalytics RoomAnalytics { get; set; }
public List<IConvertiblePreset> RoomPreset { get; set; } public List<RoomPreset> RoomPreset { get; set; }
public SIP SIP { get; set; } public SIP SIP { get; set; }
public Security Security { get; set; } public Security Security { get; set; }
@@ -2257,7 +2239,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
Standby = new Standby(); Standby = new Standby();
Cameras = new Cameras(); Cameras = new Cameras();
RoomAnalytics = new RoomAnalytics(); RoomAnalytics = new RoomAnalytics();
RoomPreset = new List<IConvertiblePreset>(); RoomPreset = new List<RoomPreset>();
Conference = new Conference2(); Conference = new Conference2();
SystemUnit = new SystemUnit(); SystemUnit = new SystemUnit();
Video = new Video(); Video = new Video();

View File

@@ -1,9 +0,0 @@
using PepperDash.Essentials.Core.Presets;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public interface IConvertiblePreset
{
PresetBase ConvertCodecPreset();
}
}

View File

@@ -22,26 +22,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
void MinMaxLayoutToggle(); void MinMaxLayoutToggle();
} }
/// <summary>
/// Defines the required elements for layout control with direct layout selection
/// </summary>
public interface IHasCodecLayoutsAvailable : IHasCodecLayouts
{
event EventHandler<AvailableLayoutChangedEventArgs> AvailableLayoutsChanged;
StringFeedback AvailableLocalLayoutsFeedback { get; }
List<CodecCommandWithLabel> AvailableLocalLayouts { get; }
void LocalLayoutSet(string layout);
void LocalLayoutSet(CodecCommandWithLabel layout);
}
public class AvailableLayoutChangedEventArgs : EventArgs
{
public List<CodecCommandWithLabel> AvailableLayouts { get; set; }
}
/// <summary> /// <summary>
/// Defines the requirements for Zoom Room layout control /// Defines the requirements for Zoom Room layout control
/// </summary> /// </summary>

View File

@@ -1,5 +1,5 @@
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.VideoCodec; using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{ {

View File

@@ -1,4 +1,4 @@
using PepperDash.Essentials.Devices.Common.VideoCodec; using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{ {

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.Reflection;
using Crestron.SimplSharp.Ssh; using Crestron.SimplSharp.Ssh;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharp; using Crestron.SimplSharp;
@@ -370,11 +371,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap); LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap);
} }
if (codec is IHasCodecLayoutsAvailable)
{
LinkVideoCodecAvailableLayoutsToApi(codec as IHasCodecLayoutsAvailable, trilist, joinMap);
}
if (codec is IHasSelfviewPosition) if (codec is IHasSelfviewPosition)
{ {
LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap); LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap);
@@ -1015,7 +1011,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
trilist.SetString(joinMap.DirectoryEntries.JoinNumber, trilist.SetString(joinMap.DirectoryEntries.JoinNumber,
Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length)); Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length));
var directoryXSig = UpdateDirectoryXSig(codec.DirectoryRoot, !codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue); var directoryXSig = UpdateDirectoryXSig(codec.DirectoryRoot, codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue == false);
Debug.Console(2, this, "Directory XSig Length: {0}", directoryXSig.Length); Debug.Console(2, this, "Directory XSig Length: {0}", directoryXSig.Length);
@@ -1030,7 +1026,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
trilist.SetString(joinMap.DirectoryEntries.JoinNumber, trilist.SetString(joinMap.DirectoryEntries.JoinNumber,
Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length)); Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length));
var directoryXSig = UpdateDirectoryXSig(args.Directory, !codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue); var directoryXSig = UpdateDirectoryXSig(args.Directory, codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue == false);
Debug.Console(2, this, "Directory XSig Length: {0}", directoryXSig.Length); Debug.Console(2, this, "Directory XSig Length: {0}", directoryXSig.Length);
@@ -1041,10 +1037,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
{ {
if (!args.DeviceOnLine) return; if (!args.DeviceOnLine) return;
// TODO [ ] Issue #868
trilist.SetString(joinMap.DirectoryEntries.JoinNumber, "\xFC"); trilist.SetString(joinMap.DirectoryEntries.JoinNumber, "\xFC");
UpdateDirectoryXSig(codec.CurrentDirectoryResult, UpdateDirectoryXSig(codec.CurrentDirectoryResult,
!codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue); codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue == false);
}; };
} }
@@ -1185,31 +1180,44 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
private string UpdateDirectoryXSig(CodecDirectory directory, bool isRoot) private string UpdateDirectoryXSig(CodecDirectory directory, bool isRoot)
{ {
var contactIndex = 1; var xSigMaxIndex = 1023;
var tokenArray = new XSigToken[directory.CurrentDirectoryResults.Count]; var tokenArray = new XSigToken[directory.CurrentDirectoryResults.Count > xSigMaxIndex
? xSigMaxIndex
: directory.CurrentDirectoryResults.Count];
Debug.Console(2, this, "Is root {0} Directory Count: {1}", isRoot, directory.CurrentDirectoryResults.Count); Debug.Console(2, this, "IsRoot: {0}, Directory Count: {1}, TokenArray.Length: {2}", isRoot, directory.CurrentDirectoryResults.Count, tokenArray.Length);
foreach (var entry in directory.CurrentDirectoryResults) var contacts = directory.CurrentDirectoryResults.Count > xSigMaxIndex
? directory.CurrentDirectoryResults.Take(xSigMaxIndex)
: directory.CurrentDirectoryResults;
var contactsToDisplay = isRoot
? contacts.Where(c => c.ParentFolderId == "root")
: contacts.Where(c => c.ParentFolderId != "root");
var counterIndex = 1;
foreach (var entry in contactsToDisplay)
{ {
var arrayIndex = contactIndex - 1; var arrayIndex = counterIndex - 1;
var entryIndex = counterIndex;
Debug.Console(2, this, "Entry Name: {0}, Folder ID: {1}", entry.Name, entry.FolderId); Debug.Console(2, this, "Entry{2:0000} Name: {0}, Folder ID: {1}, Type: {3}, ParentFolderId: {4}",
entry.Name, entry.FolderId, entryIndex, entry.GetType().GetCType().FullName, entry.ParentFolderId);
if (entry is DirectoryFolder && entry.ParentFolderId == "root") if (entry is DirectoryFolder)
{ {
tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, String.Format("[+] {0}", entry.Name)); tokenArray[arrayIndex] = new XSigSerialToken(entryIndex, String.Format("[+] {0}", entry.Name));
contactIndex++; counterIndex++;
continue; continue;
} }
tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, entry.Name); tokenArray[arrayIndex] = new XSigSerialToken(entryIndex, entry.Name);
contactIndex++; counterIndex++;
} }
return GetXSigString(tokenArray); return GetXSigString(tokenArray);
} }
@@ -1476,14 +1484,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentLayoutStringFb.JoinNumber]); codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentLayoutStringFb.JoinNumber]);
} }
private void LinkVideoCodecAvailableLayoutsToApi(IHasCodecLayoutsAvailable codec, BasicTriList trilist,
VideoCodecControllerJoinMap joinMap)
{
codec.AvailableLocalLayoutsFeedback.LinkInputSig(trilist.StringInput[joinMap.AvailableLayoutsFb.JoinNumber]);
trilist.SetStringSigAction(joinMap.SelectLayout.JoinNumber, codec.LocalLayoutSet);
}
private void LinkVideoCodecCameraModeToApi(IHasCameraAutoMode codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) private void LinkVideoCodecCameraModeToApi(IHasCameraAutoMode codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
{ {
trilist.SetSigFalseAction(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeOn); trilist.SetSigFalseAction(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeOn);
@@ -1995,19 +1995,4 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
} }
} }
} }
/// <summary>
/// Represents a codec command that might need to have a friendly label applied for UI feedback purposes
/// </summary>
public class CodecCommandWithLabel
{
public string Command { get; private set; }
public string Label { get; private set; }
public CodecCommandWithLabel(string command, string label)
{
Command = command;
Label = label;
}
}
} }

View File

@@ -2729,7 +2729,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{ {
Debug.Console(2, this, "OnDirectoryResultReturned. Result has {0} contacts", result.Contacts.Count); Debug.Console(2, this, "OnDirectoryResultReturned. Result has {0} contacts", result.Contacts.Count);
CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate();
var directoryResult = result; var directoryResult = result;
var directoryIsRoot = CurrentDirectoryResultIsNotDirectoryRoot.BoolValue == false;
// If result is Root, create a copy and filter out contacts whose parent folder is not root // If result is Root, create a copy and filter out contacts whose parent folder is not root
//if (!CurrentDirectoryResultIsNotDirectoryRoot.BoolValue) //if (!CurrentDirectoryResultIsNotDirectoryRoot.BoolValue)
@@ -2747,7 +2750,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
//} //}
Debug.Console(2, this, "Updating directoryResult. IsOnRoot: {0} Contact Count: {1}", Debug.Console(2, this, "Updating directoryResult. IsOnRoot: {0} Contact Count: {1}",
!CurrentDirectoryResultIsNotDirectoryRoot.BoolValue, directoryResult.Contacts.Count); directoryIsRoot, directoryResult.Contacts.Count);
// This will return the latest results to all UIs. Multiple indendent UI Directory browsing will require a different methodology // This will return the latest results to all UIs. Multiple indendent UI Directory browsing will require a different methodology
var handler = DirectoryResultReturned; var handler = DirectoryResultReturned;
@@ -2756,11 +2759,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
handler(this, new DirectoryEventArgs handler(this, new DirectoryEventArgs
{ {
Directory = directoryResult, Directory = directoryResult,
DirectoryIsOnRoot = !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue DirectoryIsOnRoot = directoryIsRoot
}); });
} }
CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate();
} }
catch (Exception e) catch (Exception e)
{ {