Compare commits

...

14 Commits

Author SHA1 Message Date
Jason T Alborough
29a79490ba #101 Fixes scope issue with CCriticalSection() in ConfigWriter 2020-04-10 16:29:48 -04:00
Andrew Welker
da50272980 Merge pull request #88 from PepperDash/feature/fix-get-name-attribute-issue
Feature/fix get name attribute issue
2020-04-05 09:25:28 -06:00
Neil Dorin
c8f095f0a3 Updates CameraControllerJoinMap to use new constructor for base class 2020-04-05 09:07:05 -06:00
Andrew Welker
42fbd813a2 updated methods for creating joinMap dict 2020-04-04 22:06:56 -06:00
Andrew Welker
69f5460442 trying to fix JoinMapBaseAdvanced 2020-04-04 21:09:00 -06:00
Neil Dorin
b32212083d Adds debug statment to detect if JoinNameAttribute constructor has been called 2020-04-04 14:44:43 -06:00
Neil Dorin
88702f97c6 moves logic to add joins out of the constructor and into new AddJoins() method to allow it to be called from extended class after fields have been initialized. 2020-04-04 14:12:49 -06:00
Andrew Welker
9b759daca1 Merge pull request #87 from PepperDash/feature/updated-IDeviceFactory-for-plugin-implementation
Feature/updated i device factory for plugin implementation
2020-04-04 11:27:19 -06:00
Neil Dorin
9363e94749 Updates to JoinMapBaseAdvanced constructor to properly add JoinDataComplete fields to Joins collection and to BridgeBase to implement console methods to print data at runtime. 2020-04-04 10:43:55 -06:00
Neil Dorin
6474bfa136 fixes format exception in debug statement 2020-04-03 20:07:27 -06:00
Neil Dorin
43e57ab6d1 Adds some comments, initializes JoinMaps in EiscApi and moves GenericComm factory to new methodology 2020-04-03 19:43:06 -06:00
Neil Dorin
9d7f5af26e Adds IBridgeAdvanced and updates to 1.0.35 of PepperDash.Core 2020-04-03 18:21:17 -06:00
Neil Dorin
3a101d89ea Adds some additional help 2020-04-03 18:01:08 -06:00
Neil Dorin
703695e768 Adds console method to print join maps at runtime. Adds overload of LinkToApi extension method for IBridge to allow passing the bridge in for JoinMapBaseAdvance applications 2020-04-03 09:25:48 -06:00
14 changed files with 222 additions and 100 deletions

View File

@@ -20,6 +20,46 @@ using PepperDash.Essentials.DM;
namespace PepperDash.Essentials.Bridges
{
/// <summary>
/// Helper methods for bridges
/// </summary>
public static class BridgeHelper
{
public static void PrintJoinMap(string command)
{
string bridgeKey = "";
string deviceKey = "";
var targets = command.Split(' ');
bridgeKey = targets[0].Trim();
var bridge = DeviceManager.GetDeviceForKey(bridgeKey) as EiscApi;
if (bridge == null)
{
Debug.Console(0, "Unable to find bridge with key: '{0}'", bridgeKey);
return;
}
if (targets.Length > 1)
{
deviceKey = targets[1].Trim();
if (!string.IsNullOrEmpty(deviceKey))
{
bridge.PrintJoinMapForDevice(deviceKey);
return;
}
}
else
{
bridge.PrintJoinMaps();
}
}
}
/// <summary>
/// Base class for all bridge class variants
/// </summary>
@@ -61,6 +101,8 @@ namespace PepperDash.Essentials.Bridges
public EiscApi(DeviceConfig dc) :
base(dc.Key)
{
JoinMaps = new Dictionary<string, JoinMapBaseAdvanced>();
PropertiesConfig = JsonConvert.DeserializeObject<EiscApiPropertiesConfig>(dc.Properties.ToString());
Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(PropertiesConfig.Control.IpIdInt, PropertiesConfig.Control.TcpSshProperties.Address, Global.ControlSystem);
@@ -79,11 +121,19 @@ namespace PepperDash.Essentials.Bridges
if (device != null)
{
Debug.Console(1, this, "Linking Device: '{0}'", device.Key);
if (device is IBridge) // Check for this first to allow bridges in plugins to override existing bridges that apply to the same type.
{
(device as IBridge).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
else if (device is IBridgeAdvanced)
{
Debug.Console(2, this, "'{0}' is IBridgeAdvanced", device.Key);
(device as IBridgeAdvanced).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, this);
}
else if (device is PepperDash.Essentials.Core.Monitoring.SystemMonitorController)
{
(device as PepperDash.Essentials.Core.Monitoring.SystemMonitorController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
@@ -99,16 +149,18 @@ namespace PepperDash.Essentials.Bridges
(device as CameraBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, this);
continue;
}
else if (device is PepperDash.Essentials.Core.DisplayBase)
{
(device as DisplayBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
else if (device is DmChassisController) {
else if (device is PepperDash.Essentials.Core.DisplayBase)
{
(device as DisplayBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
else if (device is DmChassisController)
{
(device as DmChassisController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
else if (device is DmBladeChassisController) {
else if (device is DmBladeChassisController)
{
(device as DmBladeChassisController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
@@ -206,6 +258,38 @@ namespace PepperDash.Essentials.Bridges
}
}
/// <summary>
/// Prints all the join maps on this bridge
/// </summary>
public void PrintJoinMaps()
{
Debug.Console(0, this, "Join Maps for EISC IPID: {0}", Eisc.ID.ToString("X"));
foreach (var joinMap in JoinMaps)
{
Debug.Console(0, "Join map for device '{0}':", joinMap.Key);
joinMap.Value.PrintJoinMapInfo();
}
}
/// <summary>
/// Prints the join map for a device by key
/// </summary>
/// <param name="deviceKey"></param>
public void PrintJoinMapForDevice(string deviceKey)
{
var joinMap = JoinMaps[deviceKey];
if (joinMap == null)
{
Debug.Console(0, this, "Unable to find joinMap for device with key: '{0}'", deviceKey);
return;
}
Debug.Console(0, "Join map for device '{0}' on EISC '{1}':", deviceKey, this.Key);
joinMap.PrintJoinMapInfo();
}
/// <summary>
/// Used for debugging to trigger an action based on a join number and type
/// </summary>

View File

@@ -18,7 +18,7 @@ namespace PepperDash.Essentials.Bridges
public static void LinkToApi(this PepperDash.Essentials.Devices.Common.Cameras.CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApi bridge)
{
CameraControllerJoinMap joinMap = new CameraControllerJoinMap(joinStart);
// Adds the join map to the bridge
bridge.AddJoinMap(cameraDevice.Key, joinMap);

View File

@@ -7,8 +7,20 @@ using Crestron.SimplSharpPro.DeviceSupport;
namespace PepperDash.Essentials.Bridges
{
/// <summary>
/// Defines a device that uses the legacy JoinMapBase for its join map
/// </summary>
[Obsolete("IBridgeAdvanced should be used going forward with JoinMapBaseAdvanced")]
public interface IBridge
{
void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey);
}
/// <summary>
/// Defines a device that uses JoinMapBaseAdvanced for its join map
/// </summary>
public interface IBridgeAdvanced
{
void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApi bridge);
}
}

View File

@@ -57,7 +57,7 @@ namespace PepperDash.Essentials.Bridges
public JoinDataComplete SupportsPresets = new JoinDataComplete(new JoinData() { JoinNumber = 57, JoinSpan = 1 }, new JoinMetadata() { Label = "Supports Presets", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
public CameraControllerJoinMap(uint joinStart)
:base(joinStart)
: base(joinStart, typeof(CameraControllerJoinMap))
{
}
}

View File

@@ -51,7 +51,8 @@ namespace PepperDash.Essentials
CrestronConsole.AddNewConsoleCommand(PepperDash.Essentials.Core.DeviceFactory.GetDeviceFactoryTypes, "gettypes", "Gets the device types that can be built. Accepts a filter string.", ConsoleAccessLevelEnum.AccessOperator);
// CrestronConsole.AddNewConsoleCommand(S => { ConfigWriter.WriteConfigFile(null); }, "writeconfig", "writes the current config to a file", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(PepperDash.Essentials.Bridges.BridgeHelper.PrintJoinMap, "getjoinmap", "map(s) for bridge or device on bridge [brKey [devKey]]", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "CONSOLE MESSAGE: {0}", s);
@@ -289,12 +290,13 @@ namespace PepperDash.Essentials
/// </summary>
public void LoadDevices()
{
// Instantiate the Device Factories
new CoreDeviceFactory();
// Build the processor wrapper class
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor"));
// Add global System Monitor device
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Monitoring.SystemMonitorController("systemMonitor"));

View File

@@ -19,7 +19,8 @@ namespace PepperDash.Essentials.Core.Config
public const long WriteTimeout = 30000;
public static CTimer WriteTimer;
public static CTimer WriteTimer;
static CCriticalSection fileLock = new CCriticalSection();
/// <summary>
/// Updates the config properties of a device
@@ -127,8 +128,6 @@ namespace PepperDash.Essentials.Core.Config
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file");
var fileLock = new CCriticalSection();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath);
try

View File

@@ -34,8 +34,14 @@ namespace PepperDash.Essentials.Core
{
#region IDeviceFactory Members
/// <summary>
/// A list of strings that can be used in the type property of a DeviceConfig object to build an instance of this device
/// </summary>
public List<string> TypeNames { get; protected set; }
/// <summary>
/// Loads an item to the DeviceFactory.FactoryMethods dictionary for each entry in the TypeNames list
/// </summary>
public void LoadTypeFactories()
{
foreach (var typeName in TypeNames)
@@ -44,6 +50,11 @@ namespace PepperDash.Essentials.Core
}
}
/// <summary>
/// The method that will build the device
/// </summary>
/// <param name="dc">The device config</param>
/// <returns>An instance of the device</returns>
public abstract EssentialsDevice BuildDevice(DeviceConfig dc);
#endregion
@@ -54,6 +65,9 @@ namespace PepperDash.Essentials.Core
/// </summary>
public abstract class EssentialsPluginDeviceFactory<T> : EssentialsDeviceFactory<T>, IPluginDeviceFactory where T : EssentialsDevice
{
/// <summary>
/// Specifies the minimum version of Essentials required for a plugin to run. Must use the format Major.Minor.Build (ex. "1.4.33")
/// </summary>
public string MinimumEssentialsFrameworkVersion { get; protected set; }
}
}

View File

@@ -48,7 +48,6 @@ namespace PepperDash.Essentials.Core
var typeName = dc.Type.ToLower();
// Check for types that have been added by plugin dlls.
if (FactoryMethods.ContainsKey(typeName))
{
@@ -57,11 +56,11 @@ namespace PepperDash.Essentials.Core
}
// Check "core" types
if (typeName == "genericcomm")
{
Debug.Console(1, "Factory Attempting to create new Generic Comm Device");
return new GenericComm(dc);
}
//if (typeName == "genericcomm")
//{
// Debug.Console(1, "Factory Attempting to create new Generic Comm Device");
// return new GenericComm(dc);
//}
if (typeName == "ceniodigin104")
{
var control = CommFactory.GetControlPropertiesConfig(dc);

View File

@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Reflection;
using PepperDash.Core;
@@ -26,12 +24,7 @@ namespace PepperDash.Essentials.Core
var joinMap = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
if (joinMap != null)
{
return joinMap;
}
else
return null;
return joinMap;
}
/// <summary>
@@ -46,18 +39,13 @@ namespace PepperDash.Essentials.Core
var joinMapSerialzed = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
if (joinMapSerialzed != null)
{
var joinMap = JsonConvert.DeserializeObject<Dictionary<string, JoinData>>(joinMapSerialzed);
if (joinMapSerialzed == null) return null;
if (joinMap != null)
return joinMap;
else
return null;
}
else
return null;
var joinMapData = JsonConvert.DeserializeObject<Dictionary<string, JoinData>>(joinMapSerialzed);
return joinMapData;
}
}
/// <summary>
@@ -82,19 +70,22 @@ namespace PepperDash.Essentials.Core
/// </summary>
public void PrintJoinMapInfo()
{
Debug.Console(0, "{0}:\n", this.GetType().Name);
Debug.Console(0, "{0}:\n", GetType().Name);
// Get the joins of each type and print them
Debug.Console(0, "Digitals:");
var digitals = Joins.Where(j => (j.Value.JoinType & eJoinType.Digital) == eJoinType.Digital).ToDictionary(j => j.Key, j => j.Value);
Debug.Console(2, "Found {0} Digital Joins", digitals.Count);
PrintJoinList(GetSortedJoins(digitals));
Debug.Console(0, "Analogs:");
var analogs = Joins.Where(j => (j.Value.JoinType & eJoinType.Analog) == eJoinType.Analog).ToDictionary(j => j.Key, j => j.Value);
Debug.Console(2, "Found {0} Analog Joins", analogs.Count);
PrintJoinList(GetSortedJoins(analogs));
Debug.Console(0, "Serials:");
var serials = Joins.Where(j => (j.Value.JoinType & eJoinType.Serial) == eJoinType.Serial).ToDictionary(j => j.Key, j => j.Value);
Debug.Console(2, "Found {0} Serial Joins", serials.Count);
PrintJoinList(GetSortedJoins(serials));
}
@@ -134,10 +125,7 @@ namespace PepperDash.Essentials.Core
/// <returns></returns>
public uint GetJoinForKey(string key)
{
if (Joins.ContainsKey(key))
return Joins[key].JoinNumber;
else return 0;
return Joins.ContainsKey(key) ? Joins[key].JoinNumber : 0;
}
/// <summary>
@@ -147,12 +135,8 @@ namespace PepperDash.Essentials.Core
/// <returns></returns>
public uint GetJoinSpanForKey(string key)
{
if (Joins.ContainsKey(key))
return Joins[key].JoinSpan;
else return 0;
return Joins.ContainsKey(key) ? Joins[key].JoinSpan : 0;
}
}
/// <summary>
@@ -160,28 +144,66 @@ namespace PepperDash.Essentials.Core
/// </summary>
public abstract class JoinMapBaseAdvanced
{
protected uint _joinOffset;
protected uint JoinOffset;
/// <summary>
/// The collection of joins and associated metadata
/// </summary>
public Dictionary<string, JoinDataComplete> Joins = new Dictionary<string, JoinDataComplete>();
public Dictionary<string, JoinDataComplete> Joins { get; private set; }
protected JoinMapBaseAdvanced(uint joinStart)
{
_joinOffset = joinStart - 1;
Joins = new Dictionary<string, JoinDataComplete>();
JoinOffset = joinStart - 1;
}
protected JoinMapBaseAdvanced(uint joinStart, Type type):this(joinStart)
{
AddJoins(type);
}
protected void AddJoins(Type type)
{
// Add all the JoinDataComplete properties to the Joins Dictionary and pass in the offset
Joins = GetType()
.GetCType()
.GetProperties()
.Where(prop => prop.IsDefined(typeof(JoinNameAttribute), false))
.Select(prop => (JoinDataComplete)prop.GetValue(this, null))
.ToDictionary(join => join.GetNameAttribute(), join =>
{
join.SetJoinOffset(_joinOffset);
return join;
});
//Joins = this.GetType()
// .GetCType()
// .GetFields(BindingFlags.Public | BindingFlags.Instance)
// .Where(field => field.IsDefined(typeof(JoinNameAttribute), true))
// .Select(field => (JoinDataComplete)field.GetValue(this))
// .ToDictionary(join => join.GetNameAttribute(), join =>
// {
// join.SetJoinOffset(_joinOffset);
// return join;
// });
//type = this.GetType(); <- this wasn't working because 'this' was always the base class, never the derived class
var fields =
type.GetCType()
.GetFields(BindingFlags.Public | BindingFlags.Instance)
.Where(f => f.IsDefined(typeof (JoinNameAttribute), true));
foreach (var field in fields)
{
var childClass = Convert.ChangeType(this, type, null);
var value = field.GetValue(childClass) as JoinDataComplete; //this here is JoinMapBaseAdvanced, not the child class. JoinMapBaseAdvanced has no fields.
if (value == null)
{
Debug.Console(0, "Unable to caset base class to {0}", type.Name);
continue;
}
value.SetJoinOffset(JoinOffset);
var joinName = value.GetNameAttribute(field);
if (String.IsNullOrEmpty(joinName)) continue;
Joins.Add(joinName, value);
}
PrintJoinMapInfo();
}
@@ -191,19 +213,22 @@ namespace PepperDash.Essentials.Core
/// </summary>
public void PrintJoinMapInfo()
{
Debug.Console(0, "{0}:\n", this.GetType().Name);
Debug.Console(0, "{0}:\n", GetType().Name);
// Get the joins of each type and print them
Debug.Console(0, "Digitals:");
var digitals = Joins.Where(j => (j.Value.Metadata.JoinType & eJoinType.Digital) == eJoinType.Digital).ToDictionary(j => j.Key, j => j.Value);
Debug.Console(2, "Found {0} Digital Joins", digitals.Count);
PrintJoinList(GetSortedJoins(digitals));
Debug.Console(0, "Analogs:");
var analogs = Joins.Where(j => (j.Value.Metadata.JoinType & eJoinType.Analog) == eJoinType.Analog).ToDictionary(j => j.Key, j => j.Value);
Debug.Console(2, "Found {0} Analog Joins", analogs.Count);
PrintJoinList(GetSortedJoins(analogs));
Debug.Console(0, "Serials:");
var serials = Joins.Where(j => (j.Value.Metadata.JoinType & eJoinType.Serial) == eJoinType.Serial).ToDictionary(j => j.Key, j => j.Value);
Debug.Console(2, "Found {0} Serial Joins", serials.Count);
PrintJoinList(GetSortedJoins(serials));
}
@@ -255,6 +280,8 @@ namespace PepperDash.Essentials.Core
Debug.Console(2, "No mathcing key found in join map for: '{0}'", customJoinData.Key);
}
}
PrintJoinMapInfo();
}
///// <summary>
@@ -407,26 +434,33 @@ namespace PepperDash.Essentials.Core
_data = customJoinData;
}
public string GetNameAttribute()
public string GetNameAttribute(MemberInfo memberInfo)
{
string name = string.Empty;
JoinNameAttribute attribute = (JoinNameAttribute)Attribute.GetCustomAttribute(typeof(JoinDataComplete), typeof(JoinNameAttribute));
if (attribute != null)
{
name = attribute.Name;
}
var name = string.Empty;
var attribute = (JoinNameAttribute)CAttribute.GetCustomAttribute(memberInfo, typeof(JoinNameAttribute));
if (attribute == null) return name;
name = attribute.Name;
Debug.Console(2, "JoinName Attribute value: {0}", name);
return name;
}
}
[AttributeUsage(AttributeTargets.Field)]
[AttributeUsage(AttributeTargets.All)]
public class JoinNameAttribute : Attribute
{
public string Name { get; set; }
private string _Name;
public JoinNameAttribute(string name)
{
Name = name;
Debug.Console(2, "Setting Attribute Name: {0}", name);
_Name = name;
}
public string Name
{
get { return _Name; }
}
}
}

View File

@@ -161,7 +161,6 @@
<Compile Include="Plugins\PluginLoader.cs" />
<Compile Include="Presets\PresetBase.cs" />
<Compile Include="Plugins\IPluginDeviceFactory.cs" />
<Compile Include="Plugins\PluginEntrypointAttribute.cs" />
<Compile Include="Ramps and Increments\ActionIncrementer.cs" />
<Compile Include="Config\Comm and IR\CommFactory.cs" />
<Compile Include="Config\Comm and IR\CommunicationExtras.cs" />

View File

@@ -1,19 +0,0 @@
using System;
namespace PepperDash.Essentials.Core.Plugins
{
[AttributeUsage(AttributeTargets.Class)]
public sealed class PluginEntryPointAttribute : Attribute
{
private readonly string _uniqueKey;
public string UniqueKey {
get { return _uniqueKey; }
}
public PluginEntryPointAttribute(string key)
{
_uniqueKey = key;
}
}
}

View File

@@ -8,7 +8,6 @@ using Crestron.SimplSharp.Reflection;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Plugins;
namespace PepperDash.Essentials
{

View File

@@ -28,7 +28,6 @@ namespace PepperDash.Essentials.Core.Touchpanels
_Touchpanel.ButtonStateChange += new Crestron.SimplSharpPro.DeviceSupport.ButtonEventHandler(_Touchpanel_ButtonStateChange);
AddPostActivationAction(() =>
{
// Link up the button feedbacks to the specified BoolFeedbacks
@@ -40,7 +39,7 @@ namespace PepperDash.Essentials.Core.Touchpanels
{
var bKey = button.Key.ToLower();
var feedback = device.GetFeedbackProperty(feedbackConfig.BoolFeedbackName);
var feedback = device.GetFeedbackProperty(feedbackConfig.FeedbackName);
var bFeedback = feedback as BoolFeedback;
var iFeedback = feedback as IntFeedback;
@@ -72,7 +71,7 @@ namespace PepperDash.Essentials.Core.Touchpanels
}
else
{
Debug.Console(1, this, "Unable to get BoolFeedback with name: {0} from device: {1}", feedbackConfig.BoolFeedbackName, device.Key);
Debug.Console(1, this, "Unable to get BoolFeedback with name: {0} from device: {1}", feedbackConfig.FeedbackName, device.Key);
}
}
else
@@ -140,6 +139,6 @@ namespace PepperDash.Essentials.Core.Touchpanels
public class KeypadButtonFeedback
{
public string DeviceKey { get; set; }
public string BoolFeedbackName { get; set; }
public string FeedbackName { get; set; }
}
}