Merge pull request #1338 from PepperDash/io-updates

This commit is contained in:
Neil Dorin
2025-09-25 09:59:36 -06:00
committed by GitHub
8 changed files with 210 additions and 279 deletions

View File

@@ -2,59 +2,54 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json; using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Config;
using Serilog.Events;
namespace PepperDash.Essentials.Core.CrestronIO namespace PepperDash.Essentials.Core.CrestronIO
{ {
[Description("Wrapper class for Digital Input")]
/// <summary> /// <summary>
/// Represents a GenericDigitalInputDevice /// Represents a GenericDigitalInputDevice
/// </summary> /// </summary>
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput /// [Description("Wrapper class for Digital Input")]
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IHasFeedback
{ {
/// <summary> private DigitalInput inputPort;
/// Gets or sets the InputPort
/// </summary>
public DigitalInput InputPort { get; private set; }
/// <summary> /// <summary>
/// Gets or sets the InputStateFeedback /// Gets or sets the InputStateFeedback
/// </summary> /// </summary>
public BoolFeedback InputStateFeedback { get; private set; } public BoolFeedback InputStateFeedback { get; private set; }
Func<bool> InputStateFeedbackFunc /// <inheritdoc />
{ public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
get
{
return () => InputPort.State;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="GenericDigitalInputDevice"/> class.
/// </summary>
/// <param name="key">key for device</param>
/// <param name="name">name for device</param>
/// <param name="postActivationFunc">function to call after activation. Should return the DigitalInput</param>
/// <param name="config">config for device</param>
public GenericDigitalInputDevice(string key, string name, Func<IOPortConfig, DigitalInput> postActivationFunc, public GenericDigitalInputDevice(string key, string name, Func<IOPortConfig, DigitalInput> postActivationFunc,
IOPortConfig config) IOPortConfig config)
: base(key, name) : base(key, name)
{ {
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc); InputStateFeedback = new BoolFeedback("inputState", () => inputPort.State);
AddPostActivationAction(() => AddPostActivationAction(() =>
{ {
InputPort = postActivationFunc(config); inputPort = postActivationFunc(config);
InputPort.Register(); inputPort.Register();
InputPort.StateChange += InputPort_StateChange;
inputPort.StateChange += InputPort_StateChange;
}); });
} }
@@ -71,41 +66,31 @@ namespace PepperDash.Essentials.Core.CrestronIO
private static DigitalInput GetDigitalInput(IOPortConfig dc) private static DigitalInput GetDigitalInput(IOPortConfig dc)
{ {
IDigitalInputPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor")) if (dc.PortDeviceKey.Equals("processor"))
{ {
if (!Global.ControlSystem.SupportsDigitalInput) if (!Global.ControlSystem.SupportsDigitalInput)
{ {
Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Processor does not support Digital Inputs"); Debug.LogError("GetDigitalInput: Processor does not support Digital Inputs");
return null; return null;
} }
ioPortDevice = Global.ControlSystem;
return Global.ControlSystem.DigitalInputPorts[dc.PortNumber];
} }
else
if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IDigitalInputPorts ioPortDevice))
{ {
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IDigitalInputPorts; Debug.LogError("GetDigitalInput: Device {key} is not a valid device", dc.PortDeviceKey);
if (ioPortDev == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Device {0} is not a valid device", dc.PortDeviceKey);
return null;
}
ioPortDevice = ioPortDev;
}
if (ioPortDevice == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Device '0' is not a valid IDigitalInputPorts Device", dc.PortDeviceKey);
return null; return null;
} }
if (dc.PortNumber > ioPortDevice.NumberOfDigitalInputPorts) if (dc.PortNumber > ioPortDevice.NumberOfDigitalInputPorts)
{ {
Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber); Debug.LogError("GetDigitalInput: Device {key} does not contain a digital input port {port}", dc.PortDeviceKey, dc.PortNumber);
return null;
} }
return ioPortDevice.DigitalInputPorts[dc.PortNumber]; return ioPortDevice.DigitalInputPorts[dc.PortNumber];
} }
#endregion #endregion
@@ -131,20 +116,20 @@ namespace PepperDash.Essentials.Core.CrestronIO
} }
else else
{ {
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
} }
try try
{ {
Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); this.LogDebug("Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// Link feedback for input state // Link feedback for input state
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]); InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
} }
catch (Exception e) catch (Exception e)
{ {
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key); this.LogError("Unable to link device {key}. {message}", Key, e.Message);
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e); this.LogDebug(e, "Stack Trace: ");
} }
} }
@@ -153,22 +138,22 @@ namespace PepperDash.Essentials.Core.CrestronIO
#region Factory #region Factory
/// <summary> /// <summary>
/// Represents a GenericDigitalInputDeviceFactory /// Factory for creating GenericDigitalInputDevice devices
/// </summary> /// </summary>
public class GenericDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericDigitalInputDevice> public class GenericDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericDigitalInputDevice>
{ {
/// <summary>
/// Constructor for GenericDigitalInputDeviceFactory
/// </summary>
public GenericDigitalInputDeviceFactory() public GenericDigitalInputDeviceFactory()
{ {
TypeNames = new List<string>() { "digitalinput" }; TypeNames = new List<string>() { "digitalinput" };
} }
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc /> /// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc) public override EssentialsDevice BuildDevice(DeviceConfig dc)
{ {
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Digital Input Device"); Debug.LogDebug("Factory Attempting to create new Generic Digital Input Device");
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString()); var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());

View File

@@ -2,66 +2,64 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
using Newtonsoft.Json; using Newtonsoft.Json;
using Serilog.Events; using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core.CrestronIO namespace PepperDash.Essentials.Core.CrestronIO
{ {
/// <summary> /// <summary>
/// Represents a generic digital input deviced tied to a versiport /// Represents a generic digital input deviced tied to a versiport
/// </summary> /// </summary>
public class GenericVersiportAnalogInputDevice : EssentialsBridgeableDevice, IAnalogInput public class GenericVersiportAnalogInputDevice : EssentialsBridgeableDevice, IAnalogInput, IHasFeedback
{ {
public Versiport InputPort { get; private set; } private Versiport inputPort;
/// <inheritdoc />
public IntFeedback InputValueFeedback { get; private set; } public IntFeedback InputValueFeedback { get; private set; }
/// <summary>
/// Get the InputMinimumChangeFeedback
/// </summary>
/// <remarks>
/// Updates when the analog input minimum change value changes
/// </remarks>
public IntFeedback InputMinimumChangeFeedback { get; private set; } public IntFeedback InputMinimumChangeFeedback { get; private set; }
Func<int> InputValueFeedbackFunc /// <inheritdoc />
{ public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
get
{
return () => InputPort.AnalogIn;
}
}
Func<int> InputMinimumChangeFeedbackFunc
{
get { return () => InputPort.AnalogMinChange; }
}
/// <summary>
/// Initializes a new instance of the <see cref="GenericVersiportAnalogInputDevice"/> class.
/// </summary>
/// <param name="key">key for the device</param>
/// <param name="name">name for the device</param>
/// <param name="postActivationFunc">function to call after activation</param>
/// <param name="config">IO port configuration</param>
public GenericVersiportAnalogInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) : public GenericVersiportAnalogInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
base(key, name) base(key, name)
{ {
InputValueFeedback = new IntFeedback(InputValueFeedbackFunc); InputValueFeedback = new IntFeedback("inputValue", () => inputPort.AnalogIn);
InputMinimumChangeFeedback = new IntFeedback(InputMinimumChangeFeedbackFunc); InputMinimumChangeFeedback = new IntFeedback("inputMinimumChange", () => inputPort.AnalogMinChange);
AddPostActivationAction(() => AddPostActivationAction(() =>
{ {
InputPort = postActivationFunc(config); inputPort = postActivationFunc(config);
InputPort.Register(); inputPort.Register();
InputPort.SetVersiportConfiguration(eVersiportConfiguration.AnalogInput); inputPort.SetVersiportConfiguration(eVersiportConfiguration.AnalogInput);
InputPort.AnalogMinChange = (ushort)(config.MinimumChange > 0 ? config.MinimumChange : 655); inputPort.AnalogMinChange = (ushort)(config.MinimumChange > 0 ? config.MinimumChange : 655);
if (config.DisablePullUpResistor) if (config.DisablePullUpResistor)
InputPort.DisablePullUpResistor = true; inputPort.DisablePullUpResistor = true;
InputPort.VersiportChange += InputPort_VersiportChange; inputPort.VersiportChange += InputPort_VersiportChange;
Debug.LogMessage(LogEventLevel.Debug, this, "Created GenericVersiportAnalogInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor);
this.LogDebug("Created GenericVersiportAnalogInputDevice on port {port}. DisablePullUpResistor: {pullUpResistorDisabled}", config.PortNumber, inputPort.DisablePullUpResistor);
}); });
} }
@@ -69,20 +67,17 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// <summary> /// <summary>
/// Set minimum voltage change for device to update voltage changed method /// Set minimum voltage change for device to update voltage changed method
/// </summary> /// </summary>
/// <param name="value">valid values range from 0 - 65535, representing the full 100% range of the processor voltage source. Check processor documentation for details</param> /// <param name="value">valid values range from 0 - 65535, representing the full 100% range of the processor voltage source. Check processor documentation for details</param>
/// <summary>
/// SetMinimumChange method
/// </summary>
public void SetMinimumChange(ushort value) public void SetMinimumChange(ushort value)
{ {
InputPort.AnalogMinChange = value; inputPort.AnalogMinChange = value;
} }
void InputPort_VersiportChange(Versiport port, VersiportEventArgs args) void InputPort_VersiportChange(Versiport port, VersiportEventArgs args)
{ {
Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event); this.LogDebug("Versiport change: {event}", args.Event);
if(args.Event == eVersiportEvent.AnalogInChange) if (args.Event == eVersiportEvent.AnalogInChange)
InputValueFeedback.FireUpdate(); InputValueFeedback.FireUpdate();
if (args.Event == eVersiportEvent.AnalogMinChangeChange) if (args.Event == eVersiportEvent.AnalogMinChangeChange)
InputMinimumChangeFeedback.FireUpdate(); InputMinimumChangeFeedback.FireUpdate();
@@ -91,9 +86,6 @@ namespace PepperDash.Essentials.Core.CrestronIO
#region Bridge Linking #region Bridge Linking
/// <summary>
/// LinkToApi method
/// </summary>
/// <inheritdoc /> /// <inheritdoc />
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{ {
@@ -110,12 +102,12 @@ namespace PepperDash.Essentials.Core.CrestronIO
} }
else else
{ {
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
} }
try try
{ {
Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); this.LogDebug("Linking to Trilist '{trilistId}'", trilist.ID.ToString("X"));
// Link feedback for input state // Link feedback for input state
InputValueFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputValue.JoinNumber]); InputValueFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputValue.JoinNumber]);
@@ -125,8 +117,8 @@ namespace PepperDash.Essentials.Core.CrestronIO
} }
catch (Exception e) catch (Exception e)
{ {
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key); this.LogError("Unable to link device {key}: {message}", Key, e.Message);
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e); this.LogDebug(e, "Stack Trace: ");
} }
trilist.OnlineStatusChange += (d, args) => trilist.OnlineStatusChange += (d, args) =>
@@ -138,11 +130,6 @@ namespace PepperDash.Essentials.Core.CrestronIO
} }
void trilist_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
throw new NotImplementedException();
}
#endregion #endregion
@@ -151,70 +138,55 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary> /// </summary>
public static Versiport GetVersiportDigitalInput(IOPortConfig dc) public static Versiport GetVersiportDigitalInput(IOPortConfig dc)
{ {
IIOPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor")) if (dc.PortDeviceKey.Equals("processor"))
{ {
if (!Global.ControlSystem.SupportsVersiport) if (!Global.ControlSystem.SupportsVersiport)
{ {
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Processor does not support Versiports"); Debug.LogError("GetVersiportAnalogInput: Processor does not support Versiports");
return null; return null;
} }
ioPortDevice = Global.ControlSystem; return Global.ControlSystem.VersiPorts[dc.PortNumber];
} }
else
if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IIOPorts ioPortDevice))
{ {
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts; Debug.LogError("GetVersiportAnalogInput: Device {key} is not a valid device", dc.PortDeviceKey);
if (ioPortDev == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device {0} is not a valid device", dc.PortDeviceKey);
return null;
}
ioPortDevice = ioPortDev;
}
if (ioPortDevice == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device '0' is not a valid IIOPorts Device", dc.PortDeviceKey);
return null; return null;
} }
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts) if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
{ {
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber); Debug.LogError("GetVersiportAnalogInput: Device {key} does not contain a port {port}", dc.PortDeviceKey, dc.PortNumber);
return null; return null;
} }
if(!ioPortDevice.VersiPorts[dc.PortNumber].SupportsAnalogInput) if (!ioPortDevice.VersiPorts[dc.PortNumber].SupportsAnalogInput)
{ {
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device {0} does not support AnalogInput on port {1}", dc.PortDeviceKey, dc.PortNumber); Debug.LogError("GetVersiportAnalogInput: Device {key} does not support AnalogInput on port {port}", dc.PortDeviceKey, dc.PortNumber);
return null; return null;
} }
return ioPortDevice.VersiPorts[dc.PortNumber]; return ioPortDevice.VersiPorts[dc.PortNumber];
} }
} }
/// <summary> /// <summary>
/// Represents a GenericVersiportAbalogInputDeviceFactory /// Factory for creating GenericVersiportAnalogInputDevice devices
/// </summary> /// </summary>
public class GenericVersiportAbalogInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportAnalogInputDevice> public class GenericVersiportAnalogInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportAnalogInputDevice>
{ {
public GenericVersiportAbalogInputDeviceFactory() /// <summary>
/// Constructor for GenericVersiportAnalogInputDeviceFactory
/// </summary>
public GenericVersiportAnalogInputDeviceFactory()
{ {
TypeNames = new List<string>() { "versiportanaloginput" }; TypeNames = new List<string>() { "versiportanaloginput" };
} }
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc /> /// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc) public override EssentialsDevice BuildDevice(DeviceConfig dc)
{ {
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Versiport Device"); Debug.LogDebug("Factory Attempting to create new Generic Versiport Device");
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString()); var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());

View File

@@ -2,78 +2,82 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
using Newtonsoft.Json; using Newtonsoft.Json;
using Serilog.Events; using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core.CrestronIO namespace PepperDash.Essentials.Core.CrestronIO
{ {
/// <summary> /// <summary>
/// Represents a generic digital input deviced tied to a versiport /// Represents a generic digital input deviced tied to a versiport
/// </summary> /// </summary>
public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IPartitionStateProvider public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IPartitionStateProvider, IHasFeedback
{ {
public Versiport InputPort { get; private set; } private Versiport inputPort;
/// <summary>
/// Gets or sets the InputStateFeedback
/// </summary>
public BoolFeedback InputStateFeedback { get; private set; } public BoolFeedback InputStateFeedback { get; private set; }
Func<bool> InputStateFeedbackFunc /// <inheritdoc />
{ public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
get
{
return () => InputPort.DigitalIn;
}
}
/// <summary> /// <summary>
/// Gets or sets the PartitionPresentFeedback /// Gets or sets the PartitionPresentFeedback
/// </summary> /// </summary>
public BoolFeedback PartitionPresentFeedback { get; } public BoolFeedback PartitionPresentFeedback { get; }
public bool PartitionPresent => !InputStateFeedbackFunc(); /// <summary>
/// Get partition state
/// </summary>
public bool PartitionPresent => !inputPort.DigitalIn;
/// <summary>
/// Initializes a new instance of the <see cref="GenericVersiportDigitalInputDevice"/> class.
/// </summary>
/// <param name="key">key for device</param>
/// <param name="name">name for device</param>
/// <param name="postActivationFunc">function to call after activation. Should return the Versiport</param>
/// <param name="config">config for device</param>
public GenericVersiportDigitalInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) : public GenericVersiportDigitalInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
base(key, name) base(key, name)
{ {
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc); InputStateFeedback = new BoolFeedback("inputState", () => inputPort.DigitalIn);
PartitionPresentFeedback = new BoolFeedback(() => !InputStateFeedbackFunc()); PartitionPresentFeedback = new BoolFeedback("partitionPresent", () => !inputPort.DigitalIn);
AddPostActivationAction(() => AddPostActivationAction(() =>
{ {
InputPort = postActivationFunc(config); inputPort = postActivationFunc(config);
InputPort.Register(); inputPort.Register();
InputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput); inputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
if (config.DisablePullUpResistor) if (config.DisablePullUpResistor)
InputPort.DisablePullUpResistor = true; inputPort.DisablePullUpResistor = true;
InputPort.VersiportChange += InputPort_VersiportChange; inputPort.VersiportChange += InputPort_VersiportChange;
InputStateFeedback.FireUpdate(); InputStateFeedback.FireUpdate();
PartitionPresentFeedback.FireUpdate(); PartitionPresentFeedback.FireUpdate();
Debug.LogMessage(LogEventLevel.Debug, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor); this.LogDebug("Created GenericVersiportDigitalInputDevice for port {port}. DisablePullUpResistor: {pullUpResistorDisable}", config.PortNumber, inputPort.DisablePullUpResistor);
}); });
Feedbacks.Add(InputStateFeedback);
Feedbacks.Add(PartitionPresentFeedback);
} }
void InputPort_VersiportChange(Versiport port, VersiportEventArgs args) void InputPort_VersiportChange(Versiport port, VersiportEventArgs args)
{ {
Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event); this.LogDebug("Versiport change: {0}", args.Event);
if(args.Event == eVersiportEvent.DigitalInChange) if (args.Event == eVersiportEvent.DigitalInChange)
{ {
InputStateFeedback.FireUpdate(); InputStateFeedback.FireUpdate();
PartitionPresentFeedback.FireUpdate(); PartitionPresentFeedback.FireUpdate();
@@ -102,20 +106,20 @@ namespace PepperDash.Essentials.Core.CrestronIO
} }
else else
{ {
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
} }
try try
{ {
Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); this.LogDebug("Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// Link feedback for input state // Link feedback for input state
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]); InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
} }
catch (Exception e) catch (Exception e)
{ {
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key); this.LogError("Unable to link device {key}. Input is null. {message}", Key, e.Message);
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e); this.LogDebug(e, "Stack Trace: ");
} }
} }
@@ -127,63 +131,50 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary> /// </summary>
public static Versiport GetVersiportDigitalInput(IOPortConfig dc) public static Versiport GetVersiportDigitalInput(IOPortConfig dc)
{ {
IIOPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor")) if (dc.PortDeviceKey.Equals("processor"))
{ {
if (!Global.ControlSystem.SupportsVersiport) if (!Global.ControlSystem.SupportsVersiport)
{ {
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Processor does not support Versiports"); Debug.LogError("GetVersiportDigitalInput: Processor does not support Versiports");
return null; return null;
} }
ioPortDevice = Global.ControlSystem; return Global.ControlSystem.VersiPorts[dc.PortNumber];
} }
else
if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IIOPorts ioPortDevice))
{ {
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts; Debug.LogError("GetVersiportDigitalInput: Device {key} is not a valid device", dc.PortDeviceKey);
if (ioPortDev == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Device {0} is not a valid device", dc.PortDeviceKey);
return null;
}
ioPortDevice = ioPortDev;
}
if (ioPortDevice == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Device '0' is not a valid IIOPorts Device", dc.PortDeviceKey);
return null; return null;
} }
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts) if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
{ {
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber); Debug.LogError("GetVersiportDigitalInput: Device {key} does not contain versiport {port}", dc.PortDeviceKey, dc.PortNumber);
return null;
} }
return ioPortDevice.VersiPorts[dc.PortNumber]; return ioPortDevice.VersiPorts[dc.PortNumber];
} }
} }
/// <summary> /// <summary>
/// Represents a GenericVersiportDigitalInputDeviceFactory /// Factory class for GenericVersiportDigitalInputDevice
/// </summary> /// </summary>
public class GenericVersiportDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportDigitalInputDevice> public class GenericVersiportDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportDigitalInputDevice>
{ {
/// <summary>
/// Constructor for GenericVersiportDigitalInputDeviceFactory
/// </summary>
public GenericVersiportDigitalInputDeviceFactory() public GenericVersiportDigitalInputDeviceFactory()
{ {
TypeNames = new List<string>() { "versiportinput" }; TypeNames = new List<string>() { "versiportinput" };
} }
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc /> /// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc) public override EssentialsDevice BuildDevice(DeviceConfig dc)
{ {
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Versiport Device"); Debug.LogDebug("Factory Attempting to create new Generic Versiport Device");
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString()); var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());

View File

@@ -2,18 +2,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
using Newtonsoft.Json; using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using Serilog.Events; using Serilog.Events;
namespace PepperDash.Essentials.Core.CrestronIO namespace PepperDash.Essentials.Core.CrestronIO
@@ -21,76 +16,68 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// <summary> /// <summary>
/// Represents a generic digital input deviced tied to a versiport /// Represents a generic digital input deviced tied to a versiport
/// </summary> /// </summary>
public class GenericVersiportDigitalOutputDevice : EssentialsBridgeableDevice, IDigitalOutput public class GenericVersiportDigitalOutputDevice : EssentialsBridgeableDevice, IDigitalOutput, IHasFeedback
{ {
public Versiport OutputPort { get; private set; } private Versiport outputPort;
/// <summary>
/// Gets or sets the OutputStateFeedback
/// </summary>
public BoolFeedback OutputStateFeedback { get; private set; } public BoolFeedback OutputStateFeedback { get; private set; }
Func<bool> OutputStateFeedbackFunc /// <inheritdoc />
{ public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
get
{
return () => OutputPort.DigitalOut;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="GenericVersiportDigitalOutputDevice"/> class.
/// </summary>
public GenericVersiportDigitalOutputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) : public GenericVersiportDigitalOutputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
base(key, name) base(key, name)
{ {
OutputStateFeedback = new BoolFeedback(OutputStateFeedbackFunc); OutputStateFeedback = new BoolFeedback("outputState", () => outputPort.DigitalOut);
AddPostActivationAction(() => AddPostActivationAction(() =>
{ {
OutputPort = postActivationFunc(config); outputPort = postActivationFunc(config);
OutputPort.Register(); outputPort.Register();
if (!OutputPort.SupportsDigitalOutput) if (!outputPort.SupportsDigitalOutput)
{ {
Debug.LogMessage(LogEventLevel.Information, this, "Device does not support configuration as a Digital Output"); this.LogError("Device does not support configuration as a Digital Output");
return; return;
} }
OutputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalOutput); outputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalOutput);
OutputPort.VersiportChange += OutputPort_VersiportChange; outputPort.VersiportChange += OutputPort_VersiportChange;
}); });
} }
void OutputPort_VersiportChange(Versiport port, VersiportEventArgs args) void OutputPort_VersiportChange(Versiport port, VersiportEventArgs args)
{ {
Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event); this.LogDebug("Versiport change: {event}", args.Event);
if(args.Event == eVersiportEvent.DigitalOutChange) if (args.Event == eVersiportEvent.DigitalOutChange)
OutputStateFeedback.FireUpdate(); OutputStateFeedback.FireUpdate();
} }
/// <summary> /// <summary>
/// Set value of the versiport digital output /// Set value of the versiport digital output
/// </summary> /// </summary>
/// <param name="state">value to set the output to</param> /// <param name="state">value to set the output to</param>
/// <summary>
/// SetOutput method
/// </summary>
public void SetOutput(bool state) public void SetOutput(bool state)
{ {
if (OutputPort.SupportsDigitalOutput) if (!outputPort.SupportsDigitalOutput)
{ {
Debug.LogMessage(LogEventLevel.Information, this, "Passed the Check"); this.LogError("Versiport does not support Digital Output Mode");
return;
OutputPort.DigitalOut = state; }
}
else
{
Debug.LogMessage(LogEventLevel.Information, this, "Versiport does not support Digital Output Mode");
}
outputPort.DigitalOut = state;
} }
#region Bridge Linking #region Bridge Linking
@@ -114,12 +101,12 @@ namespace PepperDash.Essentials.Core.CrestronIO
} }
else else
{ {
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
} }
try try
{ {
Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); this.LogDebug("Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// Link feedback for input state // Link feedback for input state
OutputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OutputState.JoinNumber]); OutputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OutputState.JoinNumber]);
@@ -127,8 +114,8 @@ namespace PepperDash.Essentials.Core.CrestronIO
} }
catch (Exception e) catch (Exception e)
{ {
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key); this.LogError("Unable to link device: {message}", e.Message);
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e); this.LogDebug(e, "Stack Trace: ");
} }
} }
@@ -140,41 +127,28 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary> /// </summary>
public static Versiport GetVersiportDigitalOutput(IOPortConfig dc) public static Versiport GetVersiportDigitalOutput(IOPortConfig dc)
{ {
if (dc.PortDeviceKey.Equals("processor"))
IIOPorts ioPortDevice; {
if (!Global.ControlSystem.SupportsVersiport)
if (dc.PortDeviceKey.Equals("processor"))
{ {
if (!Global.ControlSystem.SupportsVersiport) Debug.LogError("GetVersiportDigitalOutput: Processor does not support Versiports");
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Processor does not support Versiports");
return null;
}
ioPortDevice = Global.ControlSystem;
}
else
{
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts;
if (ioPortDev == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Device {0} is not a valid device", dc.PortDeviceKey);
return null;
}
ioPortDevice = ioPortDev;
}
if (ioPortDevice == null)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Device '0' is not a valid IOPorts Device", dc.PortDeviceKey);
return null; return null;
} }
return Global.ControlSystem.VersiPorts[dc.PortNumber];
}
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts) if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IIOPorts ioPortDevice))
{ {
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber); Debug.LogError("GetVersiportDigitalOutput: Device {key} is not a valid device", dc.PortDeviceKey);
} return null;
var port = ioPortDevice.VersiPorts[dc.PortNumber]; }
return port;
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOutput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
return null;
}
return ioPortDevice.VersiPorts[dc.PortNumber];
} }
} }
@@ -184,18 +158,18 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary> /// </summary>
public class GenericVersiportDigitalOutputDeviceFactory : EssentialsDeviceFactory<GenericVersiportDigitalInputDevice> public class GenericVersiportDigitalOutputDeviceFactory : EssentialsDeviceFactory<GenericVersiportDigitalInputDevice>
{ {
/// <summary>
/// Initialize a new instance of the <see cref="GenericVersiportDigitalOutputDeviceFactory"/> class.
/// </summary>
public GenericVersiportDigitalOutputDeviceFactory() public GenericVersiportDigitalOutputDeviceFactory()
{ {
TypeNames = new List<string>() { "versiportoutput" }; TypeNames = new List<string>() { "versiportoutput" };
} }
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc /> /// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc) public override EssentialsDevice BuildDevice(DeviceConfig dc)
{ {
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Versiport Device"); Debug.LogDebug("Factory Attempting to create new Generic Versiport Device");
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString()); var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());

View File

@@ -12,6 +12,12 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary> /// </summary>
public interface IAnalogInput public interface IAnalogInput
{ {
/// <summary>
/// Get the InputValueFeedback.
/// </summary>
/// <remarks>
/// Updates when the analog input value changes
/// </remarks>
IntFeedback InputValueFeedback { get; } IntFeedback InputValueFeedback { get; }
} }
} }

View File

@@ -14,25 +14,28 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary> /// </summary>
public class IOPortConfig public class IOPortConfig
{ {
[JsonProperty("portDeviceKey")]
/// <summary> /// <summary>
/// Gets or sets the PortDeviceKey /// Gets or sets the PortDeviceKey
/// </summary> /// </summary>
[JsonProperty("portDeviceKey")]
public string PortDeviceKey { get; set; } public string PortDeviceKey { get; set; }
[JsonProperty("portNumber")]
/// <summary> /// <summary>
/// Gets or sets the PortNumber /// Gets or sets the PortNumber
/// </summary> /// </summary>
[JsonProperty("portNumber")]
public uint PortNumber { get; set; } public uint PortNumber { get; set; }
[JsonProperty("disablePullUpResistor")]
/// <summary> /// <summary>
/// Gets or sets the DisablePullUpResistor /// Gets or sets the DisablePullUpResistor
/// </summary> /// </summary>
[JsonProperty("disablePullUpResistor")]
public bool DisablePullUpResistor { get; set; } public bool DisablePullUpResistor { get; set; }
[JsonProperty("minimumChange")]
/// <summary> /// <summary>
/// Gets or sets the MinimumChange /// Gets or sets the MinimumChange
/// </summary> /// </summary>
[JsonProperty("minimumChange")]
public int MinimumChange { get; set; } public int MinimumChange { get; set; }
} }
} }

View File

@@ -18,7 +18,7 @@ namespace PepperDash.Essentials.Core
public List<string> TypeNames { get; protected set; } public List<string> TypeNames { get; protected set; }
/// <summary> /// <summary>
/// The method that will build the device /// Build the device using the configuration
/// </summary> /// </summary>
/// <param name="dc">The device config</param> /// <param name="dc">The device config</param>
/// <returns>An instance of the device</returns> /// <returns>An instance of the device</returns>

View File

@@ -12,7 +12,7 @@ namespace PepperDash.Essentials.Core
public interface IHasFeedback : IKeyed public interface IHasFeedback : IKeyed
{ {
/// <summary> /// <summary>
/// This method shall return a list of all Output objects on a device, /// This method returns a list of all Output objects on a device,
/// including all "aggregate" devices. /// including all "aggregate" devices.
/// </summary> /// </summary>
FeedbackCollection<Feedback> Feedbacks { get; } FeedbackCollection<Feedback> Feedbacks { get; }