diff --git a/src/PepperDash.Essentials.Core/Bridges/BridgeBase.cs b/src/PepperDash.Essentials.Core/Bridges/BridgeBase.cs
index 92ac2b9c..070f1743 100644
--- a/src/PepperDash.Essentials.Core/Bridges/BridgeBase.cs
+++ b/src/PepperDash.Essentials.Core/Bridges/BridgeBase.cs
@@ -2,25 +2,29 @@
using System;
using System.Collections.Generic;
-using System.Reflection;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.EthernetCommunication;
using Newtonsoft.Json;
using PepperDash.Core;
+using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
-//using PepperDash.Essentials.Devices.Common.Cameras;
namespace PepperDash.Essentials.Core.Bridges
{
///
/// Base class for bridge API variants
///
+ [Obsolete("Will be removed in v3.0.0")]
public abstract class BridgeApi : EssentialsDevice
{
+ ///
+ /// Constructor
+ ///
+ /// Device key
protected BridgeApi(string key) :
base(key)
{
@@ -29,23 +33,36 @@ namespace PepperDash.Essentials.Core.Bridges
}
///
- /// Represents a EiscApiAdvanced
+ /// Class to link devices and rooms to an EISC Instance
///
public class EiscApiAdvanced : BridgeApi, ICommunicationMonitor
{
+ ///
+ /// Gets the PropertiesConfig
+ ///
public EiscApiPropertiesConfig PropertiesConfig { get; private set; }
+ ///
+ /// Gets the JoinMaps dictionary
+ ///
public Dictionary JoinMaps { get; private set; }
+ ///
+ /// Gets the EISC instance
+ ///
public BasicTriList Eisc { get; private set; }
+ ///
+ /// Constructor
+ ///
+ /// Device configuration
+ /// EISC instance
public EiscApiAdvanced(DeviceConfig dc, BasicTriList eisc) :
base(dc.Key)
{
JoinMaps = new Dictionary();
PropertiesConfig = dc.Properties.ToObject();
- //PropertiesConfig = JsonConvert.DeserializeObject(dc.Properties.ToString());
Eisc = eisc;
@@ -60,8 +77,7 @@ namespace PepperDash.Essentials.Core.Bridges
///
/// CustomActivate method
- ///
- ///
+ ///
public override bool CustomActivate()
{
CommunicationMonitor.Start();
@@ -83,7 +99,7 @@ namespace PepperDash.Essentials.Core.Bridges
if (PropertiesConfig.Devices == null)
{
- Debug.LogMessage(LogEventLevel.Debug, this, "No devices linked to this bridge");
+ this.LogDebug("No devices linked to this bridge");
return;
}
@@ -104,9 +120,7 @@ namespace PepperDash.Essentials.Core.Bridges
continue;
}
- Debug.LogMessage(LogEventLevel.Information, this,
- "{0} is not compatible with this bridge type. Please use 'eiscapi' instead, or updae the device.",
- device.Key);
+ this.LogWarning("{deviceKey} is not compatible with this bridge type. Please update the device.", device.Key);
}
}
@@ -121,34 +135,31 @@ namespace PepperDash.Essentials.Core.Bridges
if (registerResult != eDeviceRegistrationUnRegistrationResponse.Success)
{
- Debug.LogMessage(LogEventLevel.Verbose, this, "Registration result: {0}", registerResult);
+ this.LogVerbose("Registration result: {registerResult}", registerResult);
return;
}
- Debug.LogMessage(LogEventLevel.Debug, this, "EISC registration successful");
+ this.LogDebug("EISC registration successful");
}
///
- /// LinkRooms method
+ /// Link rooms to this EISC. Rooms MUST implement IBridgeAdvanced
///
public void LinkRooms()
{
- Debug.LogMessage(LogEventLevel.Debug, this, "Linking Rooms...");
+ this.LogDebug("Linking Rooms...");
if (PropertiesConfig.Rooms == null)
{
- Debug.LogMessage(LogEventLevel.Debug, this, "No rooms linked to this bridge.");
+ this.LogDebug("No rooms linked to this bridge.");
return;
}
foreach (var room in PropertiesConfig.Rooms)
{
- var rm = DeviceManager.GetDeviceForKey(room.RoomKey) as IBridgeAdvanced;
-
- if (rm == null)
+ if (!(DeviceManager.GetDeviceForKey(room.RoomKey) is IBridgeAdvanced rm))
{
- Debug.LogMessage(LogEventLevel.Debug, this,
- "Room {0} does not implement IBridgeAdvanced. Skipping...", room.RoomKey);
+ this.LogDebug("Room {roomKey} does not implement IBridgeAdvanced. Skipping...", room.RoomKey);
continue;
}
@@ -159,11 +170,8 @@ namespace PepperDash.Essentials.Core.Bridges
///
/// Adds a join map
///
- ///
- ///
- ///
- /// AddJoinMap method
- ///
+ /// The key of the device to add the join map for
+ /// The join map to add
public void AddJoinMap(string deviceKey, JoinMapBaseAdvanced joinMap)
{
if (!JoinMaps.ContainsKey(deviceKey))
@@ -172,14 +180,13 @@ namespace PepperDash.Essentials.Core.Bridges
}
else
{
- Debug.LogMessage(LogEventLevel.Verbose, this, "Unable to add join map with key '{0}'. Key already exists in JoinMaps dictionary", deviceKey);
+ this.LogWarning("Unable to add join map with key '{deviceKey}'. Key already exists in JoinMaps dictionary", deviceKey);
}
}
///
/// PrintJoinMaps method
- ///
- ///
+ ///
public virtual void PrintJoinMaps()
{
CrestronConsole.ConsoleCommandResponse("Join Maps for EISC IPID: {0}\r\n", Eisc.ID.ToString("X"));
@@ -190,17 +197,17 @@ namespace PepperDash.Essentials.Core.Bridges
joinMap.Value.PrintJoinMapInfo();
}
}
+
///
/// MarkdownForBridge method
- ///
- ///
+ ///
public virtual void MarkdownForBridge(string bridgeKey)
{
- Debug.LogMessage(LogEventLevel.Information, this, "Writing Joinmaps to files for EISC IPID: {0}", Eisc.ID.ToString("X"));
+ this.LogInformation("Writing Joinmaps to files for EISC IPID: {eiscId}", Eisc.ID.ToString("X"));
foreach (var joinMap in JoinMaps)
{
- Debug.LogMessage(LogEventLevel.Information, "Generating markdown for device '{0}':", joinMap.Key);
+ this.LogInformation("Generating markdown for device '{deviceKey}':", joinMap.Key);
joinMap.Value.MarkdownJoinMapInfo(joinMap.Key, bridgeKey);
}
}
@@ -208,53 +215,45 @@ namespace PepperDash.Essentials.Core.Bridges
///
/// Prints the join map for a device by key
///
- ///
- ///
- /// PrintJoinMapForDevice method
- ///
+ /// The key of the device to print the join map for
public void PrintJoinMapForDevice(string deviceKey)
{
var joinMap = JoinMaps[deviceKey];
if (joinMap == null)
{
- Debug.LogMessage(LogEventLevel.Information, this, "Unable to find joinMap for device with key: '{0}'", deviceKey);
+ this.LogInformation("Unable to find joinMap for device with key: '{deviceKey}'", deviceKey);
return;
}
- Debug.LogMessage(LogEventLevel.Information, "Join map for device '{0}' on EISC '{1}':", deviceKey, Key);
+ this.LogInformation("Join map for device '{deviceKey}' on EISC '{eiscKey}':", deviceKey, Key);
joinMap.PrintJoinMapInfo();
}
///
- /// Prints the join map for a device by key
- ///
- ///
- ///
- /// MarkdownJoinMapForDevice method
+ /// Prints the join map for a device by key in Markdown format
///
+ /// The key of the device to print the join map for
+ /// The key of the bridge to use for the Markdown output
public void MarkdownJoinMapForDevice(string deviceKey, string bridgeKey)
{
var joinMap = JoinMaps[deviceKey];
if (joinMap == null)
{
- Debug.LogMessage(LogEventLevel.Information, this, "Unable to find joinMap for device with key: '{0}'", deviceKey);
+ this.LogInformation("Unable to find joinMap for device with key: '{deviceKey}'", deviceKey);
return;
}
- Debug.LogMessage(LogEventLevel.Information, "Join map for device '{0}' on EISC '{1}':", deviceKey, Key);
+ this.LogInformation("Join map for device '{deviceKey}' on EISC '{eiscKey}':", deviceKey, Key);
joinMap.MarkdownJoinMapInfo(deviceKey, bridgeKey);
}
///
/// Used for debugging to trigger an action based on a join number and type
///
- ///
- ///
- ///
- ///
- /// ExecuteJoinAction method
- ///
+ /// The join number to execute the action for
+ /// The type of join (digital, analog, serial)
+ /// The state to pass to the action
public void ExecuteJoinAction(uint join, string type, object state)
{
try
@@ -263,78 +262,87 @@ namespace PepperDash.Essentials.Core.Bridges
{
case "digital":
{
- var uo = Eisc.BooleanOutput[join].UserObject as Action;
- if (uo != null)
+ if (Eisc.BooleanOutput[join].UserObject is Action userObject)
{
- Debug.LogMessage(LogEventLevel.Verbose, this, "Executing Action: {0}", uo.ToString());
- uo(Convert.ToBoolean(state));
+ this.LogVerbose("Executing Boolean Action");
+ userObject(Convert.ToBoolean(state));
}
else
- Debug.LogMessage(LogEventLevel.Verbose, this, "User Action is null. Nothing to Execute");
+ this.LogVerbose("User Object is null. Nothing to Execute");
break;
}
case "analog":
{
- var uo = Eisc.BooleanOutput[join].UserObject as Action;
- if (uo != null)
+ if (Eisc.UShortOutput[join].UserObject is Action userObject)
{
- Debug.LogMessage(LogEventLevel.Verbose, this, "Executing Action: {0}", uo.ToString());
- uo(Convert.ToUInt16(state));
+ this.LogVerbose("Executing Analog Action");
+ userObject(Convert.ToUInt16(state));
}
else
- Debug.LogMessage(LogEventLevel.Verbose, this, "User Action is null. Nothing to Execute"); break;
+ this.LogVerbose("User Object is null. Nothing to Execute");
+ break;
}
case "serial":
{
- var uo = Eisc.BooleanOutput[join].UserObject as Action;
- if (uo != null)
+ if (Eisc.StringOutput[join].UserObject is Action userObject)
{
- Debug.LogMessage(LogEventLevel.Verbose, this, "Executing Action: {0}", uo.ToString());
- uo(Convert.ToString(state));
+ this.LogVerbose("Executing Serial Action");
+ userObject(Convert.ToString(state));
}
else
- Debug.LogMessage(LogEventLevel.Verbose, this, "User Action is null. Nothing to Execute");
+ this.LogVerbose("User Object is null. Nothing to Execute");
break;
}
default:
{
- Debug.LogMessage(LogEventLevel.Verbose, "Unknown join type. Use digital/serial/analog");
+ this.LogVerbose("Unknown join type. Use digital/serial/analog");
break;
}
}
}
catch (Exception e)
{
- Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e);
+ this.LogError("ExecuteJoinAction error: {message}", e.Message);
+ this.LogDebug(e, "Stack Trace: ");
}
}
///
- /// Handles incoming sig changes
+ /// Handle incoming sig changes
///
- ///
- ///
+ /// BasicTriList device that triggered the event
+ /// Event arguments containing the signal information
protected void Eisc_SigChange(object currentDevice, SigEventArgs args)
{
try
{
- Debug.LogMessage(LogEventLevel.Verbose, this, "EiscApiAdvanced change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
- var uo = args.Sig.UserObject;
+ this.LogVerbose("EiscApiAdvanced change: {type} {number}={value}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
+ var userObject = args.Sig.UserObject;
- if (uo == null) return;
+ if (userObject == null) return;
- Debug.LogMessage(LogEventLevel.Debug, this, "Executing Action: {0}", uo.ToString());
- if (uo is Action)
- (uo as Action)(args.Sig.BoolValue);
- else if (uo is Action)
- (uo as Action)(args.Sig.UShortValue);
- else if (uo is Action)
- (uo as Action)(args.Sig.StringValue);
+
+ if (userObject is Action)
+ {
+ this.LogDebug("Executing Boolean Action");
+ (userObject as Action)(args.Sig.BoolValue);
+ }
+ else if (userObject is Action)
+ {
+ this.LogDebug("Executing Analog Action");
+ (userObject as Action)(args.Sig.UShortValue);
+ }
+ else if (userObject is Action)
+ {
+ this.LogDebug("Executing Serial Action");
+ (userObject as Action)(args.Sig.StringValue);
+ }
}
catch (Exception e)
{
- Debug.LogMessage(LogEventLevel.Verbose, this, "Error in Eisc_SigChange handler: {0}", e);
+ this.LogError("Eisc_SigChange handler error: {message}", e.Message);
+ this.LogDebug(e, "Stack Trace: ");
}
}
@@ -423,22 +431,33 @@ namespace PepperDash.Essentials.Core.Bridges
}
///
- /// Represents a EiscApiAdvancedFactory
+ /// Factory class for EiscApiAdvanced devices
///
+ ///
+ /// Supported types:
+ /// eiscapiadv - Create a standard EISC client over TCP/IP
+ /// eiscapiadvanced - Create a standard EISC client over TCP/IP
+ /// eiscapiadvancedserver - Create an EISC server
+ /// eiscapiadvancedclient - Create an EISC client
+ /// vceiscapiadv - Create a VC-4 EISC client
+ /// vceiscapiadvanced - Create a VC-4 EISC client
+ /// eiscapiadvudp - Create a standard EISC client over UDP
+ /// eiscapiadvancedudp - Create a standard EISC client over UDP
+ ///
public class EiscApiAdvancedFactory : EssentialsDeviceFactory
{
+ ///
+ /// Constructor
+ ///
public EiscApiAdvancedFactory()
{
- TypeNames = new List { "eiscapiadv", "eiscapiadvanced", "eiscapiadvancedserver", "eiscapiadvancedclient", "vceiscapiadv", "vceiscapiadvanced" };
+ TypeNames = new List { "eiscapiadv", "eiscapiadvanced", "eiscapiadvancedserver", "eiscapiadvancedclient", "vceiscapiadv", "vceiscapiadvanced", "eiscapiadvudp", "eiscapiadvancedudp" };
}
- ///
- /// BuildDevice method
- ///
///
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
- Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new EiscApiAdvanced Device");
+ Debug.LogDebug("Attempting to create new EiscApiAdvanced Device");
var controlProperties = CommFactory.GetControlPropertiesConfig(dc);
@@ -446,6 +465,13 @@ namespace PepperDash.Essentials.Core.Bridges
switch (dc.Type.ToLower())
{
+ case "eiscapiadvudp":
+ case "eiscapiadvancedudp":
+ {
+ eisc = new EthernetIntersystemCommunications(controlProperties.IpIdInt,
+ controlProperties.TcpSshProperties.Address, Global.ControlSystem);
+ break;
+ }
case "eiscapiadv":
case "eiscapiadvanced":
{
@@ -468,7 +494,7 @@ namespace PepperDash.Essentials.Core.Bridges
{
if (string.IsNullOrEmpty(controlProperties.RoomId))
{
- Debug.LogMessage(LogEventLevel.Information, "Unable to build VC-4 EISC Client for device {0}. Room ID is missing or empty", dc.Key);
+ Debug.LogInformation("Unable to build VC-4 EISC Client for device {deviceKey}. Room ID is missing or empty", dc.Key);
eisc = null;
break;
}
diff --git a/src/PepperDash.Essentials.Core/Routing/Extensions.cs b/src/PepperDash.Essentials.Core/Routing/Extensions.cs
index 17f1e50d..5d09176f 100644
--- a/src/PepperDash.Essentials.Core/Routing/Extensions.cs
+++ b/src/PepperDash.Essentials.Core/Routing/Extensions.cs
@@ -1,11 +1,11 @@
-using Crestron.SimplSharpPro.Keypads;
-using PepperDash.Essentials.Core.Queues;
-using PepperDash.Essentials.Core.Routing;
-using Serilog.Events;
-using System;
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
+using Crestron.SimplSharpPro.Keypads;
+using PepperDash.Essentials.Core.Queues;
+using PepperDash.Essentials.Core.Routing;
+using Serilog.Events;
using Debug = PepperDash.Core.Debug;
@@ -115,7 +115,7 @@ namespace PepperDash.Essentials.Core
public static (RouteDescriptor, RouteDescriptor) GetRouteToSource(this IRoutingInputs destination, IRoutingOutputs source, eRoutingSignalType signalType, RoutingInputPort destinationPort, RoutingOutputPort sourcePort)
{
// if it's a single signal type, find the route
- if (!signalType.HasFlag(eRoutingSignalType.AudioVideo) &&
+ if (!signalType.HasFlag(eRoutingSignalType.AudioVideo) &&
!(signalType.HasFlag(eRoutingSignalType.Video) && signalType.HasFlag(eRoutingSignalType.SecondaryAudio)))
{
var singleTypeRouteDescriptor = new RouteDescriptor(source, destination, destinationPort, signalType);
@@ -134,14 +134,15 @@ namespace PepperDash.Essentials.Core
}
// otherwise, audioVideo needs to be handled as two steps.
- Debug.LogMessage(LogEventLevel.Debug, "Attempting to build source route from {sourceKey} of type {type}", destination, source.Key);
+ Debug.LogMessage(LogEventLevel.Debug, "Attempting to build source route from {destinationKey} to {sourceKey} of type {type}", destination, source.Key, signalType);
RouteDescriptor audioRouteDescriptor;
if (signalType.HasFlag(eRoutingSignalType.SecondaryAudio))
{
audioRouteDescriptor = new RouteDescriptor(source, destination, destinationPort, eRoutingSignalType.SecondaryAudio);
- } else
+ }
+ else
{
audioRouteDescriptor = new RouteDescriptor(source, destination, destinationPort, eRoutingSignalType.Audio);
}
@@ -199,13 +200,13 @@ namespace PepperDash.Essentials.Core
Source = source,
SourcePort = sourcePort,
SignalType = signalType
- };
+ };
var coolingDevice = destination as IWarmingCooling;
//We already have a route request for this device, and it's a cooling device and is cooling
if (RouteRequests.TryGetValue(destination.Key, out RouteRequest existingRouteRequest) && coolingDevice != null && coolingDevice.IsCoolingDownFeedback.BoolValue == true)
- {
+ {
coolingDevice.IsCoolingDownFeedback.OutputChange -= existingRouteRequest.HandleCooldown;
coolingDevice.IsCoolingDownFeedback.OutputChange += routeRequest.HandleCooldown;
@@ -219,7 +220,7 @@ namespace PepperDash.Essentials.Core
//New Request
if (coolingDevice != null && coolingDevice.IsCoolingDownFeedback.BoolValue == true)
- {
+ {
coolingDevice.IsCoolingDownFeedback.OutputChange += routeRequest.HandleCooldown;
RouteRequests.Add(destination.Key, routeRequest);
@@ -239,9 +240,9 @@ namespace PepperDash.Essentials.Core
Debug.LogMessage(LogEventLevel.Information, "Device: {destination} is NOT cooling down. Removing stored route request and routing to source key: {sourceKey}", null, destination.Key, routeRequest.Source.Key);
}
- routeRequestQueue.Enqueue(new ReleaseRouteQueueItem(ReleaseRouteInternal, destination,destinationPort?.Key ?? string.Empty, false));
+ routeRequestQueue.Enqueue(new ReleaseRouteQueueItem(ReleaseRouteInternal, destination, destinationPort?.Key ?? string.Empty, false));
- routeRequestQueue.Enqueue(new RouteRequestQueueItem(RunRouteRequest, routeRequest));
+ routeRequestQueue.Enqueue(new RouteRequestQueueItem(RunRouteRequest, routeRequest));
}
///
@@ -272,7 +273,8 @@ namespace PepperDash.Essentials.Core
audioOrSingleRoute.ExecuteRoutes();
videoRoute?.ExecuteRoutes();
- } catch(Exception ex)
+ }
+ catch (Exception ex)
{
Debug.LogMessage(ex, "Exception Running Route Request {request}", null, request);
}
@@ -305,9 +307,10 @@ namespace PepperDash.Essentials.Core
Debug.LogMessage(LogEventLevel.Information, "Releasing current route: {0}", destination, current.Source.Key);
current.ReleaseRoutes(clearRoute);
}
- } catch (Exception ex)
+ }
+ catch (Exception ex)
{
- Debug.LogMessage(ex, "Exception releasing route for '{destination}':'{inputPortKey}'",null, destination?.Key ?? null, string.IsNullOrEmpty(inputPortKey) ? "auto" : inputPortKey);
+ Debug.LogMessage(ex, "Exception releasing route for '{destination}':'{inputPortKey}'", null, destination?.Key ?? null, string.IsNullOrEmpty(inputPortKey) ? "auto" : inputPortKey);
}
}
diff --git a/src/PepperDash.Essentials.Devices.Common/Generic/GenericSink.cs b/src/PepperDash.Essentials.Devices.Common/Generic/GenericSink.cs
index 8f2fc1e2..64617770 100644
--- a/src/PepperDash.Essentials.Devices.Common/Generic/GenericSink.cs
+++ b/src/PepperDash.Essentials.Devices.Common/Generic/GenericSink.cs
@@ -1,8 +1,10 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
+using PepperDash.Essentials.Core.Routing;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common.Generic
@@ -10,8 +12,17 @@ namespace PepperDash.Essentials.Devices.Common.Generic
///
/// Represents a GenericSink
///
- public class GenericSink : EssentialsDevice, IRoutingSinkWithSwitchingWithInputPort
+ public class GenericSink : EssentialsDevice, IRoutingSinkWithSwitchingWithInputPort, ICurrentSources
{
+ ///
+ public Dictionary CurrentSources { get; private set; }
+
+ ///
+ public Dictionary CurrentSourceKeys { get; private set; }
+
+ ///
+ public event EventHandler CurrentSourcesChanged;
+
///
/// Initializes a new instance of the GenericSink class
///
@@ -24,6 +35,49 @@ namespace PepperDash.Essentials.Devices.Common.Generic
var inputPort = new RoutingInputPort(RoutingPortNames.AnyVideoIn, eRoutingSignalType.AudioVideo | eRoutingSignalType.SecondaryAudio, eRoutingPortConnectionType.Hdmi, null, this);
InputPorts.Add(inputPort);
+
+ CurrentSources = new Dictionary
+ {
+ { eRoutingSignalType.Audio, null },
+ { eRoutingSignalType.Video, null },
+ };
+
+ CurrentSourceKeys = new Dictionary
+ {
+ { eRoutingSignalType.Audio, string.Empty },
+ { eRoutingSignalType.Video, string.Empty },
+ };
+ }
+
+ ///
+ public void SetCurrentSource(eRoutingSignalType signalType, string sourceListKey, SourceListItem sourceListItem)
+ {
+ foreach (eRoutingSignalType type in Enum.GetValues(typeof(eRoutingSignalType)))
+ {
+ var flagValue = Convert.ToInt32(type);
+ // Skip if flagValue is 0 or not a power of two (i.e., not a single-bit flag).
+ // (flagValue & (flagValue - 1)) != 0 checks if more than one bit is set.
+ if (flagValue == 0 || (flagValue & (flagValue - 1)) != 0)
+ {
+ this.LogDebug("Skipping {type}", type);
+ continue;
+ }
+
+ this.LogDebug("setting {type}", type);
+
+ if (signalType.HasFlag(type))
+ {
+ UpdateCurrentSources(type, sourceListKey, sourceListItem);
+ }
+ }
+ // Raise the CurrentSourcesChanged event
+ CurrentSourcesChanged?.Invoke(this, EventArgs.Empty);
+ }
+
+ private void UpdateCurrentSources(eRoutingSignalType signalType, string sourceListKey, SourceListItem sourceListItem)
+ {
+ CurrentSources[signalType] = sourceListItem;
+ CurrentSourceKeys[signalType] = sourceListKey;
}
///
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CurrentSourcesMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CurrentSourcesMessenger.cs
index 9643a607..a7c4614b 100644
--- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CurrentSourcesMessenger.cs
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CurrentSourcesMessenger.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
@@ -39,10 +40,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
sourceDevice.CurrentSourcesChanged += (sender, e) =>
{
+ // need to copy the dictionaries to avoid enumeration issues
+ var currentSourceKeys = sourceDevice.CurrentSourceKeys.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
+ var currentSources = sourceDevice.CurrentSources.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
+
PostStatusMessage(JToken.FromObject(new
{
- currentSourceKeys = sourceDevice.CurrentSourceKeys,
- currentSources = sourceDevice.CurrentSources
+ currentSourceKeys,
+ currentSources,
}));
};
}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/DeviceVolumeMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/DeviceVolumeMessenger.cs
index fba7c643..80042352 100644
--- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/DeviceVolumeMessenger.cs
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/DeviceVolumeMessenger.cs
@@ -130,34 +130,33 @@ namespace PepperDash.Essentials.AppServer.Messengers
feedback.MuteFeedback.OutputChange += (sender, args) =>
{
- PostStatusMessage(JToken.FromObject(
- new
- {
- volume = new
- {
- muted = args.BoolValue
- }
- })
- );
+ var message = new VolumeStateMessage
+ {
+ Volume = new Volume
+ {
+ Muted = args.BoolValue
+ }
+ };
+
+ PostStatusMessage(JToken.FromObject(message));
};
feedback.VolumeLevelFeedback.OutputChange += (sender, args) =>
{
- var rawValue = "";
- if (feedback is IBasicVolumeWithFeedbackAdvanced volumeAdvanced)
+ var message = new VolumeStateMessage
{
- rawValue = volumeAdvanced.RawVolumeLevel.ToString();
- }
-
- var message = new
- {
- volume = new
+ Volume = new Volume
{
- level = args.IntValue,
- rawValue
+ Level = args.IntValue,
}
};
+ if (device is IBasicVolumeWithFeedbackAdvanced volumeAdvanced)
+ {
+ message.Volume.RawValue = volumeAdvanced.RawVolumeLevel.ToString();
+ message.Volume.Units = volumeAdvanced.Units;
+ }
+
PostStatusMessage(JToken.FromObject(message));
};
}