diff --git a/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportInputDevice.cs b/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportInputDevice.cs
index 5ed1bfa8..c9133a60 100644
--- a/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportInputDevice.cs
+++ b/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportInputDevice.cs
@@ -21,7 +21,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
///
/// Represents a generic digital input deviced tied to a versiport
///
- public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
+ public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IPartitionStateProvider
{
public Versiport InputPort { get; private set; }
@@ -35,10 +35,15 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
}
+ public BoolFeedback PartitionPresentFeedback { get; }
+
+ public bool PartitionPresent => !InputStateFeedbackFunc();
+
public GenericVersiportDigitalInputDevice(string key, string name, Func postActivationFunc, IOPortConfig config) :
base(key, name)
{
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
+ PartitionPresentFeedback = new BoolFeedback(() => !InputStateFeedbackFunc());
AddPostActivationAction(() =>
{
@@ -52,7 +57,8 @@ namespace PepperDash.Essentials.Core.CrestronIO
InputPort.VersiportChange += InputPort_VersiportChange;
-
+ InputStateFeedback.FireUpdate();
+ PartitionPresentFeedback.FireUpdate();
Debug.LogMessage(LogEventLevel.Debug, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor);
@@ -65,7 +71,10 @@ namespace PepperDash.Essentials.Core.CrestronIO
Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event);
if(args.Event == eVersiportEvent.DigitalInChange)
+ {
InputStateFeedback.FireUpdate();
+ PartitionPresentFeedback.FireUpdate();
+ }
}
diff --git a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IEmergencyOSD.cs b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IEmergencyOSD.cs
new file mode 100644
index 00000000..7d158027
--- /dev/null
+++ b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IEmergencyOSD.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
+{
+ public interface IEmergencyOSD
+ {
+ void ShowEmergencyMessage(string url);
+ void HideEmergencyMessage();
+ }
+}
diff --git a/src/PepperDash.Essentials.Core/Room/Config/EssentialsRoomConfig.cs b/src/PepperDash.Essentials.Core/Room/Config/EssentialsRoomConfig.cs
index 3f457176..e9a2c29b 100644
--- a/src/PepperDash.Essentials.Core/Room/Config/EssentialsRoomConfig.cs
+++ b/src/PepperDash.Essentials.Core/Room/Config/EssentialsRoomConfig.cs
@@ -24,6 +24,7 @@ namespace PepperDash.Essentials.Room.Config
//switch on emergency type here. Right now only contact and shutdown
var e = new EssentialsRoomEmergencyContactClosure(room.Key + "-emergency", props.Emergency, room);
DeviceManager.AddDevice(e);
+ return e;
}
return null;
}
diff --git a/src/PepperDash.Essentials.Core/Room/Config/EssentialsRoomEmergencyConfig.cs b/src/PepperDash.Essentials.Core/Room/Config/EssentialsRoomEmergencyConfig.cs
index 76199a91..dbc068eb 100644
--- a/src/PepperDash.Essentials.Core/Room/Config/EssentialsRoomEmergencyConfig.cs
+++ b/src/PepperDash.Essentials.Core/Room/Config/EssentialsRoomEmergencyConfig.cs
@@ -16,7 +16,7 @@
public class EssentialsRoomEmergencyTriggerConfig
{
///
- /// contact,
+ /// contact,versiport
///
public string Type { get; set; }
///
diff --git a/src/PepperDash.Essentials.Core/Room/EsentialsRoomEmergencyContactClosure.cs b/src/PepperDash.Essentials.Core/Room/EsentialsRoomEmergencyContactClosure.cs
index 7ad7f700..48d24ab0 100644
--- a/src/PepperDash.Essentials.Core/Room/EsentialsRoomEmergencyContactClosure.cs
+++ b/src/PepperDash.Essentials.Core/Room/EsentialsRoomEmergencyContactClosure.cs
@@ -4,12 +4,16 @@ using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials.Core
{
- public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase
+ public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase, IEssentialsRoomEmergency
{
+ public event EventHandler EmergencyStateChange;
+
IEssentialsRoom Room;
string Behavior;
bool TriggerOnClose;
+ public bool InEmergency { get; private set; }
+
public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, IEssentialsRoom room) :
base(key)
{
@@ -25,14 +29,49 @@ namespace PepperDash.Essentials.Core
cs.DigitalInputPorts[portNum].StateChange += EsentialsRoomEmergencyContactClosure_StateChange;
}
}
+ else if (config.Trigger.Type.Equals("versiport", StringComparison.OrdinalIgnoreCase))
+ {
+ var portNum = (uint)config.Trigger.Number;
+ if (portNum <= cs.NumberOfVersiPorts)
+ {
+ cs.VersiPorts[portNum].Register();
+ cs.VersiPorts[portNum].SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
+ cs.VersiPorts[portNum].DisablePullUpResistor = true;
+ cs.VersiPorts[portNum].VersiportChange += EssentialsRoomEmergencyContactClosure_VersiportChange;
+ }
+ }
Behavior = config.Behavior;
TriggerOnClose = config.Trigger.TriggerOnClose;
}
+ private void EssentialsRoomEmergencyContactClosure_VersiportChange(Versiport port, VersiportEventArgs args)
+ {
+ if (args.Event == eVersiportEvent.DigitalInChange)
+ {
+ ContactClosure_StateChange(port.DigitalIn);
+ }
+ }
+
void EsentialsRoomEmergencyContactClosure_StateChange(DigitalInput digitalInput, DigitalInputEventArgs args)
{
- if (args.State && TriggerOnClose || !args.State && !TriggerOnClose)
+ ContactClosure_StateChange(args.State);
+ }
+
+ void ContactClosure_StateChange(bool portState)
+ {
+ if (portState && TriggerOnClose || !portState && !TriggerOnClose)
+ {
+ InEmergency = true;
+ if (EmergencyStateChange != null)
+ EmergencyStateChange(this, new EventArgs());
RunEmergencyBehavior();
+ }
+ else
+ {
+ InEmergency = false;
+ if (EmergencyStateChange != null)
+ EmergencyStateChange(this, new EventArgs());
+ }
}
///
@@ -44,4 +83,14 @@ namespace PepperDash.Essentials.Core
Room.Shutdown();
}
}
+
+ ///
+ /// Describes the functionality of a room emergency contact closure
+ ///
+ public interface IEssentialsRoomEmergency
+ {
+ event EventHandler EmergencyStateChange;
+
+ bool InEmergency { get; }
+ }
}
\ No newline at end of file
diff --git a/src/PepperDash.Essentials.Core/Routing/Extensions.cs b/src/PepperDash.Essentials.Core/Routing/Extensions.cs
index fccaa80c..ee885abf 100644
--- a/src/PepperDash.Essentials.Core/Routing/Extensions.cs
+++ b/src/PepperDash.Essentials.Core/Routing/Extensions.cs
@@ -108,25 +108,31 @@ namespace PepperDash.Essentials.Core
private static void RunRouteRequest(RouteRequest request)
{
- if (request.Source == null)
- return;
-
- var (audioOrSingleRoute, videoRoute) = request.Destination.GetRouteToSource(request.Source, request.SignalType, request.DestinationPort, request.SourcePort);
-
- if (audioOrSingleRoute == null && videoRoute == null)
- return;
-
- RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(audioOrSingleRoute);
-
- if (videoRoute != null)
+ try
{
- RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(videoRoute);
+ if (request.Source == null)
+ return;
+
+ var (audioOrSingleRoute, videoRoute) = request.Destination.GetRouteToSource(request.Source, request.SignalType, request.DestinationPort, request.SourcePort);
+
+ if (audioOrSingleRoute == null && videoRoute == null)
+ return;
+
+ RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(audioOrSingleRoute);
+
+ if (videoRoute != null)
+ {
+ RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(videoRoute);
+ }
+
+ Debug.LogMessage(LogEventLevel.Verbose, "Executing full route", request.Destination);
+
+ audioOrSingleRoute.ExecuteRoutes();
+ videoRoute?.ExecuteRoutes();
+ } catch(Exception ex)
+ {
+ Debug.LogMessage(ex, "Exception Running Route Request {request}", null, request);
}
-
- Debug.LogMessage(LogEventLevel.Verbose, "Executing full route", request.Destination);
-
- audioOrSingleRoute.ExecuteRoutes();
- videoRoute?.ExecuteRoutes();
}
public static void ReleaseRoute(this IRoutingInputs destination)
@@ -141,23 +147,28 @@ namespace PepperDash.Essentials.Core
///
public static void ReleaseRoute(this IRoutingInputs destination, string inputPortKey)
{
-
- Debug.LogMessage(LogEventLevel.Information, "Release route for {inputPortKey}", destination, string.IsNullOrEmpty(inputPortKey) ? "auto" : inputPortKey);
-
- if (RouteRequests.TryGetValue(destination.Key, out RouteRequest existingRequest) && destination is IWarmingCooling)
+ try
{
- var coolingDevice = destination as IWarmingCooling;
+ Debug.LogMessage(LogEventLevel.Information, "Release route for '{destination}':'{inputPortKey}'", destination?.Key ?? null, string.IsNullOrEmpty(inputPortKey) ? "auto" : inputPortKey);
- coolingDevice.IsCoolingDownFeedback.OutputChange -= existingRequest.HandleCooldown;
- }
+ if (RouteRequests.TryGetValue(destination.Key, out RouteRequest existingRequest) && destination is IWarmingCooling)
+ {
+ var coolingDevice = destination as IWarmingCooling;
- RouteRequests.Remove(destination.Key);
+ coolingDevice.IsCoolingDownFeedback.OutputChange -= existingRequest.HandleCooldown;
+ }
- var current = RouteDescriptorCollection.DefaultCollection.RemoveRouteDescriptor(destination, inputPortKey);
- if (current != null)
+ RouteRequests.Remove(destination.Key);
+
+ var current = RouteDescriptorCollection.DefaultCollection.RemoveRouteDescriptor(destination, inputPortKey);
+ if (current != null)
+ {
+ Debug.LogMessage(LogEventLevel.Information, "Releasing current route: {0}", destination, current.Source.Key);
+ current.ReleaseRoutes();
+ }
+ } catch (Exception ex)
{
- Debug.LogMessage(LogEventLevel.Debug, "Releasing current route: {0}", destination, current.Source.Key);
- current.ReleaseRoutes();
+ Debug.LogMessage(ex, "Exception releasing route for '{destination}':'{inputPortKey}'",null, destination?.Key ?? null, string.IsNullOrEmpty(inputPortKey) ? "auto" : inputPortKey);
}
}
@@ -179,7 +190,8 @@ namespace PepperDash.Essentials.Core
if (!destination.GetRouteToSource(source, null, null, signalType, 0, singleTypeRouteDescriptor, destinationPort, sourcePort))
singleTypeRouteDescriptor = null;
- foreach (var route in singleTypeRouteDescriptor.Routes)
+ var routes = singleTypeRouteDescriptor?.Routes ?? new List();
+ foreach (var route in routes)
{
Debug.LogMessage(LogEventLevel.Verbose, "Route for device: {route}", destination, route.ToString());
}
diff --git a/src/PepperDash.Essentials.Core/Routing/RouteDescriptorCollection.cs b/src/PepperDash.Essentials.Core/Routing/RouteDescriptorCollection.cs
index 6c4a5df5..9bafc128 100644
--- a/src/PepperDash.Essentials.Core/Routing/RouteDescriptorCollection.cs
+++ b/src/PepperDash.Essentials.Core/Routing/RouteDescriptorCollection.cs
@@ -41,7 +41,7 @@ namespace PepperDash.Essentials.Core
&& RouteDescriptors.Any(t => t.Destination == descriptor.Destination && t.InputPort != null && descriptor.InputPort != null && t.InputPort.Key == descriptor.InputPort.Key))
{
Debug.LogMessage(LogEventLevel.Debug, descriptor.Destination,
- "Route to [{0}] already exists in global routes table", descriptor.Source.Key);
+ "Route to [{0}] already exists in global routes table", descriptor?.Source?.Key);
return;
}
RouteDescriptors.Add(descriptor);
@@ -53,14 +53,14 @@ namespace PepperDash.Essentials.Core
/// null if no RouteDescriptor for a destination exists
public RouteDescriptor GetRouteDescriptorForDestination(IRoutingInputs destination)
{
- Debug.LogMessage(LogEventLevel.Debug, "Getting route descriptor", destination);
+ Debug.LogMessage(LogEventLevel.Information, "Getting route descriptor for '{destination}'", destination?.Key ?? null);
return RouteDescriptors.FirstOrDefault(rd => rd.Destination == destination);
}
public RouteDescriptor GetRouteDescriptorForDestinationAndInputPort(IRoutingInputs destination, string inputPortKey)
{
- Debug.LogMessage(LogEventLevel.Debug, "Getting route descriptor for {inputPortKey}", destination, string.IsNullOrEmpty(inputPortKey) ? "auto" : inputPortKey);
+ Debug.LogMessage(LogEventLevel.Information, "Getting route descriptor for '{destination}':'{inputPortKey}'", destination?.Key ?? null, string.IsNullOrEmpty(inputPortKey) ? "auto" : inputPortKey);
return RouteDescriptors.FirstOrDefault(rd => rd.Destination == destination && rd.InputPort != null && rd.InputPort.Key == inputPortKey);
}
@@ -70,7 +70,7 @@ namespace PepperDash.Essentials.Core
///
public RouteDescriptor RemoveRouteDescriptor(IRoutingInputs destination, string inputPortKey = "")
{
- Debug.LogMessage(LogEventLevel.Debug, "Removing route descriptor for {inputPortKey}", destination, string.IsNullOrEmpty(inputPortKey) ? "auto" : inputPortKey);
+ Debug.LogMessage(LogEventLevel.Information, "Removing route descriptor for '{destination}':'{inputPortKey}'", destination.Key ?? null, string.IsNullOrEmpty(inputPortKey) ? "auto" : inputPortKey);
var descr = string.IsNullOrEmpty(inputPortKey)
? GetRouteDescriptorForDestination(destination)
@@ -78,7 +78,7 @@ namespace PepperDash.Essentials.Core
if (descr != null)
RouteDescriptors.Remove(descr);
- Debug.LogMessage(LogEventLevel.Debug, "Found route descriptor {routeDescriptor}", destination, descr);
+ Debug.LogMessage(LogEventLevel.Information, "Found route descriptor {routeDescriptor}", destination, descr);
return descr;
}