Merge branch 'development' into hotfix/bridge-registration

This commit is contained in:
Andrew Welker
2020-07-08 11:33:20 -07:00
committed by GitHub
31 changed files with 3183 additions and 2271 deletions

View File

@@ -198,11 +198,11 @@ namespace PepperDash.Essentials.Core.Bridges
var uo = Eisc.BooleanOutput[join].UserObject as Action<bool>;
if (uo != null)
{
Debug.Console(1, this, "Executing Action: {0}", uo.ToString());
Debug.Console(2, this, "Executing Action: {0}", uo.ToString());
uo(Convert.ToBoolean(state));
}
else
Debug.Console(1, this, "User Action is null. Nothing to Execute");
Debug.Console(2, this, "User Action is null. Nothing to Execute");
break;
}
case "analog":
@@ -210,27 +210,27 @@ namespace PepperDash.Essentials.Core.Bridges
var uo = Eisc.BooleanOutput[join].UserObject as Action<ushort>;
if (uo != null)
{
Debug.Console(1, this, "Executing Action: {0}", uo.ToString());
Debug.Console(2, this, "Executing Action: {0}", uo.ToString());
uo(Convert.ToUInt16(state));
}
else
Debug.Console(1, this, "User Action is null. Nothing to Execute"); break;
Debug.Console(2, this, "User Action is null. Nothing to Execute"); break;
}
case "serial":
{
var uo = Eisc.BooleanOutput[join].UserObject as Action<string>;
if (uo != null)
{
Debug.Console(1, this, "Executing Action: {0}", uo.ToString());
Debug.Console(2, this, "Executing Action: {0}", uo.ToString());
uo(Convert.ToString(state));
}
else
Debug.Console(1, this, "User Action is null. Nothing to Execute");
Debug.Console(2, this, "User Action is null. Nothing to Execute");
break;
}
default:
{
Debug.Console(1, "Unknown join type. Use digital/serial/analog");
Debug.Console(2, "Unknown join type. Use digital/serial/analog");
break;
}
}

View File

@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash_Essentials_Core.Bridges.JoinMaps
{
public class GlsPartitionSensorJoinMap : JoinMapBaseAdvanced
{
[JoinName("IsOnline")]
public JoinDataComplete IsOnline = new JoinDataComplete(
new JoinData()
{
JoinNumber = 1,
JoinSpan = 1
},
new JoinMetadata()
{
Description = "Sensor Is Online",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(
new JoinData()
{
JoinNumber = 1,
JoinSpan = 1
},
new JoinMetadata()
{
Description = "Sensor Name",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("Enable")]
public JoinDataComplete Enable = new JoinDataComplete(
new JoinData()
{
JoinNumber = 2,
JoinSpan = 1
},
new JoinMetadata()
{
Description = "Sensor Enable",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("PartitionSensed")]
public JoinDataComplete PartitionSensed = new JoinDataComplete(
new JoinData()
{
JoinNumber = 3,
JoinSpan = 1
},
new JoinMetadata()
{
Description = "Sensor Partition Sensed",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("PartitionNotSensed")]
public JoinDataComplete PartitionNotSensed = new JoinDataComplete(
new JoinData()
{
JoinNumber = 4,
JoinSpan = 1
},
new JoinMetadata()
{
Description = "Sensor Partition Not Sensed",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("IncreaseSensitivity")]
public JoinDataComplete IncreaseSensitivity = new JoinDataComplete(
new JoinData()
{
JoinNumber = 6,
JoinSpan = 1
},
new JoinMetadata()
{
Description = "Sensor Increase Sensitivity",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("DecreaseSensitivity")]
public JoinDataComplete DecreaseSensitivity = new JoinDataComplete(
new JoinData()
{
JoinNumber = 7,
JoinSpan = 1
},
new JoinMetadata()
{
Description = "Sensor Decrease Sensitivity",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("Sensitivity")]
public JoinDataComplete Sensitivity = new JoinDataComplete(
new JoinData()
{
JoinNumber = 2,
JoinSpan = 1
},
new JoinMetadata()
{
Description = "Sensor Sensitivity",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Analog
});
public GlsPartitionSensorJoinMap(uint joinStart)
: base(joinStart, typeof (GlsPartitionSensorJoinMap))
{
}
}
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.GeneralIO;
@@ -13,21 +14,30 @@ namespace PepperDash.Essentials.Core.CrestronIO
[Description("Wrapper class for the C2N-RTHS sensor")]
public class C2nRthsController : CrestronGenericBridgeableBaseDevice
{
private readonly C2nRths _device;
private C2nRths _device;
public IntFeedback TemperatureFeedback { get; private set; }
public IntFeedback HumidityFeedback { get; private set; }
public C2nRthsController(string key, string name, GenericBase hardware) : base(key, name, hardware)
public C2nRthsController(string key, Func<DeviceConfig, C2nRths> preActivationFunc,
DeviceConfig config)
: base(key, config.Name)
{
_device = hardware as C2nRths;
TemperatureFeedback = new IntFeedback(() => _device.TemperatureFeedback.UShortValue);
HumidityFeedback = new IntFeedback(() => _device.HumidityFeedback.UShortValue);
AddPreActivationAction(() =>
{
_device = preActivationFunc(config);
if (_device != null) _device.BaseEvent += DeviceOnBaseEvent;
RegisterCrestronGenericBase(_device);
TemperatureFeedback = new IntFeedback(() => _device.TemperatureFeedback.UShortValue);
HumidityFeedback = new IntFeedback(() => _device.HumidityFeedback.UShortValue);
if (_device != null) _device.BaseEvent += DeviceOnBaseEvent;
});
}
private void DeviceOnBaseEvent(GenericBase device, BaseEventArgs args)
{
switch (args.EventId)
@@ -76,24 +86,63 @@ namespace PepperDash.Essentials.Core.CrestronIO
HumidityFeedback.LinkInputSig(trilist.UShortInput[joinMap.Humidity.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = Name;
}
}
public class C2nRthsControllerFactory : EssentialsDeviceFactory<C2nRthsController>
{
public C2nRthsControllerFactory()
{
TypeNames = new List<string>() { "c2nrths" };
trilist.OnlineStatusChange += (d, args) =>
{
if (!args.DeviceOnLine) return;
UpdateFeedbacksWhenOnline();
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = Name;
};
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
private void UpdateFeedbacksWhenOnline()
{
Debug.Console(1, "Factory Attempting to create new C2N-RTHS Device");
IsOnline.FireUpdate();
TemperatureFeedback.FireUpdate();
HumidityFeedback.FireUpdate();
}
#region PreActivation
private static C2nRths GetC2nRthsDevice(DeviceConfig dc)
{
var control = CommFactory.GetControlPropertiesConfig(dc);
var cresnetId = control.CresnetIdInt;
var branchId = control.ControlPortNumber;
var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
return new C2nRthsController(dc.Key, dc.Name, new C2nRths(cresnetId, Global.ControlSystem));
if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
{
Debug.Console(0, "Device {0} is a valid cresnet master - creating new C2nRths", parentKey);
return new C2nRths(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 C2nRths", parentKey);
return new C2nRths(cresnetId, cresnetBridge.CresnetBranches[branchId]);
}
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
return null;
}
#endregion
public class C2nRthsControllerFactory : EssentialsDeviceFactory<C2nRthsController>
{
public C2nRthsControllerFactory()
{
TypeNames = new List<string>() { "c2nrths" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new C2N-RTHS Device");
return new C2nRthsController(dc.Key, GetC2nRthsDevice, dc);
}
}
}
}

View File

@@ -0,0 +1,51 @@
using System.Collections.Generic;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core
{
public class DinCenCn2Controller : CrestronGenericBaseDevice, IHasCresnetBranches
{
private readonly DinCenCn2 _device;
public CrestronCollection<CresnetBranch> CresnetBranches
{
get {
return _device != null ? _device.Branches : null;
}
}
public DinCenCn2Controller(string key, string name, DinCenCn2 device, DeviceConfig config)
: base(key, name, device)
{
_device = device;
}
public class DinCenCn2ControllerFactory : EssentialsDeviceFactory<DinCenCn2Controller>
{
public DinCenCn2ControllerFactory()
{
TypeNames = new List<string>() { "dincencn2", "dincencn2poe", "din-cencn2", "din-cencn2-poe" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new C2N-RTHS Device");
var control = CommFactory.GetControlPropertiesConfig(dc);
var ipid = control.IpIdInt;
if (dc.Type.ToLower().Contains("poe"))
{
return new DinCenCn2Controller(dc.Key, dc.Name, new DinCenCn2Poe(ipid, Global.ControlSystem), dc);
}
return new DinCenCn2Controller(dc.Key, dc.Name, new DinCenCn2(ipid, Global.ControlSystem), dc);
}
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
namespace PepperDash.Essentials.Core
{
public interface IHasCresnetBranches
{
CrestronCollection<CresnetBranch> CresnetBranches { get; }
}
}

View File

@@ -13,7 +13,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
[Description("Wrapper class for the Crestron StatusSign device")]
public class StatusSignController : CrestronGenericBridgeableBaseDevice
{
private readonly StatusSign _device;
private StatusSign _device;
public BoolFeedback RedLedEnabledFeedback { get; private set; }
public BoolFeedback GreenLedEnabledFeedback { get; private set; }
@@ -23,34 +23,40 @@ namespace PepperDash.Essentials.Core.CrestronIO
public IntFeedback GreenLedBrightnessFeedback { get; private set; }
public IntFeedback BlueLedBrightnessFeedback { get; private set; }
public StatusSignController(string key, string name, GenericBase hardware) : base(key, name, hardware)
public StatusSignController(string key, Func<DeviceConfig, StatusSign> preActivationFunc, DeviceConfig config) : base(key, config.Name)
{
_device = hardware as StatusSign;
AddPreActivationAction(() =>
{
_device = preActivationFunc(config);
RedLedEnabledFeedback =
RegisterCrestronGenericBase(_device);
RedLedEnabledFeedback =
new BoolFeedback(
() =>
_device.Leds[(uint) StatusSign.Led.eLedColor.Red]
.ControlFeedback.BoolValue);
GreenLedEnabledFeedback =
new BoolFeedback(
() =>
_device.Leds[(uint) StatusSign.Led.eLedColor.Green]
.ControlFeedback.BoolValue);
BlueLedEnabledFeedback =
new BoolFeedback(
() =>
_device.Leds[(uint) StatusSign.Led.eLedColor.Blue]
_device.Leds[(uint)StatusSign.Led.eLedColor.Red]
.ControlFeedback.BoolValue);
GreenLedEnabledFeedback =
new BoolFeedback(
() =>
_device.Leds[(uint)StatusSign.Led.eLedColor.Green]
.ControlFeedback.BoolValue);
BlueLedEnabledFeedback =
new BoolFeedback(
() =>
_device.Leds[(uint)StatusSign.Led.eLedColor.Blue]
.ControlFeedback.BoolValue);
RedLedBrightnessFeedback =
new IntFeedback(() => (int) _device.Leds[(uint) StatusSign.Led.eLedColor.Red].BrightnessFeedback);
GreenLedBrightnessFeedback =
new IntFeedback(() => (int) _device.Leds[(uint) StatusSign.Led.eLedColor.Green].BrightnessFeedback);
BlueLedBrightnessFeedback =
new IntFeedback(() => (int) _device.Leds[(uint) StatusSign.Led.eLedColor.Blue].BrightnessFeedback);
RedLedBrightnessFeedback =
new IntFeedback(() => (int)_device.Leds[(uint)StatusSign.Led.eLedColor.Red].BrightnessFeedback);
GreenLedBrightnessFeedback =
new IntFeedback(() => (int)_device.Leds[(uint)StatusSign.Led.eLedColor.Green].BrightnessFeedback);
BlueLedBrightnessFeedback =
new IntFeedback(() => (int)_device.Leds[(uint)StatusSign.Led.eLedColor.Blue].BrightnessFeedback);
if (_device != null) _device.BaseEvent += _device_BaseEvent;
if (_device != null) _device.BaseEvent += _device_BaseEvent;
});
}
void _device_BaseEvent(GenericBase device, BaseEventArgs args)
@@ -167,23 +173,51 @@ namespace PepperDash.Essentials.Core.CrestronIO
device.SetColor(redBrightness, greenBrightness, blueBrightness);
}
}
public class StatusSignControllerFactory : EssentialsDeviceFactory<StatusSignController>
{
public StatusSignControllerFactory()
#region PreActivation
private static StatusSign GetStatusSignDevice(DeviceConfig dc)
{
TypeNames = new List<string>() { "statussign" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new StatusSign Device");
var control = CommFactory.GetControlPropertiesConfig(dc);
var cresnetId = control.CresnetIdInt;
var branchId = control.ControlPortNumber;
var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
return new StatusSignController(dc.Key, dc.Name, new StatusSign(cresnetId, Global.ControlSystem));
if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
{
Debug.Console(0, "Device {0} is a valid cresnet master - creating new StatusSign", parentKey);
return new StatusSign(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 StatusSign", parentKey);
return new StatusSign(cresnetId, cresnetBridge.CresnetBranches[branchId]);
}
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
return null;
}
#endregion
public class StatusSignControllerFactory : EssentialsDeviceFactory<StatusSignController>
{
public StatusSignControllerFactory()
{
TypeNames = new List<string>() { "statussign" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new StatusSign Device");
var control = CommFactory.GetControlPropertiesConfig(dc);
var cresnetId = control.CresnetIdInt;
return new StatusSignController(dc.Key, GetStatusSignDevice, dc);
}
}
}
}

View File

@@ -1,7 +1,9 @@
using System.Linq;
using System;
using System.Linq;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Core.JsonStandardObjects;
using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.Core
@@ -11,7 +13,7 @@ namespace PepperDash.Essentials.Core
/// </summary>
public abstract class CrestronGenericBaseDevice : EssentialsDevice, IOnline, IHasFeedback, ICommunicationMonitor, IUsageTracking
{
public virtual GenericBase Hardware { get; protected set; }
protected GenericBase Hardware;
/// <summary>
/// Returns a list containing the Outputs that we want to expose.
@@ -42,6 +44,24 @@ namespace PepperDash.Essentials.Core
CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, hardware, 120000, 300000);
}
protected CrestronGenericBaseDevice(string key, string name)
: base(key, name)
{
Feedbacks = new FeedbackCollection<Feedback>();
}
protected void RegisterCrestronGenericBase(GenericBase hardware)
{
Hardware = hardware;
IsOnline = new BoolFeedback("IsOnlineFeedback", () => Hardware.IsOnline);
IsRegistered = new BoolFeedback("IsRegistered", () => Hardware.Registered);
IpConnectionsText = new StringFeedback("IpConnectionsText", () => Hardware.ConnectedIpList != null ? string.Join(",", Hardware.ConnectedIpList.Select(cip => cip.DeviceIpAddress).ToArray()) : string.Empty);
AddToFeedbackList(IsOnline, IpConnectionsText);
CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, hardware, 120000, 300000);
}
/// <summary>
/// Make sure that overriding classes call this!
/// Registers the Crestron device, connects up to the base events, starts communication monitor
@@ -135,6 +155,11 @@ namespace PepperDash.Essentials.Core
{
}
protected CrestronGenericBridgeableBaseDevice(string key, string name)
: base(key, name)
{
}
public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
}

View File

@@ -238,6 +238,42 @@ namespace PepperDash.Essentials.Core
}
}
public static void AddDevice(IEnumerable<IKeyed> devicesToAdd)
{
try
{
if (!DeviceCriticalSection.TryEnter())
{
Debug.Console(0, Debug.ErrorLogLevel.Error,
"Currently unable to add devices to Device Manager. Please try again");
return;
}
if (!AddDeviceEnabled)
{
Debug.Console(0, Debug.ErrorLogLevel.Error,
"All devices have been activated. Adding new devices is not allowed.");
return;
}
foreach (var dev in devicesToAdd)
{
try
{
Devices.Add(dev.Key, dev);
}
catch (ArgumentException ex)
{
Debug.Console(0, "Error adding device with key {0} to Device Manager: {1}\r\nStack Trace: {2}",
dev.Key, ex.Message, ex.StackTrace);
}
}
}
finally
{
DeviceCriticalSection.Leave();
}
}
public static void RemoveDevice(IKeyed newDev)
{
try

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash_Essentials_Core
{
public class IsReadyEventArgs : EventArgs
{
public bool IsReady { get; set; }
public IsReadyEventArgs(bool data)
{
IsReady = data;
}
}
public interface IHasReady
{
event EventHandler<IsReadyEventArgs> IsReadyEvent;
bool IsReady { get; }
}
}

View File

@@ -6,134 +6,192 @@ using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.Gateways;
using Newtonsoft.Json;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash_Essentials_Core;
namespace PepperDash.Essentials.Core
namespace PepperDash.Essentials.Core
{
[Description("Wrapper class for Crestron Infinet-EX Gateways")]
public class CenRfgwController : CrestronGenericBaseDevice
{
private GatewayBase _Gateway;
public GatewayBase GateWay { get { return _Gateway; } }
/// <summary>
/// Constructor for the on-board gateway
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
public CenRfgwController(string key, string name, GatewayBase gateway) :
base(key, name, gateway)
{
_Gateway = gateway;
}
public static CenRfgwController GetNewExGatewayController(string key, string name, ushort ipId, ushort cresnetId, string gatewayType)
{
eExGatewayType type = (eExGatewayType)Enum.Parse(typeof(eExGatewayType), gatewayType, true);
try
{
var cs = Global.ControlSystem;
GatewayBase gw = null;
switch (type)
{
case eExGatewayType.Ethernet:
gw = new CenRfgwEx(ipId, cs);
break;
case eExGatewayType.EthernetShared:
gw = new CenRfgwExEthernetSharable(ipId, cs);
break;
case eExGatewayType.Cresnet:
gw = new CenRfgwExCresnet(cresnetId, cs);
break;
}
return new CenRfgwController(key, name, gw);
}
catch (Exception)
{
Debug.Console(0, "ERROR: Cannot create EX Gateway, id {0}, type {1}", type == eExGatewayType.Cresnet ? cresnetId : ipId, gatewayType);
return null;
}
}
public static CenRfgwController GetNewErGatewayController(string key, string name, ushort ipId, ushort cresnetId, string gatewayType)
{
eExGatewayType type = (eExGatewayType)Enum.Parse(typeof(eExGatewayType), gatewayType, true);
try
{
var cs = Global.ControlSystem;
GatewayBase gw = null;
switch (type)
{
case eExGatewayType.Ethernet:
gw = new CenErfgwPoe(ipId, cs);
break;
case eExGatewayType.EthernetShared:
gw = new CenErfgwPoeEthernetSharable(ipId, cs);
break;
case eExGatewayType.Cresnet:
gw = new CenErfgwPoeCresnet(cresnetId, cs);
break;
}
return new CenRfgwController(key, name, gw);
}
catch (Exception)
{
Debug.Console(0, "ERROR: Cannot create ER Gateway, id {0}, type {1}", type== eExGatewayType.Cresnet ? cresnetId : ipId, gatewayType);
return null;
}
}
}
public enum eExGatewayType
{
Ethernet, EthernetShared, Cresnet
}
[Description("Wrapper class for Crestron Infinet-EX Gateways")]
public class CenRfgwController : CrestronGenericBaseDevice, IHasReady
{
public event EventHandler<IsReadyEventArgs> IsReadyEvent;
public bool IsReady { get; private set; }
#region Factory
public class CenRfgwControllerFactory : EssentialsDeviceFactory<CenRfgwController>
{
public CenRfgwControllerFactory()
{
TypeNames = new List<string>() { "cenrfgwex", "cenerfgwpoe" };
}
private GatewayBase _gateway;
public override EssentialsDevice BuildDevice(DeviceConfig dc)
public GatewayBase GateWay
{
Debug.Console(1, "Factory Attempting to create new CEN-GWEXER Device");
var props = JsonConvert.DeserializeObject<EssentialsRfGatewayConfig>(dc.Properties.ToString());
var type = dc.Type.ToLower();
var control = props.Control;
var ipid = control.IpIdInt;
var cresnetId = control.CresnetIdInt;
var gatewayType = props.GatewayType;
switch (type)
{
case ("cenrfgwex"):
return CenRfgwController.GetNewExGatewayController(dc.Key, dc.Name,
(ushort)ipid, (ushort)cresnetId, gatewayType);
case ("cenerfgwpoe"):
return CenRfgwController.GetNewErGatewayController(dc.Key, dc.Name,
(ushort)ipid, (ushort)cresnetId, gatewayType);
default:
return null;
}
get { return _gateway; }
}
/// <summary>
/// Constructor for the on-board gateway
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="gateway"></param>
public CenRfgwController(string key, string name, GatewayBase gateway) :
base(key, name, gateway)
{
_gateway = gateway;
IsReady = true;
FireIsReadyEvent(IsReady);
}
public CenRfgwController(string key, Func<DeviceConfig, GatewayBase> preActivationFunc, DeviceConfig config) :
base(key, config.Name)
{
IsReady = false;
FireIsReadyEvent(IsReady);
AddPreActivationAction(() =>
{
_gateway = preActivationFunc(config);
IsReady = true;
RegisterCrestronGenericBase(_gateway);
FireIsReadyEvent(IsReady);
});
}
public static GatewayBase GetNewIpRfGateway(DeviceConfig dc)
{
var control = CommFactory.GetControlPropertiesConfig(dc);
var type = dc.Type;
var ipId = control.IpIdInt;
if (type.Equals("cenrfgwex", StringComparison.InvariantCultureIgnoreCase))
{
return new CenRfgwEx(ipId, Global.ControlSystem);
}
if (type.Equals("cenerfgwpoe", StringComparison.InvariantCultureIgnoreCase))
{
return new CenErfgwPoe(ipId, Global.ControlSystem);
}
return null;
}
private void FireIsReadyEvent(bool data)
{
var handler = IsReadyEvent;
if (handler == null) return;
handler(this, new IsReadyEventArgs(data));
}
public static GatewayBase GetNewSharedIpRfGateway(DeviceConfig dc)
{
var control = CommFactory.GetControlPropertiesConfig(dc);
var ipId = control.IpIdInt;
if (dc.Type.Equals("cenrfgwex", StringComparison.InvariantCultureIgnoreCase))
{
return new CenRfgwExEthernetSharable(ipId, Global.ControlSystem);
}
if (dc.Type.Equals("cenerfgwpoe", StringComparison.InvariantCultureIgnoreCase))
{
return new CenErfgwPoeEthernetSharable(ipId, Global.ControlSystem);
}
return null;
}
public static GatewayBase GetCenRfgwCresnetController(DeviceConfig dc)
{
var control = CommFactory.GetControlPropertiesConfig(dc);
var type = dc.Type;
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 CenRfgw", parentKey);
if (type.Equals("cenerfgwpoe", StringComparison.InvariantCultureIgnoreCase))
{
return new CenErfgwPoeCresnet(cresnetId, Global.ControlSystem);
}
if (type.Equals("cenrfgwex", StringComparison.InvariantCultureIgnoreCase))
{
return new CenRfgwExCresnet(cresnetId, Global.ControlSystem);
}
}
var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as ICresnetBridge;
if (cresnetBridge != null)
{
Debug.Console(0, "Device {0} is a valid cresnet master - creating new CenRfgw", parentKey);
if (type.Equals("cenerfgwpoe", StringComparison.InvariantCultureIgnoreCase))
{
return new CenErfgwPoeCresnet(cresnetId, cresnetBridge.Branches[branchId]);
}
if (type.Equals("cenrfgwex", StringComparison.InvariantCultureIgnoreCase))
{
return new CenRfgwExCresnet(cresnetId, cresnetBridge.Branches[branchId]);
}
}
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
return null;
}
public enum EExGatewayType
{
Ethernet,
EthernetShared,
Cresnet
}
#region Factory
public class CenRfgwControllerFactory : EssentialsDeviceFactory<CenRfgwController>
{
public CenRfgwControllerFactory()
{
TypeNames = new List<string> {"cenrfgwex", "cenerfgwpoe"};
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new CEN-GWEXER Device");
var props = JsonConvert.DeserializeObject<EssentialsRfGatewayConfig>(dc.Properties.ToString());
EExGatewayType gatewayType =
(EExGatewayType) Enum.Parse(typeof (EExGatewayType), props.GatewayType, true);
switch (gatewayType)
{
case (EExGatewayType.Ethernet):
return new CenRfgwController(dc.Key, dc.Name, GetNewIpRfGateway(dc));
case (EExGatewayType.EthernetShared):
return new CenRfgwController(dc.Key, dc.Name, GetNewSharedIpRfGateway(dc));
case (EExGatewayType.Cresnet):
return new CenRfgwController(dc.Key, GetCenRfgwCresnetController, dc);
}
return null;
}
}
#endregion
}
#endregion
}
}

View File

@@ -1,488 +1,488 @@
using System;
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using Crestron.SimplSharp.Reflection;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Core
{
public static class JoinMapHelper
{
/// <summary>
/// Attempts to get the serialized join map from config
/// </summary>
/// <param name="joinMapKey"></param>
/// <returns></returns>
public static string GetSerializedJoinMapForDevice(string joinMapKey)
{
if (string.IsNullOrEmpty(joinMapKey))
return null;
var joinMap = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
return joinMap;
}
/// <summary>
/// Attempts to get the serialized join map from config
/// </summary>
/// <param name="joinMapKey"></param>
/// <returns></returns>
public static string GetJoinMapForDevice(string joinMapKey)
{
return GetSerializedJoinMapForDevice(joinMapKey);
}
/// <summary>
/// Attempts to find a custom join map by key and returns it deserialized if found
/// </summary>
/// <param name="joinMapKey"></param>
/// <returns></returns>
public static Dictionary<string, JoinData> TryGetJoinMapAdvancedForDevice(string joinMapKey)
{
if (string.IsNullOrEmpty(joinMapKey))
return null;
var joinMapSerialzed = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
if (joinMapSerialzed == null) return null;
var joinMapData = JsonConvert.DeserializeObject<Dictionary<string, JoinData>>(joinMapSerialzed);
return joinMapData;
}
}
/// <summary>
/// Base class for join maps
/// </summary>
[Obsolete("This is being deprecated in favor of JoinMapBaseAdvanced")]
public abstract class JoinMapBase
{
/// <summary>
/// Modifies all the join numbers by adding the offset. This should never be called twice
/// </summary>
/// <param name="joinStart"></param>
public abstract void OffsetJoinNumbers(uint joinStart);
/// <summary>
/// The collection of joins and associated metadata
/// </summary>
public Dictionary<string, JoinMetadata> Joins = new Dictionary<string, JoinMetadata>();
/// <summary>
/// Prints the join information to console
/// </summary>
public void PrintJoinMapInfo()
{
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));
}
/// <summary>
/// Returns a sorted list by JoinNumber
/// </summary>
/// <param name="joins"></param>
/// <returns></returns>
List<KeyValuePair<string, JoinMetadata>> GetSortedJoins(Dictionary<string, JoinMetadata> joins)
{
var sortedJoins = joins.ToList();
sortedJoins.Sort((pair1, pair2) => pair1.Value.JoinNumber.CompareTo(pair2.Value.JoinNumber));
return sortedJoins;
}
void PrintJoinList(List<KeyValuePair<string, JoinMetadata>> joins)
{
foreach (var join in joins)
{
Debug.Console(0,
@"Join Number: {0} | Label: '{1}' | JoinSpan: '{2}' | Type: '{3}' | Capabilities: '{4}'",
join.Value.JoinNumber,
join.Value.Label,
join.Value.JoinSpan,
join.Value.JoinType.ToString(),
join.Value.JoinCapabilities.ToString());
}
}
/// <summary>
/// Returns the join number for the join with the specified key
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public uint GetJoinForKey(string key)
{
return Joins.ContainsKey(key) ? Joins[key].JoinNumber : 0;
}
/// <summary>
/// Returns the join span for the join with the specified key
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public uint GetJoinSpanForKey(string key)
{
return Joins.ContainsKey(key) ? Joins[key].JoinSpan : 0;
}
}
/// <summary>
/// Base class for join maps
/// </summary>
public abstract class JoinMapBaseAdvanced
{
protected uint JoinOffset;
/// <summary>
/// The collection of joins and associated metadata
/// </summary>
public Dictionary<string, JoinDataComplete> Joins { get; private set; }
protected JoinMapBaseAdvanced(uint joinStart)
{
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 = 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();
}
/// <summary>
/// Prints the join information to console
/// </summary>
public void PrintJoinMapInfo()
{
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));
}
/// <summary>
/// Returns a sorted list by JoinNumber
/// </summary>
/// <param name="joins"></param>
/// <returns></returns>
List<KeyValuePair<string, JoinDataComplete>> GetSortedJoins(Dictionary<string, JoinDataComplete> joins)
{
var sortedJoins = joins.ToList();
sortedJoins.Sort((pair1, pair2) => pair1.Value.JoinNumber.CompareTo(pair2.Value.JoinNumber));
return sortedJoins;
}
void PrintJoinList(List<KeyValuePair<string, JoinDataComplete>> joins)
{
foreach (var join in joins)
{
Debug.Console(0,
@"Join Number: {0} | JoinSpan: '{1}' | Label: '{2}' | Type: '{3}' | Capabilities: '{4}'",
join.Value.JoinNumber,
join.Value.JoinSpan,
join.Value.Metadata.Label,
join.Value.Metadata.JoinType.ToString(),
join.Value.Metadata.JoinCapabilities.ToString());
}
}
/// <summary>
/// Attempts to find the matching key for the custom join and if found overwrites the default JoinData with the custom
/// </summary>
/// <param name="joinData"></param>
public void SetCustomJoinData(Dictionary<string, JoinData> joinData)
{
foreach (var customJoinData in joinData)
{
var join = Joins[customJoinData.Key];
if (join != null)
{
join.SetCustomJoinData(customJoinData.Value);
}
else
{
Debug.Console(2, "No mathcing key found in join map for: '{0}'", customJoinData.Key);
}
}
PrintJoinMapInfo();
}
///// <summary>
///// Returns the join number for the join with the specified key
///// </summary>
///// <param name="key"></param>
///// <returns></returns>
//public uint GetJoinForKey(string key)
//{
// return Joins.ContainsKey(key) ? Joins[key].JoinNumber : 0;
//}
///// <summary>
///// Returns the join span for the join with the specified key
///// </summary>
///// <param name="key"></param>
///// <returns></returns>
//public uint GetJoinSpanForKey(string key)
//{
// return Joins.ContainsKey(key) ? Joins[key].JoinSpan : 0;
//}
}
/// <summary>
/// Read = Provides feedback to SIMPL
/// Write = Responds to sig values from SIMPL
/// </summary>
[Flags]
public enum eJoinCapabilities
{
None = 0,
ToSIMPL = 1,
FromSIMPL = 2,
ToFromSIMPL = ToSIMPL | FromSIMPL
}
[Flags]
public enum eJoinType
{
None = 0,
Digital = 1,
Analog = 2,
Serial = 4,
DigitalAnalog = Digital | Analog,
DigitalSerial = Digital | Serial,
AnalogSerial = Analog | Serial,
DigitalAnalogSerial = Digital | Analog | Serial
}
/// <summary>
/// Metadata describing the join
/// </summary>
public class JoinMetadata
using Crestron.SimplSharp.Reflection;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Core
{
public static class JoinMapHelper
{
private string _description;
/// <summary>
/// Join number (based on join offset value)
/// </summary>
[JsonProperty("joinNumber")]
[Obsolete]
public uint JoinNumber { get; set; }
/// <summary>
/// Join range span. If join indicates the start of a range of joins, this indicated the maximum number of joins in the range
/// </summary>
[Obsolete]
[JsonProperty("joinSpan")]
public uint JoinSpan { get; set; }
/// <summary>
/// A label for the join to better describe its usage
/// </summary>
[Obsolete("Use Description instead")]
[JsonProperty("label")]
public string Label { get { return _description; } set { _description = value; } }
/// <summary>
/// A description for the join to better describe its usage
/// </summary>
[JsonProperty("description")]
public string Description { get { return _description; } set { _description = value; } }
/// <summary>
/// Signal type(s)
/// </summary>
[JsonProperty("joinType")]
public eJoinType JoinType { get; set; }
/// <summary>
/// Indicates whether the join is read and/or write
/// </summary>
[JsonProperty("joinCapabilities")]
public eJoinCapabilities JoinCapabilities { get; set; }
/// <summary>
/// Indicates a set of valid values (particularly if this translates to an enum
/// </summary>
[JsonProperty("validValues")]
public string[] ValidValues { get; set; }
}
/// <summary>
/// Data describing the join. Can be
/// </summary>
public class JoinData
{
/// <summary>
/// Join number (based on join offset value)
/// </summary>
[JsonProperty("joinNumber")]
public uint JoinNumber { get; set; }
/// <summary>
/// Join range span. If join indicates the start of a range of joins, this indicated the maximum number of joins in the range
/// </summary>
[JsonProperty("joinSpan")]
public uint JoinSpan { get; set; }
}
/// <summary>
/// A class to aggregate the JoinData and JoinMetadata for a join
/// </summary>
public class JoinDataComplete
{
private uint _joinOffset;
private JoinData _data;
public JoinMetadata Metadata { get; set; }
public JoinDataComplete(JoinData data, JoinMetadata metadata)
{
_data = data;
Metadata = metadata;
}
/// <summary>
/// Sets the join offset value
/// </summary>
/// <param name="joinOffset"></param>
public void SetJoinOffset(uint joinOffset)
{
_joinOffset = joinOffset;
}
/// <summary>
/// The join number (including the offset)
/// </summary>
public uint JoinNumber
{
get { return _data.JoinNumber+ _joinOffset; }
set { _data.JoinNumber = value; }
}
public uint JoinSpan
{
get { return _data.JoinSpan; }
}
public void SetCustomJoinData(JoinData customJoinData)
{
_data = customJoinData;
}
public string GetNameAttribute(MemberInfo memberInfo)
{
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;
/// Attempts to get the serialized join map from config
/// </summary>
/// <param name="joinMapKey"></param>
/// <returns></returns>
public static string GetSerializedJoinMapForDevice(string joinMapKey)
{
if (string.IsNullOrEmpty(joinMapKey))
return null;
var joinMap = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
return joinMap;
}
/// <summary>
/// Attempts to get the serialized join map from config
/// </summary>
/// <param name="joinMapKey"></param>
/// <returns></returns>
public static string GetJoinMapForDevice(string joinMapKey)
{
return GetSerializedJoinMapForDevice(joinMapKey);
}
/// <summary>
/// Attempts to find a custom join map by key and returns it deserialized if found
/// </summary>
/// <param name="joinMapKey"></param>
/// <returns></returns>
public static Dictionary<string, JoinData> TryGetJoinMapAdvancedForDevice(string joinMapKey)
{
if (string.IsNullOrEmpty(joinMapKey))
return null;
var joinMapSerialzed = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
if (joinMapSerialzed == null) return null;
var joinMapData = JsonConvert.DeserializeObject<Dictionary<string, JoinData>>(joinMapSerialzed);
return joinMapData;
}
}
/// <summary>
/// Base class for join maps
/// </summary>
[Obsolete("This is being deprecated in favor of JoinMapBaseAdvanced")]
public abstract class JoinMapBase
{
/// <summary>
/// Modifies all the join numbers by adding the offset. This should never be called twice
/// </summary>
/// <param name="joinStart"></param>
public abstract void OffsetJoinNumbers(uint joinStart);
/// <summary>
/// The collection of joins and associated metadata
/// </summary>
public Dictionary<string, JoinMetadata> Joins = new Dictionary<string, JoinMetadata>();
/// <summary>
/// Prints the join information to console
/// </summary>
public void PrintJoinMapInfo()
{
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));
}
/// <summary>
/// Returns a sorted list by JoinNumber
/// </summary>
/// <param name="joins"></param>
/// <returns></returns>
List<KeyValuePair<string, JoinMetadata>> GetSortedJoins(Dictionary<string, JoinMetadata> joins)
{
var sortedJoins = joins.ToList();
sortedJoins.Sort((pair1, pair2) => pair1.Value.JoinNumber.CompareTo(pair2.Value.JoinNumber));
return sortedJoins;
}
void PrintJoinList(List<KeyValuePair<string, JoinMetadata>> joins)
{
foreach (var join in joins)
{
Debug.Console(0,
@"Join Number: {0} | Label: '{1}' | JoinSpan: '{2}' | Type: '{3}' | Capabilities: '{4}'",
join.Value.JoinNumber,
join.Value.Label,
join.Value.JoinSpan,
join.Value.JoinType.ToString(),
join.Value.JoinCapabilities.ToString());
}
}
/// <summary>
/// Returns the join number for the join with the specified key
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public uint GetJoinForKey(string key)
{
return Joins.ContainsKey(key) ? Joins[key].JoinNumber : 0;
}
/// <summary>
/// Returns the join span for the join with the specified key
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public uint GetJoinSpanForKey(string key)
{
return Joins.ContainsKey(key) ? Joins[key].JoinSpan : 0;
}
}
[AttributeUsage(AttributeTargets.All)]
public class JoinNameAttribute : CAttribute
{
private string _Name;
public JoinNameAttribute(string name)
{
Debug.Console(2, "Setting Attribute Name: {0}", name);
_Name = name;
}
public string Name
{
get { return _Name; }
}
/// <summary>
/// Base class for join maps
/// </summary>
public abstract class JoinMapBaseAdvanced
{
protected uint JoinOffset;
/// <summary>
/// The collection of joins and associated metadata
/// </summary>
public Dictionary<string, JoinDataComplete> Joins { get; private set; }
protected JoinMapBaseAdvanced(uint joinStart)
{
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 = 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();
}
/// <summary>
/// Prints the join information to console
/// </summary>
public void PrintJoinMapInfo()
{
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));
}
/// <summary>
/// Returns a sorted list by JoinNumber
/// </summary>
/// <param name="joins"></param>
/// <returns></returns>
List<KeyValuePair<string, JoinDataComplete>> GetSortedJoins(Dictionary<string, JoinDataComplete> joins)
{
var sortedJoins = joins.ToList();
sortedJoins.Sort((pair1, pair2) => pair1.Value.JoinNumber.CompareTo(pair2.Value.JoinNumber));
return sortedJoins;
}
void PrintJoinList(List<KeyValuePair<string, JoinDataComplete>> joins)
{
foreach (var join in joins)
{
Debug.Console(0,
@"Join Number: {0} | JoinSpan: '{1}' | Label: '{2}' | Type: '{3}' | Capabilities: '{4}'",
join.Value.JoinNumber,
join.Value.JoinSpan,
join.Value.Metadata.Label,
join.Value.Metadata.JoinType.ToString(),
join.Value.Metadata.JoinCapabilities.ToString());
}
}
/// <summary>
/// Attempts to find the matching key for the custom join and if found overwrites the default JoinData with the custom
/// </summary>
/// <param name="joinData"></param>
public void SetCustomJoinData(Dictionary<string, JoinData> joinData)
{
foreach (var customJoinData in joinData)
{
var join = Joins[customJoinData.Key];
if (join != null)
{
join.SetCustomJoinData(customJoinData.Value);
}
else
{
Debug.Console(2, "No mathcing key found in join map for: '{0}'", customJoinData.Key);
}
}
PrintJoinMapInfo();
}
///// <summary>
///// Returns the join number for the join with the specified key
///// </summary>
///// <param name="key"></param>
///// <returns></returns>
//public uint GetJoinForKey(string key)
//{
// return Joins.ContainsKey(key) ? Joins[key].JoinNumber : 0;
//}
///// <summary>
///// Returns the join span for the join with the specified key
///// </summary>
///// <param name="key"></param>
///// <returns></returns>
//public uint GetJoinSpanForKey(string key)
//{
// return Joins.ContainsKey(key) ? Joins[key].JoinSpan : 0;
//}
}
/// <summary>
/// Read = Provides feedback to SIMPL
/// Write = Responds to sig values from SIMPL
/// </summary>
[Flags]
public enum eJoinCapabilities
{
None = 0,
ToSIMPL = 1,
FromSIMPL = 2,
ToFromSIMPL = ToSIMPL | FromSIMPL
}
[Flags]
public enum eJoinType
{
None = 0,
Digital = 1,
Analog = 2,
Serial = 4,
DigitalAnalog = Digital | Analog,
DigitalSerial = Digital | Serial,
AnalogSerial = Analog | Serial,
DigitalAnalogSerial = Digital | Analog | Serial
}
/// <summary>
/// Metadata describing the join
/// </summary>
public class JoinMetadata
{
private string _description;
/// <summary>
/// Join number (based on join offset value)
/// </summary>
[JsonProperty("joinNumber")]
[Obsolete]
public uint JoinNumber { get; set; }
/// <summary>
/// Join range span. If join indicates the start of a range of joins, this indicated the maximum number of joins in the range
/// </summary>
[Obsolete]
[JsonProperty("joinSpan")]
public uint JoinSpan { get; set; }
/// <summary>
/// A label for the join to better describe its usage
/// </summary>
[Obsolete("Use Description instead")]
[JsonProperty("label")]
public string Label { get { return _description; } set { _description = value; } }
/// <summary>
/// A description for the join to better describe its usage
/// </summary>
[JsonProperty("description")]
public string Description { get { return _description; } set { _description = value; } }
/// <summary>
/// Signal type(s)
/// </summary>
[JsonProperty("joinType")]
public eJoinType JoinType { get; set; }
/// <summary>
/// Indicates whether the join is read and/or write
/// </summary>
[JsonProperty("joinCapabilities")]
public eJoinCapabilities JoinCapabilities { get; set; }
/// <summary>
/// Indicates a set of valid values (particularly if this translates to an enum
/// </summary>
[JsonProperty("validValues")]
public string[] ValidValues { get; set; }
}
/// <summary>
/// Data describing the join. Can be
/// </summary>
public class JoinData
{
/// <summary>
/// Join number (based on join offset value)
/// </summary>
[JsonProperty("joinNumber")]
public uint JoinNumber { get; set; }
/// <summary>
/// Join range span. If join indicates the start of a range of joins, this indicated the maximum number of joins in the range
/// </summary>
[JsonProperty("joinSpan")]
public uint JoinSpan { get; set; }
}
/// <summary>
/// A class to aggregate the JoinData and JoinMetadata for a join
/// </summary>
public class JoinDataComplete
{
private uint _joinOffset;
private JoinData _data;
public JoinMetadata Metadata { get; set; }
public JoinDataComplete(JoinData data, JoinMetadata metadata)
{
_data = data;
Metadata = metadata;
}
/// <summary>
/// Sets the join offset value
/// </summary>
/// <param name="joinOffset"></param>
public void SetJoinOffset(uint joinOffset)
{
_joinOffset = joinOffset;
}
/// <summary>
/// The join number (including the offset)
/// </summary>
public uint JoinNumber
{
get { return _data.JoinNumber+ _joinOffset; }
set { _data.JoinNumber = value; }
}
public uint JoinSpan
{
get { return _data.JoinSpan; }
}
public void SetCustomJoinData(JoinData customJoinData)
{
_data = customJoinData;
}
public string GetNameAttribute(MemberInfo memberInfo)
{
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.All)]
public class JoinNameAttribute : CAttribute
{
private string _Name;
public JoinNameAttribute(string name)
{
Debug.Console(2, "Setting Attribute Name: {0}", name);
_Name = name;
}
public string Name
{
get { return _Name; }
}
}
}

View File

@@ -0,0 +1,573 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.GeneralIO;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.Core
{
[Description("Wrapper class for CEN-ODT-C-POE")]
public class CenOdtOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider
{
public CenOdtCPoe OccSensor { get; private set; }
public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
public BoolFeedback GraceOccupancyDetectedFeedback { get; private set; }
public BoolFeedback RawOccupancyFeedback { get; private set; }
public BoolFeedback PirSensorEnabledFeedback { get; private set; }
public BoolFeedback LedFlashEnabledFeedback { get; private set; }
public BoolFeedback ShortTimeoutEnabledFeedback { get; private set; }
public IntFeedback PirSensitivityInVacantStateFeedback { get; private set; }
public IntFeedback PirSensitivityInOccupiedStateFeedback { get; private set; }
public IntFeedback CurrentTimeoutFeedback { get; private set; }
public IntFeedback RemoteTimeoutFeedback { get; private set; }
public IntFeedback InternalPhotoSensorValue { get; set; }
public IntFeedback ExternalPhotoSensorValue { get; set; }
public BoolFeedback OrWhenVacatedFeedback { get; private set; }
public BoolFeedback AndWhenVacatedFeedback { get; private set; }
public BoolFeedback UltrasonicAEnabledFeedback { get; private set; }
public BoolFeedback UltrasonicBEnabledFeedback { get; private set; }
public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; }
public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; }
public BoolFeedback RawOccupancyPirFeedback { get; private set; }
public BoolFeedback RawOccupancyUsFeedback { get; private set; }
// Debug properties
public bool InTestMode { get; private set; }
public bool TestRoomIsOccupiedFeedback { get; private set; }
public Func<bool> RoomIsOccupiedFeedbackFunc
{
get
{
return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue;
}
}
public CenOdtOccupancySensorBaseController(string key, string name, CenOdtCPoe sensor)
: base(key, name, sensor)
{
OccSensor = sensor;
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PassiveInfraredSensorEnabledFeedback.BoolValue);
LedFlashEnabledFeedback = new BoolFeedback(() => OccSensor.LedFlashEnabledFeedback.BoolValue);
ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue);
PirSensitivityInVacantStateFeedback = new IntFeedback(() => (int)OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback);
PirSensitivityInOccupiedStateFeedback = new IntFeedback(() => (int)OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback);
CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue);
RemoteTimeoutFeedback = new IntFeedback(() => OccSensor.RemoteTimeout.UShortValue);
GraceOccupancyDetectedFeedback = new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue);
RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyDetectedFeedback.BoolValue);
InternalPhotoSensorValue = new IntFeedback(() => OccSensor.InternalPhotoSensorValueFeedback.UShortValue);
//ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ex.UShortValue);
AndWhenVacatedFeedback = new BoolFeedback(() => OccSensor.AndWhenVacatedFeedback.BoolValue);
OrWhenVacatedFeedback = new BoolFeedback(() => OccSensor.OrWhenVacatedFeedback.BoolValue);
UltrasonicAEnabledFeedback = new BoolFeedback(() => OccSensor.UltrasonicSensorSideAEnabledFeedback.BoolValue);
UltrasonicBEnabledFeedback = new BoolFeedback(() => OccSensor.UltrasonicSensorSideBEnabledFeedback.BoolValue);
RawOccupancyPirFeedback = new BoolFeedback(() => OccSensor.RawOccupancyDetectedByPassiveInfraredSensorFeedback.BoolValue);
RawOccupancyUsFeedback = new BoolFeedback(() => OccSensor.RawOccupancyDetectedByUltrasonicSensorFeedback.BoolValue);
UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => (int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback);
UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => (int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback);
OccSensor.BaseEvent += new Crestron.SimplSharpPro.BaseEventHandler(OccSensor_BaseEvent);
OccSensor.CenOccupancySensorChange += new GenericEventHandler(OccSensor_CenOccupancySensorChange);
}
/// <summary>
/// Catches events for feedbacks on the base class. Any extending wrapper class should call this delegate after it checks for it's own event IDs.
/// </summary>
/// <param name="device"></param>
/// <param name="args"></param>
protected virtual void OccSensor_CenOccupancySensorChange(object device, GenericEventArgs args)
{
if (args.EventId == GlsOccupancySensorBase.PirEnabledFeedbackEventId)
PirSensorEnabledFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId)
LedFlashEnabledFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId)
ShortTimeoutEnabledFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId)
PirSensitivityInOccupiedStateFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId)
PirSensitivityInVacantStateFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId)
RawOccupancyPirFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId)
RawOccupancyUsFeedback.FireUpdate();
}
protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args)
{
Debug.Console(2, this, "PoEOccupancySensorChange EventId: {0}", args.EventId);
if (args.EventId == Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId
|| args.EventId == Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId)
{
Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue);
RoomIsOccupiedFeedback.FireUpdate();
}
else if (args.EventId == GlsOccupancySensorBase.TimeoutFeedbackEventId)
CurrentTimeoutFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.TimeoutLocalFeedbackEventId)
RemoteTimeoutFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId)
GraceOccupancyDetectedFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.RawOccupancyFeedbackEventId)
RawOccupancyFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId)
InternalPhotoSensorValue.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId)
ExternalPhotoSensorValue.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId)
AndWhenVacatedFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.OrWhenVacatedFeedbackEventId)
OrWhenVacatedFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsAEnabledFeedbackEventId)
UltrasonicAEnabledFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsBEnabledFeedbackEventId)
UltrasonicBEnabledFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId)
UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId)
UltrasonicSensitivityInVacantStateFeedback.FireUpdate();
}
public void SetTestMode(bool mode)
{
InTestMode = mode;
Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode);
}
public void SetTestOccupiedState(bool state)
{
if (!InTestMode)
Debug.Console(1, "Mock mode not enabled");
else
{
TestRoomIsOccupiedFeedback = state;
RoomIsOccupiedFeedback.FireUpdate();
}
}
/// <summary>
/// Enables or disables the PIR sensor
/// </summary>
/// <param name="state"></param>
public void SetPirEnable(bool state)
{
if (state)
{
OccSensor.EnablePassiveInfraredSensor();
}
else
{
OccSensor.DisablePassiveInfraredSensor();
}
}
/// <summary>
/// Enables or disables the LED Flash
/// </summary>
/// <param name="state"></param>
public void SetLedFlashEnable(bool state)
{
if (state)
{
OccSensor.EnableLedFlash();
}
else
{
OccSensor.DisableLedFlash();
}
}
/// <summary>
/// Enables or disables short timeout based on state
/// </summary>
/// <param name="state"></param>
public void SetShortTimeoutState(bool state)
{
if (state)
{
OccSensor.EnableShortTimeout();
}
else
{
OccSensor.DisableShortTimeout();
}
}
public void IncrementPirSensitivityInOccupiedState(bool pressRelease)
{
if ((int)OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback != 3)
{
OccSensor.PassiveInfraredSensorSensitivityInOccupiedState = OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback + 1;
}
}
public void DecrementPirSensitivityInOccupiedState(bool pressRelease)
{
if ((int)OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback != 0)
{
OccSensor.PassiveInfraredSensorSensitivityInOccupiedState = OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback - 1;
}
}
public void IncrementPirSensitivityInVacantState(bool pressRelease)
{
if ((int)OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback != 3)
{
OccSensor.PassiveInfraredSensorSensitivityInVacantState = OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback + 1;
}
}
public void DecrementPirSensitivityInVacantState(bool pressRelease)
{
if ((int)OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback != 0)
{
OccSensor.PassiveInfraredSensorSensitivityInVacantState = OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback - 1;
}
}
public void IncrementUsSensitivityInOccupiedState(bool pressRelease)
{
if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback < 3)
{
OccSensor.UltrasonicSensorSensitivityInOccupiedState = OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback + 1;
}
else if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback > 4)
{
OccSensor.UltrasonicSensorSensitivityInOccupiedState = OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback - 1;
}
else if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback == 4)
{
OccSensor.UltrasonicSensorSensitivityInOccupiedState = 0;
}
}
public void DecrementUsSensitivityInOccupiedState(bool pressRelease)
{
if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback > 0
&& (int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback < 4)
{
OccSensor.UltrasonicSensorSensitivityInOccupiedState = OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback - 1;
}
else if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback > 3
&& (int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback < 7)
{
OccSensor.UltrasonicSensorSensitivityInOccupiedState = OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback + 1;
}
}
public void IncrementUsSensitivityInVacantState(bool pressRelease)
{
if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback < 3)
{
OccSensor.UltrasonicSensorSensitivityInVacantState = OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback + 1;
}
else if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback > 4)
{
OccSensor.UltrasonicSensorSensitivityInVacantState = OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback - 1;
}
else if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback == 4)
{
OccSensor.UltrasonicSensorSensitivityInVacantState = 0;
}
}
public void DecrementUsSensitivityInVacantState(bool pressRelease)
{
if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback > 0
&& (int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback < 4)
{
OccSensor.UltrasonicSensorSensitivityInVacantState = OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback - 1;
}
else if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback > 3
&& (int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback < 7)
{
OccSensor.UltrasonicSensorSensitivityInVacantState = OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback + 1;
}
}
public void ForceOccupied()
{
OccSensor.ForceOccupied();
}
public void ForceVacant()
{
OccSensor.ForceVacant();
}
public void EnableRawStates(bool state)
{
if (state)
{
OccSensor.EnableRawStates();
}
else
OccSensor.DisableRawStates();
}
public void SetRemoteTimeout(ushort time)
{
OccSensor.RemoteTimeout.UShortValue = time;
}
public void SetInternalPhotoSensorMinChange(ushort value)
{
OccSensor.InternalPhotoSensorMinimumChange.UShortValue = value;
}
/// <summary>
/// Sets the OrWhenVacated state
/// </summary>
/// <param name="state"></param>
public void SetOrWhenVacatedState(bool state)
{
if (state)
{
OccSensor.OrWhenVacated();
}
}
/// <summary>
/// Sets the AndWhenVacated state
/// </summary>
/// <param name="state"></param>
public void SetAndWhenVacatedState(bool state)
{
if (state)
{
OccSensor.AndWhenVacated();
}
}
/// <summary>
/// Enables or disables the Ultrasonic A sensor
/// </summary>
/// <param name="state"></param>
public void SetUsAEnable(bool state)
{
if (state)
{
OccSensor.EnableUltrasonicSensorSideA();
}
else
{
OccSensor.DisableUltrasonicSensorSideA();
}
}
/// <summary>
/// Enables or disables the Ultrasonic B sensor
/// </summary>
/// <param name="state"></param>
public void SetUsBEnable(bool state)
{
if (state)
{
OccSensor.EnableUltrasonicSensorSideB();
}
else
{
OccSensor.DisableUltrasonicSensorSideB();
}
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge);
}
protected void LinkOccSensorToApi(CenOdtOccupancySensorBaseController occController,
BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
CenOdtOccupancySensorBaseJoinMap joinMap = new CenOdtOccupancySensorBaseJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<CenOdtOccupancySensorBaseJoinMap>(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.");
}
Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.Online.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
trilist.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler((d, args) =>
{
if (args.DeviceOnLine)
{
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
}
}
);
// Occupied status
trilist.SetSigTrueAction(joinMap.ForceOccupied.JoinNumber, new Action(() => occController.ForceOccupied()));
trilist.SetSigTrueAction(joinMap.ForceVacant.JoinNumber, new Action(() => occController.ForceVacant()));
occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]);
occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]);
occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback.JoinNumber]);
trilist.SetBoolSigAction(joinMap.EnableRawStates.JoinNumber, new Action<bool>((b) => occController.EnableRawStates(b)));
// Timouts
trilist.SetUShortSigAction(joinMap.Timeout.JoinNumber, new Action<ushort>((u) => occController.SetRemoteTimeout(u)));
occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout.JoinNumber]);
occController.RemoteTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback.JoinNumber]);
// LED Flash
trilist.SetSigTrueAction(joinMap.EnableLedFlash.JoinNumber, new Action(() => occController.SetLedFlashEnable(true)));
trilist.SetSigTrueAction(joinMap.DisableLedFlash.JoinNumber, new Action(() => occController.SetLedFlashEnable(false)));
occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash.JoinNumber]);
// Short Timeout
trilist.SetSigTrueAction(joinMap.EnableShortTimeout.JoinNumber, new Action(() => occController.SetShortTimeoutState(true)));
trilist.SetSigTrueAction(joinMap.DisableShortTimeout.JoinNumber, new Action(() => occController.SetShortTimeoutState(false)));
occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout.JoinNumber]);
// PIR Sensor
trilist.SetSigTrueAction(joinMap.EnablePir.JoinNumber, new Action(() => occController.SetPirEnable(true)));
trilist.SetSigTrueAction(joinMap.DisablePir.JoinNumber, new Action(() => occController.SetPirEnable(false)));
occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir.JoinNumber]);
// PIR Sensitivity in Occupied State
trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState.JoinNumber, new Action<bool>((b) => occController.IncrementPirSensitivityInOccupiedState(b)));
trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState.JoinNumber, new Action<bool>((b) => occController.DecrementPirSensitivityInOccupiedState(b)));
occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInOccupiedState.JoinNumber]);
// PIR Sensitivity in Vacant State
trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState.JoinNumber, new Action<bool>((b) => occController.IncrementPirSensitivityInVacantState(b)));
trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState.JoinNumber, new Action<bool>((b) => occController.DecrementPirSensitivityInVacantState(b)));
occController.PirSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInVacantState.JoinNumber]);
// OR When Vacated
trilist.SetBoolSigAction(joinMap.OrWhenVacated.JoinNumber, new Action<bool>((b) => occController.SetOrWhenVacatedState(b)));
occController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated.JoinNumber]);
// AND When Vacated
trilist.SetBoolSigAction(joinMap.AndWhenVacated.JoinNumber, new Action<bool>((b) => occController.SetAndWhenVacatedState(b)));
occController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated.JoinNumber]);
// Ultrasonic A Sensor
trilist.SetSigTrueAction(joinMap.EnableUsA.JoinNumber, new Action(() => occController.SetUsAEnable(true)));
trilist.SetSigTrueAction(joinMap.DisableUsA.JoinNumber, new Action(() => occController.SetUsAEnable(false)));
occController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA.JoinNumber]);
// Ultrasonic B Sensor
trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, new Action(() => occController.SetUsBEnable(true)));
trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, new Action(() => occController.SetUsBEnable(false)));
occController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]);
// US Sensitivity in Occupied State
trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber, new Action<bool>((b) => occController.IncrementUsSensitivityInOccupiedState(b)));
trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState.JoinNumber, new Action<bool>((b) => occController.DecrementUsSensitivityInOccupiedState(b)));
occController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInOccupiedState.JoinNumber]);
// US Sensitivity in Vacant State
trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState.JoinNumber, new Action<bool>((b) => occController.IncrementUsSensitivityInVacantState(b)));
trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState.JoinNumber, new Action<bool>((b) => occController.DecrementUsSensitivityInVacantState(b)));
occController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInVacantState.JoinNumber]);
//Sensor Raw States
occController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]);
occController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]);
}
public class CenOdtOccupancySensorBaseControllerFactory : EssentialsDeviceFactory<CenOdtOccupancySensorBaseController>
{
public CenOdtOccupancySensorBaseControllerFactory()
{
TypeNames = new List<string>() { "cenodtcpoe", "cenodtocc" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device");
var typeName = dc.Type.ToLower();
var key = dc.Key;
var name = dc.Name;
var comm = CommFactory.GetControlPropertiesConfig(dc);
var occSensor = new CenOdtCPoe(comm.IpIdInt, Global.ControlSystem);
if (occSensor == null)
{
Debug.Console(0, "ERROR: Unable to create Occupancy Sensor Device. Key: '{0}'", key);
return null;
}
return new CenOdtOccupancySensorBaseController(key, name, occSensor);
}
}
}
}

View File

@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Occupancy
{
public class EssentialsGlsOccupancySensorBaseController : CrestronGenericBaseDevice, IOccupancyStatusProvider
{
public GlsOccupancySensorBase OccSensor { get; private set; }
public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
<<<<<<< HEAD
/// <summary>
/// Set by debugging functions
/// </summary>
public bool InMockMode { get; private set; }
public bool MockRoomIsOccupiedFeedback { get; private set; }
=======
// Debug properties
public bool InTestMode { get; private set; }
public bool TestRoomIsOccupiedFeedback { get; private set; }
>>>>>>> origin/feature/ecs-342-neil
public Func<bool> RoomIsOccupiedFeedbackFunc
{
get
{
<<<<<<< HEAD
return () => InMockMode ? MockRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue;
=======
return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue;
>>>>>>> origin/feature/ecs-342-neil
}
}
public EssentialsGlsOccupancySensorBaseController(string key, string name, GlsOccupancySensorBase sensor, GlsOccupancySensorConfigurationProperties props)
: base(key, name, sensor)
{
OccSensor = sensor;
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
OccSensor.GlsOccupancySensorChange += new GlsOccupancySensorChangeEventHandler(sensor_GlsOccupancySensorChange);
}
void sensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
{
RoomIsOccupiedFeedback.FireUpdate();
}
public void SetTestMode(bool mode)
{
InTestMode = mode;
Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode);
}
public void SetTestOccupiedState(bool state)
{
if (!InTestMode)
Debug.Console(1, "Mock mode not enabled");
else
{
TestRoomIsOccupiedFeedback = state;
RoomIsOccupiedFeedback.FireUpdate();
}
}
}
/// <summary>
///
/// </summary>
public class GlsOccupancySensorConfigurationProperties
{
public string CresnetId { get; set; }
public string Model { get; set; }
}
}

View File

@@ -0,0 +1,460 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.GeneralIO;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.Core
{
[Description("Wrapper class for Single Technology GLS Occupancy Sensors")]
public class GlsOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider
{
public GlsOccupancySensorBase OccSensor { get; private set; }
public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
public BoolFeedback GraceOccupancyDetectedFeedback { get; private set; }
public BoolFeedback RawOccupancyFeedback { get; private set; }
public BoolFeedback PirSensorEnabledFeedback { get; private set; }
public BoolFeedback LedFlashEnabledFeedback { get; private set; }
public BoolFeedback ShortTimeoutEnabledFeedback { get; private set; }
public IntFeedback PirSensitivityInVacantStateFeedback { get; private set; }
public IntFeedback PirSensitivityInOccupiedStateFeedback { get; private set; }
public IntFeedback CurrentTimeoutFeedback { get; private set; }
public IntFeedback LocalTimoutFeedback { get; private set; }
public IntFeedback InternalPhotoSensorValue { get; set; }
public IntFeedback ExternalPhotoSensorValue { get; set; }
// Debug properties
public bool InTestMode { get; private set; }
public bool TestRoomIsOccupiedFeedback { get; private set; }
public Func<bool> RoomIsOccupiedFeedbackFunc
{
get
{
return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue;
}
}
public GlsOccupancySensorBaseController(string key, Func<DeviceConfig, GlsOccupancySensorBase> preActivationFunc,
DeviceConfig config)
: base(key, config.Name)
{
AddPreActivationAction(() =>
{
OccSensor = preActivationFunc(config);
RegisterCrestronGenericBase(OccSensor);
RegisterGlsOdtSensorBaseController(OccSensor);
});
}
public GlsOccupancySensorBaseController(string key, string name) : base(key, name) {}
protected void RegisterGlsOdtSensorBaseController(GlsOccupancySensorBase occSensor)
{
OccSensor = occSensor;
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PirEnabledFeedback.BoolValue);
LedFlashEnabledFeedback = new BoolFeedback(() => OccSensor.LedFlashEnabledFeedback.BoolValue);
ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue);
PirSensitivityInVacantStateFeedback =
new IntFeedback(() => OccSensor.PirSensitivityInVacantStateFeedback.UShortValue);
PirSensitivityInOccupiedStateFeedback =
new IntFeedback(() => OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue);
CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue);
LocalTimoutFeedback = new IntFeedback(() => OccSensor.LocalTimeoutFeedback.UShortValue);
GraceOccupancyDetectedFeedback =
new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue);
RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyFeedback.BoolValue);
InternalPhotoSensorValue = new IntFeedback(() => OccSensor.InternalPhotoSensorValueFeedback.UShortValue);
ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ExternalPhotoSensorValueFeedback.UShortValue);
OccSensor.BaseEvent += OccSensor_BaseEvent;
OccSensor.GlsOccupancySensorChange += OccSensor_GlsOccupancySensorChange;
}
/// <summary>
/// Catches events for feedbacks on the base class. Any extending wrapper class should call this delegate after it checks for it's own event IDs.
/// </summary>
/// <param name="device"></param>
/// <param name="args"></param>
protected virtual void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
{
switch (args.EventId)
{
case GlsOccupancySensorBase.PirEnabledFeedbackEventId:
PirSensorEnabledFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId:
LedFlashEnabledFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId:
ShortTimeoutEnabledFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId:
PirSensitivityInOccupiedStateFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId:
PirSensitivityInVacantStateFeedback.FireUpdate();
break;
}
}
protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args)
{
Debug.Console(2, this, "GlsOccupancySensorChange EventId: {0}", args.EventId);
switch (args.EventId)
{
case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId:
case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId:
Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue);
RoomIsOccupiedFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.TimeoutFeedbackEventId:
CurrentTimeoutFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.TimeoutLocalFeedbackEventId:
LocalTimoutFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId:
GraceOccupancyDetectedFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.RawOccupancyFeedbackEventId:
RawOccupancyFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId:
InternalPhotoSensorValue.FireUpdate();
break;
case GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId:
ExternalPhotoSensorValue.FireUpdate();
break;
}
}
public void SetTestMode(bool mode)
{
InTestMode = mode;
Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode);
}
public void SetTestOccupiedState(bool state)
{
if (!InTestMode)
Debug.Console(1, "Mock mode not enabled");
else
{
TestRoomIsOccupiedFeedback = state;
RoomIsOccupiedFeedback.FireUpdate();
}
}
/// <summary>
/// Enables or disables the PIR sensor
/// </summary>
/// <param name="state"></param>
public void SetPirEnable(bool state)
{
if (state)
{
OccSensor.EnablePir.BoolValue = state;
OccSensor.DisablePir.BoolValue = !state;
}
else
{
OccSensor.EnablePir.BoolValue = state;
OccSensor.DisablePir.BoolValue = !state;
}
}
/// <summary>
/// Enables or disables the LED Flash
/// </summary>
/// <param name="state"></param>
public void SetLedFlashEnable(bool state)
{
if (state)
{
OccSensor.EnableLedFlash.BoolValue = state;
OccSensor.DisableLedFlash.BoolValue = !state;
}
else
{
OccSensor.EnableLedFlash.BoolValue = state;
OccSensor.DisableLedFlash.BoolValue = !state;
}
}
/// <summary>
/// Enables or disables short timeout based on state
/// </summary>
/// <param name="state"></param>
public void SetShortTimeoutState(bool state)
{
if (state)
{
OccSensor.EnableShortTimeout.BoolValue = state;
OccSensor.DisableShortTimeout.BoolValue = !state;
}
else
{
OccSensor.EnableShortTimeout.BoolValue = state;
OccSensor.DisableShortTimeout.BoolValue = !state;
}
}
public void IncrementPirSensitivityInOccupiedState(bool pressRelease)
{
OccSensor.IncrementPirSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void DecrementPirSensitivityInOccupiedState(bool pressRelease)
{
OccSensor.DecrementPirSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void IncrementPirSensitivityInVacantState(bool pressRelease)
{
OccSensor.IncrementPirSensitivityInVacantState.BoolValue = pressRelease;
}
public void DecrementPirSensitivityInVacantState(bool pressRelease)
{
OccSensor.DecrementPirSensitivityInVacantState.BoolValue = pressRelease;
}
public void ForceOccupied()
{
OccSensor.ForceOccupied.BoolValue = true;
}
public void ForceVacant()
{
OccSensor.ForceVacant.BoolValue = true;
}
public void EnableRawStates(bool state)
{
OccSensor.EnableRawStates.BoolValue = state;
}
public void SetRemoteTimeout(ushort time)
{
OccSensor.RemoteTimeout.UShortValue = time;
}
public void SetInternalPhotoSensorMinChange(ushort value)
{
OccSensor.InternalPhotoSensorMinimumChange.UShortValue = value;
}
public void SetExternalPhotoSensorMinChange(ushort value)
{
OccSensor.ExternalPhotoSensorMinimumChange.UShortValue = value;
}
protected void LinkOccSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist,
uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new GlsOccupancySensorBaseJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<GlsOccupancySensorBaseJoinMap>(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.");
}
Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
#region Single and Dual Sensor Stuff
occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
trilist.OnlineStatusChange += (d, args) =>
{
if (args.DeviceOnLine)
{
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
}
};
// Occupied status
trilist.SetSigTrueAction(joinMap.ForceOccupied.JoinNumber, occController.ForceOccupied);
trilist.SetSigTrueAction(joinMap.ForceVacant.JoinNumber, occController.ForceVacant);
occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]);
occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]);
occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback.JoinNumber]);
trilist.SetBoolSigAction(joinMap.EnableRawStates.JoinNumber, occController.EnableRawStates);
// Timouts
trilist.SetUShortSigAction(joinMap.Timeout.JoinNumber, occController.SetRemoteTimeout);
occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout.JoinNumber]);
occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback.JoinNumber]);
// LED Flash
trilist.SetSigTrueAction(joinMap.EnableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(true));
trilist.SetSigTrueAction(joinMap.DisableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(false));
occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash.JoinNumber]);
// Short Timeout
trilist.SetSigTrueAction(joinMap.EnableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(true));
trilist.SetSigTrueAction(joinMap.DisableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(false));
occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout.JoinNumber]);
// PIR Sensor
trilist.SetSigTrueAction(joinMap.EnablePir.JoinNumber, () => occController.SetPirEnable(true));
trilist.SetSigTrueAction(joinMap.DisablePir.JoinNumber, () => occController.SetPirEnable(false));
occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir.JoinNumber]);
// PIR Sensitivity in Occupied State
trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState.JoinNumber, occController.IncrementPirSensitivityInOccupiedState);
trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState.JoinNumber, occController.DecrementPirSensitivityInOccupiedState);
occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInOccupiedState.JoinNumber]);
// PIR Sensitivity in Vacant State
trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState.JoinNumber, occController.IncrementPirSensitivityInVacantState);
trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState.JoinNumber, occController.DecrementPirSensitivityInVacantState);
occController.PirSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInVacantState.JoinNumber]);
#endregion
#region Dual Technology Sensor Stuff
var odtOccController = occController as GlsOdtOccupancySensorController;
if (odtOccController == null) return;
// OR When Vacated
trilist.SetBoolSigAction(joinMap.OrWhenVacated.JoinNumber, odtOccController.SetOrWhenVacatedState);
odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated.JoinNumber]);
// AND When Vacated
trilist.SetBoolSigAction(joinMap.AndWhenVacated.JoinNumber, odtOccController.SetAndWhenVacatedState);
odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated.JoinNumber]);
// Ultrasonic A Sensor
trilist.SetSigTrueAction(joinMap.EnableUsA.JoinNumber, () => odtOccController.SetUsAEnable(true));
trilist.SetSigTrueAction(joinMap.DisableUsA.JoinNumber, () => odtOccController.SetUsAEnable(false));
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA.JoinNumber]);
// Ultrasonic B Sensor
trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, () => odtOccController.SetUsBEnable(true));
trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, () => odtOccController.SetUsBEnable(false));
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]);
// US Sensitivity in Occupied State
trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber, odtOccController.IncrementUsSensitivityInOccupiedState);
trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState.JoinNumber, odtOccController.DecrementUsSensitivityInOccupiedState);
odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInOccupiedState.JoinNumber]);
// US Sensitivity in Vacant State
trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState.JoinNumber, odtOccController.IncrementUsSensitivityInVacantState);
trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState.JoinNumber, odtOccController.DecrementUsSensitivityInVacantState);
odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInVacantState.JoinNumber]);
//Sensor Raw States
odtOccController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]);
odtOccController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]);
#endregion
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge);
}
#region PreActivation
private static GlsOirCCn GetGlsOirCCn(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 GlsOirCCn", parentKey);
return new GlsOirCCn(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 GlsOirCCn", parentKey);
return new GlsOirCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]);
}
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
return null;
}
#endregion
public class GlsOccupancySensorBaseControllerFactory : EssentialsDeviceFactory<GlsOccupancySensorBaseController>
{
public GlsOccupancySensorBaseControllerFactory()
{
TypeNames = new List<string>() { "glsoirccn" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device");
return new GlsOccupancySensorBaseController(dc.Key, GetGlsOirCCn, dc);
}
}
}
}

View File

@@ -0,0 +1,219 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.Core
{
[Description("Wrapper class for Dual Technology GLS Occupancy Sensors")]
public class GlsOdtOccupancySensorController : GlsOccupancySensorBaseController
{
public new GlsOdtCCn OccSensor { get; private set; }
public BoolFeedback OrWhenVacatedFeedback { get; private set; }
public BoolFeedback AndWhenVacatedFeedback { get; private set; }
public BoolFeedback UltrasonicAEnabledFeedback { get; private set; }
public BoolFeedback UltrasonicBEnabledFeedback { get; private set; }
public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; }
public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; }
public BoolFeedback RawOccupancyPirFeedback { get; private set; }
public BoolFeedback RawOccupancyUsFeedback { get; private set; }
public GlsOdtOccupancySensorController(string key, Func<DeviceConfig, GlsOdtCCn> preActivationFunc,
DeviceConfig config)
: base(key, config.Name)
{
AddPreActivationAction(() =>
{
OccSensor = preActivationFunc(config);
RegisterCrestronGenericBase(OccSensor);
RegisterGlsOdtSensorBaseController(OccSensor);
AndWhenVacatedFeedback = new BoolFeedback(() => OccSensor.AndWhenVacatedFeedback.BoolValue);
OrWhenVacatedFeedback = new BoolFeedback(() => OccSensor.OrWhenVacatedFeedback.BoolValue);
UltrasonicAEnabledFeedback = new BoolFeedback(() => OccSensor.UsAEnabledFeedback.BoolValue);
UltrasonicBEnabledFeedback = new BoolFeedback(() => OccSensor.UsBEnabledFeedback.BoolValue);
RawOccupancyPirFeedback = new BoolFeedback(() => OccSensor.RawOccupancyPirFeedback.BoolValue);
RawOccupancyUsFeedback = new BoolFeedback(() => OccSensor.RawOccupancyUsFeedback.BoolValue);
UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInVacantStateFeedback.UShortValue);
UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue);
});
}
/// <summary>
/// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class.
/// Then calls the base delegate method to ensure any common event IDs are captured.
/// </summary>
/// <param name="device"></param>
/// <param name="args"></param>
protected override void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
{
if (args.EventId == GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId)
AndWhenVacatedFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.OrWhenVacatedFeedbackEventId)
OrWhenVacatedFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsAEnabledFeedbackEventId)
UltrasonicAEnabledFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsBEnabledFeedbackEventId)
UltrasonicBEnabledFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId)
UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId)
UltrasonicSensitivityInVacantStateFeedback.FireUpdate();
base.OccSensor_GlsOccupancySensorChange(device, args);
}
/// <summary>
/// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class.
/// Then calls the base delegate method to ensure any common event IDs are captured.
/// </summary>
/// <param name="device"></param>
/// <param name="args"></param>
protected override void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args)
{
if (args.EventId == GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId)
RawOccupancyPirFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId)
RawOccupancyUsFeedback.FireUpdate();
base.OccSensor_BaseEvent(device, args);
}
/// <summary>
/// Sets the OrWhenVacated state
/// </summary>
/// <param name="state"></param>
public void SetOrWhenVacatedState(bool state)
{
OccSensor.OrWhenVacated.BoolValue = state;
}
/// <summary>
/// Sets the AndWhenVacated state
/// </summary>
/// <param name="state"></param>
public void SetAndWhenVacatedState(bool state)
{
OccSensor.AndWhenVacated.BoolValue = state;
}
/// <summary>
/// Enables or disables the Ultrasonic A sensor
/// </summary>
/// <param name="state"></param>
public void SetUsAEnable(bool state)
{
OccSensor.EnableUsA.BoolValue = state;
OccSensor.DisableUsA.BoolValue = !state;
}
/// <summary>
/// Enables or disables the Ultrasonic B sensor
/// </summary>
/// <param name="state"></param>
public void SetUsBEnable(bool state)
{
OccSensor.EnableUsB.BoolValue = state;
OccSensor.DisableUsB.BoolValue = !state;
}
public void IncrementUsSensitivityInOccupiedState(bool pressRelease)
{
OccSensor.IncrementUsSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void DecrementUsSensitivityInOccupiedState(bool pressRelease)
{
OccSensor.DecrementUsSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void IncrementUsSensitivityInVacantState(bool pressRelease)
{
OccSensor.IncrementUsSensitivityInVacantState.BoolValue = pressRelease;
}
public void DecrementUsSensitivityInVacantState(bool pressRelease)
{
OccSensor.DecrementUsSensitivityInVacantState.BoolValue = pressRelease;
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge);
}
#region PreActivation
private static GlsOdtCCn GetGlsOdtCCn(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 GlsOdtCCn", parentKey);
return new GlsOdtCCn(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 GlsOdtCCn", parentKey);
return new GlsOdtCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]);
}
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
return null;
}
#endregion
public class GlsOdtOccupancySensorControllerFactory : EssentialsDeviceFactory<GlsOdtOccupancySensorController>
{
public GlsOdtOccupancySensorControllerFactory()
{
TypeNames = new List<string>() { "glsodtccn" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device");
return new GlsOdtOccupancySensorController(dc.Key, GetGlsOdtCCn, dc);
}
}
}
}

View File

@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Aggregates the RoomIsOccupied feedbacks of one or more IOccupancyStatusProvider objects
/// </summary>
public class IOccupancyStatusProviderAggregator : Device, IOccupancyStatusProvider
{
/// <summary>
/// Aggregated feedback of all linked IOccupancyStatusProvider devices
/// </summary>
public BoolFeedback RoomIsOccupiedFeedback
{
get
{
return AggregatedOccupancyStatus.Output;
}
}
private BoolFeedbackOr AggregatedOccupancyStatus;
public IOccupancyStatusProviderAggregator(string key, string name)
: base(key, name)
{
AggregatedOccupancyStatus = new BoolFeedbackOr();
}
/// <summary>
/// Adds an IOccupancyStatusProvider device
/// </summary>
/// <param name="statusProvider"></param>
public void AddOccupancyStatusProvider(IOccupancyStatusProvider statusProvider)
{
AggregatedOccupancyStatus.AddOutputIn(statusProvider.RoomIsOccupiedFeedback);
}
}
}

View File

@@ -0,0 +1,280 @@
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.GeneralIO;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash_Essentials_Core.Bridges.JoinMaps;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.Gateways;
using Newtonsoft.Json;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash_Essentials_Core;
namespace PepperDash.Essentials.Core
{
[Description("Wrapper class for GLS Cresnet Partition Sensor")]
public class GlsPartitionSensorController : CrestronGenericBridgeableBaseDevice
{
private GlsPartCn _partitionSensor;
public StringFeedback NameFeedback { get; private set; }
public BoolFeedback EnableFeedback { get; private set; }
public BoolFeedback PartitionSensedFeedback { get; private set; }
public BoolFeedback PartitionNotSensedFeedback { get; private set; }
public IntFeedback SensitivityFeedback { get; private set; }
public bool InTestMode { get; private set; }
public bool TestEnableFeedback { get; private set; }
public bool TestPartitionSensedFeedback { get; private set; }
public int TestSensitivityFeedback { get; private set; }
public GlsPartitionSensorController(string key, Func<DeviceConfig, GlsPartCn> preActivationFunc, DeviceConfig config)
: base(key, config.Name)
{
AddPreActivationAction(() =>
{
_partitionSensor = preActivationFunc(config);
RegisterCrestronGenericBase(_partitionSensor);
NameFeedback = new StringFeedback(() => Name);
EnableFeedback = new BoolFeedback(() => _partitionSensor.EnableFeedback.BoolValue);
PartitionSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionSensedFeedback.BoolValue);
PartitionNotSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionNotSensedFeedback.BoolValue);
SensitivityFeedback = new IntFeedback(() => _partitionSensor.SensitivityFeedback.UShortValue);
if (_partitionSensor != null) _partitionSensor.BaseEvent += PartitionSensor_BaseEvent;
});
}
private void PartitionSensor_BaseEvent(GenericBase device, BaseEventArgs args)
{
Debug.Console(2, this, "EventId: {0}, Index: {1}", args.EventId, args.Index);
switch (args.EventId)
{
case (GlsPartCn.EnableFeedbackEventId):
{
EnableFeedback.FireUpdate();
break;
}
case (GlsPartCn.PartitionSensedFeedbackEventId):
{
PartitionSensedFeedback.FireUpdate();
break;
}
case (GlsPartCn.PartitionNotSensedFeedbackEventId):
{
PartitionNotSensedFeedback.FireUpdate();
break;
}
case (GlsPartCn.SensitivityFeedbackEventId):
{
SensitivityFeedback.FireUpdate();
break;
}
default:
{
Debug.Console(2, this, "Unhandled args.EventId: {0}", args.EventId);
break;
}
}
}
public void SetTestMode(bool mode)
{
InTestMode = mode;
Debug.Console(1, this, "InTestMode: {0}", InTestMode.ToString());
}
public void SetTestEnableState(bool state)
{
if (InTestMode)
{
TestEnableFeedback = state;
Debug.Console(1, this, "TestEnableFeedback: {0}", TestEnableFeedback.ToString());
return;
}
Debug.Console(1, this, "InTestMode: {0}, unable to set enable state: {1}", InTestMode.ToString(), state.ToString());
}
public void SetTestPartitionSensedState(bool state)
{
if (InTestMode)
{
TestPartitionSensedFeedback = state;
Debug.Console(1, this, "TestPartitionSensedFeedback: {0}", TestPartitionSensedFeedback.ToString());
return;
}
Debug.Console(1, this, "InTestMode: {0}, unable to set partition state: {1}", InTestMode.ToString(), state.ToString());
}
public void SetTestSensitivityValue(int value)
{
if (InTestMode)
{
TestSensitivityFeedback = value;
Debug.Console(1, this, "TestSensitivityFeedback: {0}", TestSensitivityFeedback);
return;
}
Debug.Console(1, this, "InTestMode: {0}, unable to set sensitivity value: {1}", InTestMode.ToString(), value);
}
public void SetEnableState(bool state)
{
if (_partitionSensor == null)
return;
_partitionSensor.Enable.BoolValue = state;
}
public void IncreaseSensitivity()
{
if (_partitionSensor == null)
return;
_partitionSensor.IncreaseSensitivity();
}
public void DecreaseSensitivity()
{
if (_partitionSensor == null)
return;
_partitionSensor.DecreaseSensitivity();
}
public void SetSensitivity(ushort value)
{
if (_partitionSensor == null)
return;
_partitionSensor.Sensitivity.UShortValue = value;
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new GlsPartitionSensorJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<GlsPartitionSensorJoinMap>(joinMapSerialized);
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
}
else
{
Debug.Console(0, this, "Please update config to use 'type': 'EiscApiAdvanced' to get all join map features for this device");
}
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, this, "Linking to Bridge Type {0}", GetType().Name);
// link input from simpl
trilist.SetSigTrueAction(joinMap.Enable.JoinNumber, () => SetEnableState(true));
trilist.SetSigFalseAction(joinMap.Enable.JoinNumber, () => SetEnableState(false));
trilist.SetSigTrueAction(joinMap.IncreaseSensitivity.JoinNumber, IncreaseSensitivity);
trilist.SetSigTrueAction(joinMap.DecreaseSensitivity.JoinNumber, DecreaseSensitivity);
trilist.SetUShortSigAction(joinMap.Sensitivity.JoinNumber, SetSensitivity);
// link output to simpl
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
EnableFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Enable.JoinNumber]);
PartitionSensedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionSensed.JoinNumber]);
PartitionNotSensedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionNotSensed.JoinNumber]);
SensitivityFeedback.LinkInputSig(trilist.UShortInput[joinMap.Sensitivity.JoinNumber]);
FeedbacksFireUpdates();
// update when device is online
_partitionSensor.OnlineStatusChange += (o, a) =>
{
if (a.DeviceOnLine)
{
FeedbacksFireUpdates();
}
};
// update when trilist is online
trilist.OnlineStatusChange += (o, a) =>
{
if (a.DeviceOnLine)
{
FeedbacksFireUpdates();
}
};
}
private void FeedbacksFireUpdates()
{
IsOnline.FireUpdate();
NameFeedback.FireUpdate();
EnableFeedback.FireUpdate();
PartitionSensedFeedback.FireUpdate();
PartitionNotSensedFeedback.FireUpdate();
SensitivityFeedback.FireUpdate();
}
#region PreActivation
private static GlsPartCn GetGlsPartCnDevice(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 GlsPartCn", parentKey);
return new GlsPartCn(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 GlsPartCn", parentKey);
return new GlsPartCn(cresnetId, cresnetBridge.CresnetBranches[branchId]);
}
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
return null;
}
#endregion
public class GlsPartitionSensorControllerFactory : EssentialsDeviceFactory<GlsPartitionSensorController>
{
public GlsPartitionSensorControllerFactory()
{
TypeNames = new List<string>() { "glspartcn" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new C2N-RTHS Device");
return new GlsPartitionSensorController(dc.Key, GetGlsPartCnDevice, dc);
}
}
}
}

View File

@@ -137,6 +137,7 @@
<Compile Include="Bridges\JoinMaps\GenericLightingJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\GenericRelayControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\GlsOccupancySensorBaseJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\GlsPartitionSensorJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\HdMdNxM4kEControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\HdMdxxxCEControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\Hrxxx0WirelessRemoteControllerJoinMap.cs" />
@@ -171,6 +172,8 @@
</Compile>
<Compile Include="Crestron IO\Cards\CenCi33Controller.cs" />
<Compile Include="Crestron IO\Cards\InternalCardCageController.cs" />
<Compile Include="Crestron IO\DinCenCn\DinCenCnController.cs" />
<Compile Include="Crestron IO\DinCenCn\IHasCresnetBranches.cs" />
<Compile Include="Crestron IO\Inputs\CenIoDigIn104Controller.cs" />
<Compile Include="Crestron IO\Inputs\GenericDigitalInputDevice.cs" />
<Compile Include="Crestron IO\Inputs\GenericVersiportInputDevice.cs" />
@@ -192,6 +195,7 @@
<Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" />
<Compile Include="Factory\DeviceFactory.cs" />
<Compile Include="Factory\IDeviceFactory.cs" />
<Compile Include="Factory\ReadyEventArgs.cs" />
<Compile Include="Feedbacks\BoolFeedback.cs" />
<Compile Include="Feedbacks\FeedbackCollection.cs" />
<Compile Include="Feedbacks\FeedbackEventArgs.cs" />
@@ -213,6 +217,11 @@
<Compile Include="Monitoring\SystemMonitorController.cs" />
<Compile Include="Microphone Privacy\MicrophonePrivacyController.cs" />
<Compile Include="Microphone Privacy\MicrophonePrivacyControllerConfig.cs" />
<Compile Include="Occupancy\CenOdtOccupancySensorBaseController.cs" />
<Compile Include="Occupancy\GlsOccupancySensorBaseController.cs" />
<Compile Include="Occupancy\GlsOdtOccupancySensorController.cs" />
<Compile Include="Occupancy\IOccupancyStatusProviderAggregator.cs" />
<Compile Include="PartitionSensor\GlsPartitionSensorController.cs" />
<Compile Include="Plugins\PluginLoader.cs" />
<Compile Include="Presets\PresetBase.cs" />
<Compile Include="Plugins\IPluginDeviceFactory.cs" />

View File

@@ -21,30 +21,70 @@ namespace PepperDash.Essentials.Core
[Description("Wrapper class for all HR-Series remotes")]
public class Hrxx0WirelessRemoteController : EssentialsBridgeableDevice, IHasFeedback
{
private CenRfgwController _gateway;
private Hr1x0WirelessRemoteBase _remote;
public FeedbackCollection<Feedback> Feedbacks { get; set; }
public CrestronCollection<Button> Buttons { get { return _remote.Button; } }
private DeviceConfig _config;
public Hrxx0WirelessRemoteController(string key, Func<DeviceConfig, Hr1x0WirelessRemoteBase> preActivationFunc,
DeviceConfig config)
: base(key, config.Name)
{
Feedbacks = new FeedbackCollection<Feedback>();
AddPreActivationAction(() =>
var props = JsonConvert.DeserializeObject<CrestronRemotePropertiesConfig>(config.Properties.ToString());
var type = config.Type;
var rfId = (uint)props.Control.InfinetIdInt;
_config = config;
GatewayBase gateway;
if (props.GatewayDeviceKey == "processor")
{
_remote = preActivationFunc(config);
gateway = Global.ControlSystem.ControllerRFGatewayDevice;
}
_remote.ButtonStateChange += new ButtonEventHandler(_remote_ButtonStateChange);
else
{
var gatewayDev = DeviceManager.GetDeviceForKey(props.GatewayDeviceKey) as CenRfgwController;
if (gatewayDev == null)
{
Debug.Console(0, "GetHr1x0WirelessRemote: Device '{0}' is not a valid device", props.GatewayDeviceKey);
}
if (gatewayDev != null)
{
Debug.Console(0, "GetHr1x0WirelessRemote: Device '{0}' is a valid device", props.GatewayDeviceKey);
gateway = gatewayDev.GateWay;
_gateway = gatewayDev;
}
}
Feedbacks.Add(new BoolFeedback("BatteryCritical", () => _remote.BatteryCriticalFeedback.BoolValue));
Feedbacks.Add(new BoolFeedback("BatteryLow", () => _remote.BatteryLowFeedback.BoolValue));
Feedbacks.Add(new IntFeedback("BatteryVoltage", () => _remote.BatteryVoltageFeedback.UShortValue));
if (_gateway == null) return;
_remote.BaseEvent += new BaseEventHandler(_remote_BaseEvent);
});
_gateway.IsReadyEvent += _gateway_IsReadyEvent;
if (_gateway.IsReady)
{
AddPreActivationAction(() =>
{
_remote = preActivationFunc(config);
RegisterEvents();
});
}
}
void _gateway_IsReadyEvent(object sender, PepperDash_Essentials_Core.IsReadyEventArgs e)
{
if (e.IsReady != true) return;
_remote = GetHr1x0WirelessRemote(_config);
RegisterEvents();
}
void _remote_BaseEvent(GenericBase device, BaseEventArgs args)
@@ -57,6 +97,17 @@ namespace PepperDash.Essentials.Core
Feedbacks["BatteryVoltage"].FireUpdate();
}
private void RegisterEvents()
{
_remote.ButtonStateChange += _remote_ButtonStateChange;
Feedbacks.Add(new BoolFeedback("BatteryCritical", () => _remote.BatteryCriticalFeedback.BoolValue));
Feedbacks.Add(new BoolFeedback("BatteryLow", () => _remote.BatteryLowFeedback.BoolValue));
Feedbacks.Add(new IntFeedback("BatteryVoltage", () => _remote.BatteryVoltageFeedback.UShortValue));
_remote.BaseEvent += _remote_BaseEvent;
}
void _remote_ButtonStateChange(GenericBase device, ButtonEventArgs args)
{
try
@@ -112,22 +163,29 @@ namespace PepperDash.Essentials.Core
return null;
}
Hr1x0WirelessRemoteBase remoteBase;
switch (type)
{
case ("hr100"):
return new Hr100(rfId, gateway);
remoteBase = new Hr100(rfId, gateway);
break;
case ("hr150"):
return new Hr150(rfId, gateway);
remoteBase = new Hr150(rfId, gateway);
break;
case ("hr310"):
return new Hr310(rfId, gateway);
remoteBase = new Hr310(rfId, gateway);
break;
default:
return null;
}
}
static void gateway_BaseEvent(GenericBase device, BaseEventArgs args)
{
throw new NotImplementedException();
// register the device when using an internal RF gateway
if (props.GatewayDeviceKey == "processor")
{
remoteBase.RegisterWithLogging(config.Key);
}
return remoteBase;
}
#endregion
@@ -249,4 +307,4 @@ namespace PepperDash.Essentials.Core
trilist.BooleanInput[join].BoolValue = b;
}
}
}
}