Skip to content

Commit

Permalink
Merge pull request #1212 from PepperDash/feature-2.0.0/versiport-room…
Browse files Browse the repository at this point in the history
…-combiner

Enable using Versiports with Room Combiner
  • Loading branch information
andrew-welker authored Feb 19, 2025
2 parents cc724dd + 261779d commit f2545fb
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// <summary>
/// Represents a generic digital input deviced tied to a versiport
/// </summary>
public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IPartitionStateProvider
{
public Versiport InputPort { get; private set; }

Expand All @@ -35,10 +35,15 @@ Func<bool> InputStateFeedbackFunc
}
}

public BoolFeedback PartitionPresentFeedback { get; }

public bool PartitionPresent => !InputStateFeedbackFunc();

public GenericVersiportDigitalInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
base(key, name)
{
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
PartitionPresentFeedback = new BoolFeedback(() => !InputStateFeedbackFunc());

AddPostActivationAction(() =>
{
Expand All @@ -52,7 +57,8 @@ public GenericVersiportDigitalInputDevice(string key, string name, Func<IOPortCo

InputPort.VersiportChange += InputPort_VersiportChange;


InputStateFeedback.FireUpdate();
PartitionPresentFeedback.FireUpdate();

Debug.LogMessage(LogEventLevel.Debug, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor);

Expand All @@ -65,7 +71,10 @@ void InputPort_VersiportChange(Versiport port, VersiportEventArgs args)
Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event);

if(args.Event == eVersiportEvent.DigitalInChange)
{
InputStateFeedback.FireUpdate();
PartitionPresentFeedback.FireUpdate();
}
}


Expand Down
Original file line number Diff line number Diff line change
@@ -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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesC
//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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class EssentialsRoomEmergencyConfig
public class EssentialsRoomEmergencyTriggerConfig
{
/// <summary>
/// contact,
/// contact,versiport
/// </summary>
public string Type { get; set; }
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@

namespace PepperDash.Essentials.Core
{
public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase
public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase, IEssentialsRoomEmergency
{
public event EventHandler<EventArgs> EmergencyStateChange;

IEssentialsRoom Room;
string Behavior;
bool TriggerOnClose;

public bool InEmergency { get; private set; }

public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, IEssentialsRoom room) :
base(key)
{
Expand All @@ -25,14 +29,49 @@ public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergency
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());
}
}

/// <summary>
Expand All @@ -44,4 +83,14 @@ public void RunEmergencyBehavior()
Room.Shutdown();
}
}

/// <summary>
/// Describes the functionality of a room emergency contact closure
/// </summary>
public interface IEssentialsRoomEmergency
{
event EventHandler<EventArgs> EmergencyStateChange;

bool InEmergency { get; }
}
}
64 changes: 38 additions & 26 deletions src/PepperDash.Essentials.Core/Routing/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,25 +108,31 @@ private static void ReleaseAndMakeRoute(IRoutingInputs destination, IRoutingOutp

private static void RunRouteRequest(RouteRequest request)
{
if (request.Source == null)
return;
try
{
if (request.Source == null)
return;

var (audioOrSingleRoute, videoRoute) = request.Destination.GetRouteToSource(request.Source, request.SignalType, request.DestinationPort, request.SourcePort);
var (audioOrSingleRoute, videoRoute) = request.Destination.GetRouteToSource(request.Source, request.SignalType, request.DestinationPort, request.SourcePort);

if (audioOrSingleRoute == null && videoRoute == null)
return;
if (audioOrSingleRoute == null && videoRoute == null)
return;

RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(audioOrSingleRoute);
RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(audioOrSingleRoute);

if (videoRoute != null)
{
RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(videoRoute);
}
if (videoRoute != null)
{
RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(videoRoute);
}

Debug.LogMessage(LogEventLevel.Verbose, "Executing full route", request.Destination);
Debug.LogMessage(LogEventLevel.Verbose, "Executing full route", request.Destination);

audioOrSingleRoute.ExecuteRoutes();
videoRoute?.ExecuteRoutes();
audioOrSingleRoute.ExecuteRoutes();
videoRoute?.ExecuteRoutes();
} catch(Exception ex)
{
Debug.LogMessage(ex, "Exception Running Route Request {request}", null, request);
}
}

public static void ReleaseRoute(this IRoutingInputs destination)
Expand All @@ -141,23 +147,28 @@ public static void ReleaseRoute(this IRoutingInputs destination)
/// <param name="destination"></param>
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);
}
}

Expand All @@ -179,7 +190,8 @@ public static (RouteDescriptor, RouteDescriptor) GetRouteToSource(this IRoutingI
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<RouteSwitchDescriptor>();
foreach (var route in routes)
{
Debug.LogMessage(LogEventLevel.Verbose, "Route for device: {route}", destination, route.ToString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public void AddRouteDescriptor(RouteDescriptor descriptor)
&& 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);
Expand All @@ -53,14 +53,14 @@ public void AddRouteDescriptor(RouteDescriptor descriptor)
/// <returns>null if no RouteDescriptor for a destination exists</returns>
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);
}

Expand All @@ -70,15 +70,15 @@ public RouteDescriptor GetRouteDescriptorForDestinationAndInputPort(IRoutingInpu
/// </summary>
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)
: GetRouteDescriptorForDestinationAndInputPort(destination, inputPortKey);
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;
}
Expand Down

0 comments on commit f2545fb

Please sign in to comment.