Compare commits

...

8 Commits

Author SHA1 Message Date
Andrew Welker
72e67a1c4c fix: implement IHasFeedback for all IO devices and modify logging 2025-09-25 09:47:44 -05:00
Andrew Welker
f8728b6825 docs: update XML comments for EssentialsDeviceFactory 2025-09-25 09:46:55 -05:00
Andrew Welker
d9ef8a2289 docs: add XML comments for IAnalogInput 2025-09-25 09:46:03 -05:00
Andrew Welker
278408a3bc docs: reword XML comments for IHasFeedback Interface 2025-09-25 09:45:42 -05:00
Andrew Welker
5921b5dbb0 Merge pull request #1336 from PepperDash/hotfix/check-for-cs-lan-on-mctp
Hotfix/check for cs lan on mctp
2025-09-23 13:58:15 -04:00
Neil Dorin
ba0de5128f Update src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-23 11:56:57 -06:00
Neil Dorin
258699fbcd fix: Enhance AppUrl change logging
Updated logging to include the new AppUrl value when it changes. This provides better context in the logs, making it easier to track the specific URL that was set.
2025-09-18 18:23:12 -06:00
Neil Dorin
738504e9fc fix: Add error handling for network parameter retrieval
Introduced a try-catch block to handle exceptions when fetching the Crestron Ethernet adapter's ID, subnet mask, and IP address. Added logging for cases where the processor lacks a CS LAN. Also included a new using directive for Serilog.Events.
2025-09-18 14:48:21 -06:00
8 changed files with 225 additions and 281 deletions

View File

@@ -2,59 +2,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
namespace PepperDash.Essentials.Core.CrestronIO
{
[Description("Wrapper class for Digital Input")]
/// <summary>
/// Represents a GenericDigitalInputDevice
/// </summary>
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
/// [Description("Wrapper class for Digital Input")]
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IHasFeedback
{
/// <summary>
/// Gets or sets the InputPort
/// </summary>
public DigitalInput InputPort { get; private set; }
private DigitalInput inputPort;
/// <summary>
/// Gets or sets the InputStateFeedback
/// </summary>
public BoolFeedback InputStateFeedback { get; private set; }
Func<bool> InputStateFeedbackFunc
{
get
{
return () => InputPort.State;
}
}
/// <inheritdoc />
public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
/// <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,
IOPortConfig config)
: base(key, name)
{
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
InputStateFeedback = new BoolFeedback("inputState", () => inputPort.State);
AddPostActivationAction(() =>
{
InputPort = postActivationFunc(config);
inputPort = postActivationFunc(config);
InputPort.Register();
InputPort.StateChange += InputPort_StateChange;
inputPort.Register();
inputPort.StateChange += InputPort_StateChange;
});
}
@@ -71,41 +66,31 @@ namespace PepperDash.Essentials.Core.CrestronIO
private static DigitalInput GetDigitalInput(IOPortConfig dc)
{
IDigitalInputPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor"))
{
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;
}
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;
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);
Debug.LogError("GetDigitalInput: Device {key} is not a valid device", dc.PortDeviceKey);
return null;
}
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];
}
#endregion
@@ -131,20 +116,20 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
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
{
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
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
}
catch (Exception e)
{
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key);
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
this.LogError("Unable to link device {key}. {message}", Key, e.Message);
this.LogDebug(e, "Stack Trace: ");
}
}
@@ -153,22 +138,22 @@ namespace PepperDash.Essentials.Core.CrestronIO
#region Factory
/// <summary>
/// Represents a GenericDigitalInputDeviceFactory
/// Factory for creating GenericDigitalInputDevice devices
/// </summary>
public class GenericDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericDigitalInputDevice>
{
/// <summary>
/// Constructor for GenericDigitalInputDeviceFactory
/// </summary>
public GenericDigitalInputDeviceFactory()
{
TypeNames = new List<string>() { "digitalinput" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
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());

View File

@@ -2,66 +2,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
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
{
/// <summary>
/// Represents a generic digital input deviced tied to a versiport
/// </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; }
/// <summary>
/// Get the InputMinimumChangeFeedback
/// </summary>
/// <remarks>
/// Updates when the analog input minimum change value changes
/// </remarks>
public IntFeedback InputMinimumChangeFeedback { get; private set; }
Func<int> InputValueFeedbackFunc
{
get
{
return () => InputPort.AnalogIn;
}
}
Func<int> InputMinimumChangeFeedbackFunc
{
get { return () => InputPort.AnalogMinChange; }
}
/// <inheritdoc />
public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
/// <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) :
base(key, name)
{
InputValueFeedback = new IntFeedback(InputValueFeedbackFunc);
InputMinimumChangeFeedback = new IntFeedback(InputMinimumChangeFeedbackFunc);
InputValueFeedback = new IntFeedback("inputValue", () => inputPort.AnalogIn);
InputMinimumChangeFeedback = new IntFeedback("inputMinimumChange", () => inputPort.AnalogMinChange);
AddPostActivationAction(() =>
{
InputPort = postActivationFunc(config);
inputPort = postActivationFunc(config);
InputPort.Register();
inputPort.Register();
InputPort.SetVersiportConfiguration(eVersiportConfiguration.AnalogInput);
InputPort.AnalogMinChange = (ushort)(config.MinimumChange > 0 ? config.MinimumChange : 655);
inputPort.SetVersiportConfiguration(eVersiportConfiguration.AnalogInput);
inputPort.AnalogMinChange = (ushort)(config.MinimumChange > 0 ? config.MinimumChange : 655);
if (config.DisablePullUpResistor)
InputPort.DisablePullUpResistor = true;
inputPort.DisablePullUpResistor = true;
InputPort.VersiportChange += InputPort_VersiportChange;
Debug.LogMessage(LogEventLevel.Debug, this, "Created GenericVersiportAnalogInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor);
inputPort.VersiportChange += InputPort_VersiportChange;
this.LogDebug("Created GenericVersiportAnalogInputDevice on port {port}. DisablePullUpResistor: {pullUpResistorDisabled}", config.PortNumber, inputPort.DisablePullUpResistor);
});
}
@@ -69,20 +67,17 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// <summary>
/// Set minimum voltage change for device to update voltage changed method
/// </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>
/// <summary>
/// SetMinimumChange method
/// </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>
public void SetMinimumChange(ushort value)
{
InputPort.AnalogMinChange = value;
inputPort.AnalogMinChange = value;
}
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();
if (args.Event == eVersiportEvent.AnalogMinChangeChange)
InputMinimumChangeFeedback.FireUpdate();
@@ -91,9 +86,6 @@ namespace PepperDash.Essentials.Core.CrestronIO
#region Bridge Linking
/// <summary>
/// LinkToApi method
/// </summary>
/// <inheritdoc />
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
@@ -110,12 +102,12 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
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
{
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
InputValueFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputValue.JoinNumber]);
@@ -125,8 +117,8 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
catch (Exception e)
{
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key);
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
this.LogError("Unable to link device {key}: {message}", Key, e.Message);
this.LogDebug(e, "Stack Trace: ");
}
trilist.OnlineStatusChange += (d, args) =>
@@ -138,11 +130,6 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
void trilist_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
throw new NotImplementedException();
}
#endregion
@@ -151,70 +138,55 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary>
public static Versiport GetVersiportDigitalInput(IOPortConfig dc)
{
IIOPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor"))
{
if (!Global.ControlSystem.SupportsVersiport)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Processor does not support Versiports");
Debug.LogError("GetVersiportAnalogInput: Processor does not support Versiports");
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;
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);
Debug.LogError("GetVersiportAnalogInput: Device {key} is not a valid device", dc.PortDeviceKey);
return null;
}
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;
}
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 ioPortDevice.VersiPorts[dc.PortNumber];
}
}
/// <summary>
/// Represents a GenericVersiportAbalogInputDeviceFactory
/// Represents a GenericVersiportAnalogInputDeviceFactory
/// </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" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
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());

View File

@@ -2,78 +2,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
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
{
/// <summary>
/// Represents a generic digital input deviced tied to a versiport
/// </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; }
Func<bool> InputStateFeedbackFunc
{
get
{
return () => InputPort.DigitalIn;
}
}
/// <inheritdoc />
public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
/// <summary>
/// Gets or sets the PartitionPresentFeedback
/// </summary>
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) :
base(key, name)
{
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
PartitionPresentFeedback = new BoolFeedback(() => !InputStateFeedbackFunc());
InputStateFeedback = new BoolFeedback("inputState", () => inputPort.DigitalIn);
PartitionPresentFeedback = new BoolFeedback("partitionPresent", () => !inputPort.DigitalIn);
AddPostActivationAction(() =>
{
InputPort = postActivationFunc(config);
inputPort = postActivationFunc(config);
InputPort.Register();
inputPort.Register();
InputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
inputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
if (config.DisablePullUpResistor)
InputPort.DisablePullUpResistor = true;
inputPort.DisablePullUpResistor = true;
InputPort.VersiportChange += InputPort_VersiportChange;
inputPort.VersiportChange += InputPort_VersiportChange;
InputStateFeedback.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)
{
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();
PartitionPresentFeedback.FireUpdate();
@@ -102,20 +106,20 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
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
{
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
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
}
catch (Exception e)
{
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key);
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
this.LogError("Unable to link device {key}. Input is null. {message}", Key, e.Message);
this.LogDebug(e, "Stack Trace: ");
}
}
@@ -127,63 +131,50 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary>
public static Versiport GetVersiportDigitalInput(IOPortConfig dc)
{
IIOPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor"))
{
if (!Global.ControlSystem.SupportsVersiport)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Processor does not support Versiports");
Debug.LogError("GetVersiportDigitalInput: Processor does not support Versiports");
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;
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);
Debug.LogError("GetVersiportDigitalInput: Device {key} is not a valid device", dc.PortDeviceKey);
return null;
}
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];
}
}
/// <summary>
/// Represents a GenericVersiportDigitalInputDeviceFactory
/// Factory class for GenericVersiportDigitalInputDevice
/// </summary>
public class GenericVersiportDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportDigitalInputDevice>
{
/// <summary>
/// Constructor for GenericVersiportDigitalInputDeviceFactory
/// </summary>
public GenericVersiportDigitalInputDeviceFactory()
{
TypeNames = new List<string>() { "versiportinput" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
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());

View File

@@ -2,18 +2,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
namespace PepperDash.Essentials.Core.CrestronIO
@@ -21,76 +16,68 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// <summary>
/// Represents a generic digital input deviced tied to a versiport
/// </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; }
Func<bool> OutputStateFeedbackFunc
{
get
{
return () => OutputPort.DigitalOut;
}
}
/// <inheritdoc />
public FeedbackCollection<Feedback> Feedbacks { get; private set; } = new FeedbackCollection<Feedback>();
/// <summary>
/// Initializes a new instance of the <see cref="GenericVersiportDigitalOutputDevice"/> class.
/// </summary>
public GenericVersiportDigitalOutputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
base(key, name)
{
OutputStateFeedback = new BoolFeedback(OutputStateFeedbackFunc);
OutputStateFeedback = new BoolFeedback("outputState", () => outputPort.DigitalOut);
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;
}
OutputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalOutput);
outputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalOutput);
OutputPort.VersiportChange += OutputPort_VersiportChange;
outputPort.VersiportChange += OutputPort_VersiportChange;
});
}
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();
}
/// <summary>
/// Set value of the versiport digital output
/// </summary>
/// <param name="state">value to set the output to</param>
/// <summary>
/// SetOutput method
/// </summary>
/// <param name="state">value to set the output to</param>
public void SetOutput(bool state)
{
if (OutputPort.SupportsDigitalOutput)
{
Debug.LogMessage(LogEventLevel.Information, this, "Passed the Check");
OutputPort.DigitalOut = state;
}
else
{
Debug.LogMessage(LogEventLevel.Information, this, "Versiport does not support Digital Output Mode");
}
if (!outputPort.SupportsDigitalOutput)
{
this.LogError("Versiport does not support Digital Output Mode");
return;
}
outputPort.DigitalOut = state;
}
#region Bridge Linking
@@ -114,12 +101,12 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
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
{
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
OutputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OutputState.JoinNumber]);
@@ -127,8 +114,8 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
catch (Exception e)
{
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key);
Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
this.LogError("Unable to link device: {message}", e.Message);
this.LogDebug(e, "Stack Trace: ");
}
}
@@ -140,41 +127,28 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// </summary>
public static Versiport GetVersiportDigitalOutput(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, "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);
Debug.LogError("GetVersiportDigitalOuptut: Processor does not support Versiports");
return null;
}
return Global.ControlSystem.VersiPorts[dc.PortNumber];
}
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
{
Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
}
var port = ioPortDevice.VersiPorts[dc.PortNumber];
return port;
if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IIOPorts ioPortDevice))
{
Debug.LogError("GetVersiportDigitalOutput: Device {key} is not a valid device", dc.PortDeviceKey);
return null;
}
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>
public class GenericVersiportDigitalOutputDeviceFactory : EssentialsDeviceFactory<GenericVersiportDigitalInputDevice>
{
/// <summary>
/// Initialize a new instance of the <see cref="GenericVersiportDigitalOutputDeviceFactory"/> class.
/// </summary>
public GenericVersiportDigitalOutputDeviceFactory()
{
TypeNames = new List<string>() { "versiportoutput" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
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());

View File

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

View File

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

View File

@@ -12,7 +12,7 @@ namespace PepperDash.Essentials.Core
public interface IHasFeedback : IKeyed
{
/// <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.
/// </summary>
FeedbackCollection<Feedback> Feedbacks { get; }

View File

@@ -16,6 +16,7 @@ using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.DeviceInfo;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using PepperDash.Essentials.Core.UI;
using Serilog.Events;
using Feedback = PepperDash.Essentials.Core.Feedback;
namespace PepperDash.Essentials.Touchpanel
@@ -190,12 +191,27 @@ namespace PepperDash.Essentials.Touchpanel
RegisterForExtenders();
var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter);
var csSubnetMask = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, csAdapterId);
var csIpAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);
try
{
var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter);
var csSubnetMask = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, csAdapterId);
var csIpAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);
this.csSubnetMask = System.Net.IPAddress.Parse(csSubnetMask);
this.csIpAddress = System.Net.IPAddress.Parse(csIpAddress);
this.csSubnetMask = System.Net.IPAddress.Parse(csSubnetMask);
this.csIpAddress = System.Net.IPAddress.Parse(csIpAddress);
}
catch (ArgumentException)
{
Debug.LogInformation("This processor does not have a CS LAN", this);
}
catch (InvalidOperationException)
{
Debug.LogInformation("This processor does not have a CS LAN", this);
}
catch (Exception ex)
{
Debug.LogError($"Unexpected exception when checking CS LAN: {ex}", this);
}
}
/// <summary>
@@ -502,7 +518,7 @@ namespace PepperDash.Essentials.Touchpanel
_bridge.UserCodeChanged += UpdateFeedbacks;
_bridge.AppUrlChanged += (s, a) =>
{
this.LogInformation("AppURL changed");
this.LogInformation("AppURL changed: {appURL}", _bridge.AppUrl);
SetAppUrl(_bridge.AppUrl);
UpdateFeedbacks(s, a);
};