diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalInputJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalInputJoinMap.cs
index 085a33bd..82c09e54 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalInputJoinMap.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalInputJoinMap.cs
@@ -1,10 +1,10 @@
using System;
-namespace PepperDash.Essentials.Core.Bridges
-{
- public class IDigitalInputJoinMap : JoinMapBaseAdvanced
- {
-
+namespace PepperDash.Essentials.Core.Bridges
+{
+ public class IDigitalInputJoinMap : JoinMapBaseAdvanced
+ {
+
[JoinName("InputState")]
public JoinDataComplete InputState = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Room Email Url", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
@@ -26,6 +26,6 @@ namespace PepperDash.Essentials.Core.Bridges
protected IDigitalInputJoinMap(uint joinStart, Type type)
: base(joinStart, type)
{
- }
- }
+ }
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalOutputJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalOutputJoinMap.cs
new file mode 100644
index 00000000..cbe62398
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalOutputJoinMap.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace PepperDash.Essentials.Core.Bridges
+{
+ public class IDigitalOutputJoinMap : JoinMapBaseAdvanced
+ {
+
+ [JoinName("OutputState")]
+ public JoinDataComplete OutputState = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
+ new JoinMetadata { Description = "Get / Set state of Digital Input", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
+
+ ///
+ /// Constructor to use when instantiating this Join Map without inheriting from it
+ ///
+ /// Join this join map will start at
+ public IDigitalOutputJoinMap(uint joinStart)
+ : this(joinStart, typeof(IDigitalOutputJoinMap))
+ {
+ }
+
+ ///
+ /// Constructor to use when extending this Join map
+ ///
+ /// Join this join map will start at
+ /// Type of the child join map
+ protected IDigitalOutputJoinMap(uint joinStart, Type type)
+ : base(joinStart, type)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/DinIo8/DinIo8Controller.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/DinIo8/DinIo8Controller.cs
new file mode 100644
index 00000000..794fe609
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/DinIo8/DinIo8Controller.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using Crestron.SimplSharpPro;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.GeneralIO;
+using PepperDash.Core;
+using PepperDash.Essentials.Core.Bridges;
+using PepperDash.Essentials.Core.Config;
+
+namespace PepperDash.Essentials.Core.CrestronIO
+{
+ public class DinIo8Controller:CrestronGenericBaseDevice, IIOPorts
+ {
+ private DinIo8 _device;
+
+ public DinIo8Controller(string key, Func preActivationFunc, DeviceConfig config):base(key, config.Name)
+ {
+ AddPreActivationAction(() =>
+ {
+ _device = preActivationFunc(config);
+
+ RegisterCrestronGenericBase(_device);
+ });
+ }
+
+ #region Implementation of IIOPorts
+
+ public CrestronCollection VersiPorts
+ {
+ get { return _device.VersiPorts; }
+ }
+
+ public int NumberOfVersiPorts
+ {
+ get { return _device.NumberOfVersiPorts; }
+ }
+
+ #endregion
+
+
+ }
+
+ public class DinIo8ControllerFactory : EssentialsDeviceFactory
+ {
+ public DinIo8ControllerFactory()
+ {
+ TypeNames = new List() { "DinIo8" };
+ }
+
+ public override EssentialsDevice BuildDevice(DeviceConfig dc)
+ {
+ Debug.Console(1, "Factory Attempting to create new DinIo8 Device");
+
+ return new DinIo8Controller(dc.Key, GetDinIo8Device, dc);
+ }
+
+ static DinIo8 GetDinIo8Device(DeviceConfig dc)
+ {
+ var control = CommFactory.GetControlPropertiesConfig(dc);
+ var cresnetId = control.CresnetIdInt;
+ var branchId = control.ControlPortNumber;
+ var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
+
+ if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
+ {
+ Debug.Console(0, "Device {0} is a valid cresnet master - creating new DinIo8", parentKey);
+ return new DinIo8(cresnetId, Global.ControlSystem);
+ }
+ var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches;
+
+ if (cresnetBridge != null)
+ {
+ Debug.Console(0, "Device {0} is a valid cresnet master - creating new DinIo8", parentKey);
+ return new DinIo8(cresnetId, cresnetBridge.CresnetBranches[branchId]);
+ }
+ Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Outputs/GenericVersiportOutputDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Outputs/GenericVersiportOutputDevice.cs
new file mode 100644
index 00000000..197a5b19
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Outputs/GenericVersiportOutputDevice.cs
@@ -0,0 +1,176 @@
+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;
+
+namespace PepperDash.Essentials.Core.CrestronIO
+{
+ ///
+ /// Represents a generic digital input deviced tied to a versiport
+ ///
+ public class GenericVersiportDigitalOutputDevice : EssentialsBridgeableDevice, IDigitalOutput
+ {
+ public Versiport OutputPort { get; private set; }
+
+ public BoolFeedback OutputStateFeedback { get; private set; }
+
+ Func OutputStateFeedbackFunc
+ {
+ get
+ {
+ return () => OutputPort.DigitalOut;
+ }
+ }
+
+ public GenericVersiportDigitalOutputDevice(string key, string name, Func postActivationFunc, IOPortConfig config) :
+ base(key, name)
+ {
+ OutputStateFeedback = new BoolFeedback(OutputStateFeedbackFunc);
+
+ AddPostActivationAction(() =>
+ {
+ OutputPort = postActivationFunc(config);
+
+ OutputPort.Register();
+
+ OutputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalOutput);
+ if (config.DisablePullUpResistor)
+ OutputPort.DisablePullUpResistor = true;
+
+ OutputPort.VersiportChange += OutputPort_VersiportChange;
+
+
+
+ Debug.Console(1, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, OutputPort.DisablePullUpResistor);
+
+ });
+
+ }
+
+ void OutputPort_VersiportChange(Versiport port, VersiportEventArgs args)
+ {
+ Debug.Console(1, this, "Versiport change: {0}", args.Event);
+
+ if(args.Event == eVersiportEvent.DigitalOutChange)
+ OutputStateFeedback.FireUpdate();
+ }
+
+ ///
+ /// Set value of the versiport digital output
+ ///
+ /// value to set the output to
+ public void SetOutput(bool state)
+ {
+ OutputPort.DigitalOut = state;
+ }
+
+ #region Bridge Linking
+
+ public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+ var joinMap = new IDigitalOutputJoinMap(joinStart);
+
+ var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
+
+ if (!string.IsNullOrEmpty(joinMapSerialized))
+ joinMap = JsonConvert.DeserializeObject(joinMapSerialized);
+
+ if (bridge != null)
+ {
+ bridge.AddJoinMap(Key, joinMap);
+ }
+ else
+ {
+ Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
+ }
+
+ try
+ {
+ Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
+
+ // Link feedback for input state
+ OutputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OutputState.JoinNumber]);
+ trilist.SetBoolSigAction(joinMap.OutputState.JoinNumber, SetOutput);
+ }
+ catch (Exception e)
+ {
+ Debug.Console(1, this, "Unable to link device '{0}'. Input is null", Key);
+ Debug.Console(1, this, "Error: {0}", e);
+ }
+ }
+
+ #endregion
+
+
+ public static Versiport GetVersiportDigitalOutput(IOPortConfig dc)
+ {
+
+ IIOPorts ioPortDevice;
+
+ if (dc.PortDeviceKey.Equals("processor"))
+ {
+ if (!Global.ControlSystem.SupportsVersiport)
+ {
+ Debug.Console(0, "GetVersiportDigitalOuptut: Processor does not support Versiports");
+ return null;
+ }
+ ioPortDevice = Global.ControlSystem;
+ }
+ else
+ {
+ var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts;
+ if (ioPortDev == null)
+ {
+ Debug.Console(0, "GetVersiportDigitalOuptut: Device {0} is not a valid device", dc.PortDeviceKey);
+ return null;
+ }
+ ioPortDevice = ioPortDev;
+ }
+ if (ioPortDevice == null)
+ {
+ Debug.Console(0, "GetVersiportDigitalOuptut: Device '0' is not a valid IIOPorts Device", dc.PortDeviceKey);
+ return null;
+ }
+
+ if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
+ {
+ Debug.Console(0, "GetVersiportDigitalOuptut: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
+ }
+
+ return ioPortDevice.VersiPorts[dc.PortNumber];
+
+ }
+ }
+
+
+ public class GenericVersiportDigitalOutputDeviceFactory : EssentialsDeviceFactory
+ {
+ public GenericVersiportDigitalOutputDeviceFactory()
+ {
+ TypeNames = new List() { "versiportoutput" };
+ }
+
+ public override EssentialsDevice BuildDevice(DeviceConfig dc)
+ {
+ Debug.Console(1, "Factory Attempting to create new Generic Versiport Device");
+
+ var props = JsonConvert.DeserializeObject(dc.Properties.ToString());
+
+ if (props == null) return null;
+
+ var portDevice = new GenericVersiportDigitalOutputDevice(dc.Key, dc.Name, GenericVersiportDigitalOutputDevice.GetVersiportDigitalOutput, props);
+
+ return portDevice;
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Outputs/IDigitalOutput.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Outputs/IDigitalOutput.cs
new file mode 100644
index 00000000..b4151941
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Outputs/IDigitalOutput.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+
+namespace PepperDash.Essentials.Core.CrestronIO
+{
+ ///
+ /// Represents a device that provides digital input
+ ///
+ public interface IDigitalOutput
+ {
+ BoolFeedback OutputStateFeedback { get; }
+ void SetOutput(bool state);
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj
index dfa59b88..2cf2928c 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj
@@ -123,6 +123,7 @@
+
@@ -179,12 +180,15 @@
+
+
+