mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-15 20:54:55 +00:00
Merge pull request #1212 from PepperDash/feature-2.0.0/versiport-room-combiner
Enable using Versiports with Room Combiner
This commit is contained in:
@@ -21,7 +21,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a generic digital input deviced tied to a versiport
|
/// Represents a generic digital input deviced tied to a versiport
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
|
public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IPartitionStateProvider
|
||||||
{
|
{
|
||||||
public Versiport InputPort { get; private set; }
|
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<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
|
public GenericVersiportDigitalInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
|
||||||
base(key, name)
|
base(key, name)
|
||||||
{
|
{
|
||||||
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
|
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
|
||||||
|
PartitionPresentFeedback = new BoolFeedback(() => !InputStateFeedbackFunc());
|
||||||
|
|
||||||
AddPostActivationAction(() =>
|
AddPostActivationAction(() =>
|
||||||
{
|
{
|
||||||
@@ -52,7 +57,8 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
|||||||
|
|
||||||
InputPort.VersiportChange += InputPort_VersiportChange;
|
InputPort.VersiportChange += InputPort_VersiportChange;
|
||||||
|
|
||||||
|
InputStateFeedback.FireUpdate();
|
||||||
|
PartitionPresentFeedback.FireUpdate();
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor);
|
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);
|
Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event);
|
||||||
|
|
||||||
if(args.Event == eVersiportEvent.DigitalInChange)
|
if(args.Event == eVersiportEvent.DigitalInChange)
|
||||||
|
{
|
||||||
InputStateFeedback.FireUpdate();
|
InputStateFeedback.FireUpdate();
|
||||||
|
PartitionPresentFeedback.FireUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
//switch on emergency type here. Right now only contact and shutdown
|
//switch on emergency type here. Right now only contact and shutdown
|
||||||
var e = new EssentialsRoomEmergencyContactClosure(room.Key + "-emergency", props.Emergency, room);
|
var e = new EssentialsRoomEmergencyContactClosure(room.Key + "-emergency", props.Emergency, room);
|
||||||
DeviceManager.AddDevice(e);
|
DeviceManager.AddDevice(e);
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
public class EssentialsRoomEmergencyTriggerConfig
|
public class EssentialsRoomEmergencyTriggerConfig
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// contact,
|
/// contact,versiport
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -4,12 +4,16 @@ using PepperDash.Essentials.Room.Config;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase
|
public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase, IEssentialsRoomEmergency
|
||||||
{
|
{
|
||||||
|
public event EventHandler<EventArgs> EmergencyStateChange;
|
||||||
|
|
||||||
IEssentialsRoom Room;
|
IEssentialsRoom Room;
|
||||||
string Behavior;
|
string Behavior;
|
||||||
bool TriggerOnClose;
|
bool TriggerOnClose;
|
||||||
|
|
||||||
|
public bool InEmergency { get; private set; }
|
||||||
|
|
||||||
public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, IEssentialsRoom room) :
|
public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, IEssentialsRoom room) :
|
||||||
base(key)
|
base(key)
|
||||||
{
|
{
|
||||||
@@ -25,14 +29,49 @@ namespace PepperDash.Essentials.Core
|
|||||||
cs.DigitalInputPorts[portNum].StateChange += EsentialsRoomEmergencyContactClosure_StateChange;
|
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;
|
Behavior = config.Behavior;
|
||||||
TriggerOnClose = config.Trigger.TriggerOnClose;
|
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)
|
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();
|
RunEmergencyBehavior();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InEmergency = false;
|
||||||
|
if (EmergencyStateChange != null)
|
||||||
|
EmergencyStateChange(this, new EventArgs());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -44,4 +83,14 @@ namespace PepperDash.Essentials.Core
|
|||||||
Room.Shutdown();
|
Room.Shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Describes the functionality of a room emergency contact closure
|
||||||
|
/// </summary>
|
||||||
|
public interface IEssentialsRoomEmergency
|
||||||
|
{
|
||||||
|
event EventHandler<EventArgs> EmergencyStateChange;
|
||||||
|
|
||||||
|
bool InEmergency { get; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -108,25 +108,31 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
private static void RunRouteRequest(RouteRequest request)
|
private static void RunRouteRequest(RouteRequest request)
|
||||||
{
|
{
|
||||||
if (request.Source == null)
|
try
|
||||||
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);
|
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)
|
public static void ReleaseRoute(this IRoutingInputs destination)
|
||||||
@@ -141,23 +147,28 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// <param name="destination"></param>
|
/// <param name="destination"></param>
|
||||||
public static void ReleaseRoute(this IRoutingInputs destination, string inputPortKey)
|
public static void ReleaseRoute(this IRoutingInputs destination, string inputPortKey)
|
||||||
{
|
{
|
||||||
|
try
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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);
|
RouteRequests.Remove(destination.Key);
|
||||||
if (current != null)
|
|
||||||
|
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);
|
Debug.LogMessage(ex, "Exception releasing route for '{destination}':'{inputPortKey}'",null, destination?.Key ?? null, string.IsNullOrEmpty(inputPortKey) ? "auto" : inputPortKey);
|
||||||
current.ReleaseRoutes();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +190,8 @@ namespace PepperDash.Essentials.Core
|
|||||||
if (!destination.GetRouteToSource(source, null, null, signalType, 0, singleTypeRouteDescriptor, destinationPort, sourcePort))
|
if (!destination.GetRouteToSource(source, null, null, signalType, 0, singleTypeRouteDescriptor, destinationPort, sourcePort))
|
||||||
singleTypeRouteDescriptor = null;
|
singleTypeRouteDescriptor = null;
|
||||||
|
|
||||||
foreach (var route in singleTypeRouteDescriptor.Routes)
|
var routes = singleTypeRouteDescriptor?.Routes ?? new List<RouteSwitchDescriptor>();
|
||||||
|
foreach (var route in routes)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Route for device: {route}", destination, route.ToString());
|
Debug.LogMessage(LogEventLevel.Verbose, "Route for device: {route}", destination, route.ToString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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))
|
&& 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,
|
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;
|
return;
|
||||||
}
|
}
|
||||||
RouteDescriptors.Add(descriptor);
|
RouteDescriptors.Add(descriptor);
|
||||||
@@ -53,14 +53,14 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// <returns>null if no RouteDescriptor for a destination exists</returns>
|
/// <returns>null if no RouteDescriptor for a destination exists</returns>
|
||||||
public RouteDescriptor GetRouteDescriptorForDestination(IRoutingInputs destination)
|
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);
|
return RouteDescriptors.FirstOrDefault(rd => rd.Destination == destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RouteDescriptor GetRouteDescriptorForDestinationAndInputPort(IRoutingInputs destination, string inputPortKey)
|
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);
|
return RouteDescriptors.FirstOrDefault(rd => rd.Destination == destination && rd.InputPort != null && rd.InputPort.Key == inputPortKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public RouteDescriptor RemoveRouteDescriptor(IRoutingInputs destination, string inputPortKey = "")
|
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)
|
var descr = string.IsNullOrEmpty(inputPortKey)
|
||||||
? GetRouteDescriptorForDestination(destination)
|
? GetRouteDescriptorForDestination(destination)
|
||||||
@@ -78,7 +78,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
if (descr != null)
|
if (descr != null)
|
||||||
RouteDescriptors.Remove(descr);
|
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;
|
return descr;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user