From 5afdc2effad5d0e9cbf8e2f2857fff544cba26af Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 24 May 2024 16:11:20 -0500 Subject: [PATCH 1/4] fix: remove Crestron.SimplSharp.Reflection Ran into some odd exceptions loading on a VC-4 instance, and changing to System.Reflection solved them. --- .../Factory/DeviceFactory.cs | 19 ++------- .../ProcessorExtensionDeviceFactory.cs | 4 +- .../Plugins/PluginLoader.cs | 39 +++++++++++-------- .../DeviceFactory.cs | 2 +- .../Factory/DeviceFactory.cs | 2 +- 5 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/PepperDash.Essentials.Core/Factory/DeviceFactory.cs b/src/PepperDash.Essentials.Core/Factory/DeviceFactory.cs index 65b410e6..f4ce92a0 100644 --- a/src/PepperDash.Essentials.Core/Factory/DeviceFactory.cs +++ b/src/PepperDash.Essentials.Core/Factory/DeviceFactory.cs @@ -1,7 +1,7 @@  using Crestron.SimplSharp; -using Crestron.SimplSharp.Reflection; +using System.Reflection; using Newtonsoft.Json.Linq; using PepperDash.Core; using PepperDash.Essentials.Core.Config; @@ -14,7 +14,7 @@ namespace PepperDash.Essentials.Core { public class DeviceFactoryWrapper { - public CType CType { get; set; } + public Type CType { get; set; } public string Description { get; set; } public Func FactoryMethod { get; set; } @@ -69,7 +69,7 @@ namespace PepperDash.Essentials.Core DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method}); } - public static void AddFactoryForType(string typeName, string description, CType cType, Func method) + public static void AddFactoryForType(string typeName, string description, Type cType, Func method) { //Debug.LogMessage(LogEventLevel.Debug, "Adding factory method for type '{0}'", typeName); @@ -149,18 +149,7 @@ namespace PepperDash.Essentials.Core } catch (Exception ex) { - Debug.LogMessage(LogEventLevel.Error, "Exception occurred while creating device {0}: {1}", dc.Key, ex.Message); - - Debug.LogMessage(LogEventLevel.Verbose, "{0}", ex.StackTrace); - - if (ex.InnerException == null) - { - return null; - } - - Debug.LogMessage(LogEventLevel.Error, "Inner exception while creating device {0}: {1}", dc.Key, - ex.InnerException.Message); - Debug.LogMessage(LogEventLevel.Verbose, "{0}", ex.InnerException.StackTrace); + Debug.LogMessage(ex, "Exception occurred while creating device {0}: {1}", null, dc.Key, ex.Message); return null; } } diff --git a/src/PepperDash.Essentials.Core/Factory/ProcessorExtensionDeviceFactory.cs b/src/PepperDash.Essentials.Core/Factory/ProcessorExtensionDeviceFactory.cs index 68f5dc1f..95e0fb76 100644 --- a/src/PepperDash.Essentials.Core/Factory/ProcessorExtensionDeviceFactory.cs +++ b/src/PepperDash.Essentials.Core/Factory/ProcessorExtensionDeviceFactory.cs @@ -1,5 +1,5 @@  -using Crestron.SimplSharp.Reflection; +using System.Reflection; using PepperDash.Core; using PepperDash.Essentials.Core.Config; using Serilog.Events; @@ -55,7 +55,7 @@ namespace PepperDash.Essentials.Core ProcessorExtensionDeviceFactory.ProcessorExtensionFactoryMethods.Add(extensionName, new DeviceFactoryWrapper() { FactoryMethod = method }); } - public static void AddFactoryForType(string extensionName, string description, CType cType, Func method) + public static void AddFactoryForType(string extensionName, string description, Type cType, Func method) { //Debug.LogMessage(LogEventLevel.Debug, "Adding factory method for type '{0}'", typeName); diff --git a/src/PepperDash.Essentials.Core/Plugins/PluginLoader.cs b/src/PepperDash.Essentials.Core/Plugins/PluginLoader.cs index 022bfd2f..aebd2d22 100644 --- a/src/PepperDash.Essentials.Core/Plugins/PluginLoader.cs +++ b/src/PepperDash.Essentials.Core/Plugins/PluginLoader.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronIO; -using Crestron.SimplSharp.Reflection; +using System.Reflection; using PepperDash.Core; using PepperDash.Essentials.Core; @@ -119,24 +119,31 @@ namespace PepperDash.Essentials /// static LoadedAssembly LoadAssembly(string filePath) { - //Debug.LogMessage(LogEventLevel.Verbose, "Attempting to load {0}", filePath); - var assembly = Assembly.LoadFrom(filePath); - if (assembly != null) + try { - var assyVersion = GetAssemblyVersion(assembly); + //Debug.LogMessage(LogEventLevel.Verbose, "Attempting to load {0}", filePath); + var assembly = Assembly.LoadFrom(filePath); + if (assembly != null) + { + var assyVersion = GetAssemblyVersion(assembly); - var loadedAssembly = new LoadedAssembly(assembly.GetName().Name, assyVersion, assembly); - LoadedAssemblies.Add(loadedAssembly); - Debug.LogMessage(LogEventLevel.Information, "Loaded assembly '{0}', version {1}", loadedAssembly.Name, loadedAssembly.Version); - return loadedAssembly; - } - else + var loadedAssembly = new LoadedAssembly(assembly.GetName().Name, assyVersion, assembly); + LoadedAssemblies.Add(loadedAssembly); + Debug.LogMessage(LogEventLevel.Information, "Loaded assembly '{0}', version {1}", loadedAssembly.Name, loadedAssembly.Version); + return loadedAssembly; + } + else + { + Debug.LogMessage(LogEventLevel.Information, "Unable to load assembly: '{0}'", filePath); + } + + return null; + } catch(Exception ex) { - Debug.LogMessage(LogEventLevel.Information, "Unable to load assembly: '{0}'", filePath); + Debug.LogMessage(ex, "Error loading assembly from {path}", null, filePath); + return null; } - return null; - } /// @@ -354,7 +361,7 @@ namespace PepperDash.Essentials try { var assy = loadedAssembly.Assembly; - CType[] types = {}; + Type[] types = {}; try { types = assy.GetTypes(); @@ -439,7 +446,7 @@ namespace PepperDash.Essentials /// /// /// - static void LoadCustomLegacyPlugin(CType type, MethodInfo loadPlugin, LoadedAssembly loadedAssembly) + static void LoadCustomLegacyPlugin(Type type, MethodInfo loadPlugin, LoadedAssembly loadedAssembly) { Debug.LogMessage(LogEventLevel.Verbose, "LoadPlugin method found in {0}", type.Name); diff --git a/src/PepperDash.Essentials.Devices.Common/DeviceFactory.cs b/src/PepperDash.Essentials.Devices.Common/DeviceFactory.cs index bd8cf92f..fdb583dc 100644 --- a/src/PepperDash.Essentials.Devices.Common/DeviceFactory.cs +++ b/src/PepperDash.Essentials.Devices.Common/DeviceFactory.cs @@ -2,7 +2,7 @@ using System; using System.Linq; -using Crestron.SimplSharp.Reflection; +using System.Reflection; using PepperDash.Core; using PepperDash.Essentials.Core; using Serilog.Events; diff --git a/src/PepperDash.Essentials/Factory/DeviceFactory.cs b/src/PepperDash.Essentials/Factory/DeviceFactory.cs index 73063e30..c68f0520 100644 --- a/src/PepperDash.Essentials/Factory/DeviceFactory.cs +++ b/src/PepperDash.Essentials/Factory/DeviceFactory.cs @@ -6,7 +6,7 @@ using System.Linq; using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharpPro; -using Crestron.SimplSharp.Reflection; +using System.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Linq; From effefc939cbda9c5487cfe458316b71846bb609e Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 24 May 2024 16:12:50 -0500 Subject: [PATCH 2/4] fix: minor Web API enhancements * changed path for DevJson to include the device key instead of requiring it in the body * Made the `GetRequestBody` method an extension method for the `HttpCwsRequest` class --- .../Web/EssentialsWebApi.cs | 2 +- .../Web/EssentialsWebApiHelpers.cs | 12 +++---- .../RequestHandlers/AppDebugRequestHandler.cs | 2 +- .../RequestHandlers/DevJsonRequestHandler.cs | 34 ++++++++++++++++--- .../RequestHandlers/DevListRequestHandler.cs | 2 +- ...DoNotLoadConfigOnNextBootRequestHandler.cs | 2 +- .../SetDeviceStreamDebugRequestHandler.cs | 2 +- 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/PepperDash.Essentials.Core/Web/EssentialsWebApi.cs b/src/PepperDash.Essentials.Core/Web/EssentialsWebApi.cs index 0ce6b209..a37a78c0 100644 --- a/src/PepperDash.Essentials.Core/Web/EssentialsWebApi.cs +++ b/src/PepperDash.Essentials.Core/Web/EssentialsWebApi.cs @@ -89,7 +89,7 @@ namespace PepperDash.Essentials.Core.Web Name = "DevList", RouteHandler = new DevListRequestHandler() }, - new HttpCwsRoute("deviceCommands") + new HttpCwsRoute("deviceCommands/{deviceKey}") { Name = "DevJson", RouteHandler = new DevJsonRequestHandler() diff --git a/src/PepperDash.Essentials.Core/Web/EssentialsWebApiHelpers.cs b/src/PepperDash.Essentials.Core/Web/EssentialsWebApiHelpers.cs index 89718fcf..cc6d4cd6 100644 --- a/src/PepperDash.Essentials.Core/Web/EssentialsWebApiHelpers.cs +++ b/src/PepperDash.Essentials.Core/Web/EssentialsWebApiHelpers.cs @@ -7,11 +7,11 @@ using PepperDash.Core; namespace PepperDash.Essentials.Core.Web { - public class EssentialsWebApiHelpers + public static class EssentialsWebApiHelpers { - public static string GetRequestBody(HttpCwsRequest request) + public static string GetRequestBody(this HttpCwsRequest request) { - var bytes = new Byte[request.ContentLength]; + var bytes = new byte[request.ContentLength]; request.InputStream.Read(bytes, 0, request.ContentLength); @@ -22,8 +22,8 @@ namespace PepperDash.Essentials.Core.Web { return new { - Name = assembly.Name, - Version = assembly.Version + assembly.Name, + assembly.Version }; } @@ -31,7 +31,7 @@ namespace PepperDash.Essentials.Core.Web { return new { - Key = device.Key, + device.Key, Name = (device is IKeyName) ? (device as IKeyName).Name : "---" diff --git a/src/PepperDash.Essentials.Core/Web/RequestHandlers/AppDebugRequestHandler.cs b/src/PepperDash.Essentials.Core/Web/RequestHandlers/AppDebugRequestHandler.cs index 1157c5e1..0b7497d2 100644 --- a/src/PepperDash.Essentials.Core/Web/RequestHandlers/AppDebugRequestHandler.cs +++ b/src/PepperDash.Essentials.Core/Web/RequestHandlers/AppDebugRequestHandler.cs @@ -52,7 +52,7 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers return; } - var data = EssentialsWebApiHelpers.GetRequestBody(context.Request); + var data = context.Request.GetRequestBody(); if (string.IsNullOrEmpty(data)) { context.Response.StatusCode = 400; diff --git a/src/PepperDash.Essentials.Core/Web/RequestHandlers/DevJsonRequestHandler.cs b/src/PepperDash.Essentials.Core/Web/RequestHandlers/DevJsonRequestHandler.cs index 3599eb23..d14ffb83 100644 --- a/src/PepperDash.Essentials.Core/Web/RequestHandlers/DevJsonRequestHandler.cs +++ b/src/PepperDash.Essentials.Core/Web/RequestHandlers/DevJsonRequestHandler.cs @@ -26,6 +26,26 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers /// protected override void HandlePost(HttpCwsContext context) { + var routeData = context.Request.RouteData; + + if(routeData == null) + { + context.Response.StatusCode = 400; + context.Response.StatusDescription = "Bad Request"; + context.Response.End(); + + return; + } + + if(!routeData.Values.TryGetValue("deviceKey", out var deviceKey)) + { + context.Response.StatusCode = 400; + context.Response.StatusDescription = "Bad Request"; + context.Response.End(); + + return; + } + if (context.Request.ContentLength < 0) { context.Response.StatusCode = 400; @@ -35,7 +55,8 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers return; } - var data = EssentialsWebApiHelpers.GetRequestBody(context.Request); + var data = context.Request.GetRequestBody(); + if (string.IsNullOrEmpty(data)) { context.Response.StatusCode = 400; @@ -46,9 +67,14 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers } try - { - var daw = JsonConvert.DeserializeObject(data); - DeviceJsonApi.DoDeviceActionWithJson(data); + { + var daw = new DeviceActionWrapper { DeviceKey = (string) deviceKey}; + + JsonConvert.PopulateObject(data, daw); + + Debug.LogMessage(LogEventLevel.Verbose, "Device Action Wrapper: {@wrapper}", null, daw); + + DeviceJsonApi.DoDeviceAction(daw); context.Response.StatusCode = 200; context.Response.StatusDescription = "OK"; diff --git a/src/PepperDash.Essentials.Core/Web/RequestHandlers/DevListRequestHandler.cs b/src/PepperDash.Essentials.Core/Web/RequestHandlers/DevListRequestHandler.cs index e9df4347..a83685fb 100644 --- a/src/PepperDash.Essentials.Core/Web/RequestHandlers/DevListRequestHandler.cs +++ b/src/PepperDash.Essentials.Core/Web/RequestHandlers/DevListRequestHandler.cs @@ -34,7 +34,7 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers return; } - allDevices.Sort((a, b) => System.String.Compare(a.Key, b.Key, System.StringComparison.Ordinal)); + allDevices.Sort((a, b) => string.Compare(a.Key, b.Key, System.StringComparison.Ordinal)); var deviceList = allDevices.Select(d => EssentialsWebApiHelpers.MapToDeviceListObject(d)).ToList(); diff --git a/src/PepperDash.Essentials.Core/Web/RequestHandlers/DoNotLoadConfigOnNextBootRequestHandler.cs b/src/PepperDash.Essentials.Core/Web/RequestHandlers/DoNotLoadConfigOnNextBootRequestHandler.cs index 4ec3bc97..fdcad73c 100644 --- a/src/PepperDash.Essentials.Core/Web/RequestHandlers/DoNotLoadConfigOnNextBootRequestHandler.cs +++ b/src/PepperDash.Essentials.Core/Web/RequestHandlers/DoNotLoadConfigOnNextBootRequestHandler.cs @@ -52,7 +52,7 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers return; } - var data = EssentialsWebApiHelpers.GetRequestBody(context.Request); + var data = context.Request.GetRequestBody(); if (string.IsNullOrEmpty(data)) { context.Response.StatusCode = 400; diff --git a/src/PepperDash.Essentials.Core/Web/RequestHandlers/SetDeviceStreamDebugRequestHandler.cs b/src/PepperDash.Essentials.Core/Web/RequestHandlers/SetDeviceStreamDebugRequestHandler.cs index a08fda2b..6378f1b2 100644 --- a/src/PepperDash.Essentials.Core/Web/RequestHandlers/SetDeviceStreamDebugRequestHandler.cs +++ b/src/PepperDash.Essentials.Core/Web/RequestHandlers/SetDeviceStreamDebugRequestHandler.cs @@ -89,7 +89,7 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers return; } - var data = EssentialsWebApiHelpers.GetRequestBody(context.Request); + var data = context.Request.GetRequestBody(); if (data == null) { context.Response.StatusCode = 500; From 35e0662b27a52755d4a75e5e5d323212fe1e9632 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 24 May 2024 16:13:21 -0500 Subject: [PATCH 3/4] fix: only update CurrentInputPort if it has changed --- .../Displays/DisplayBase.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs b/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs index 541ef80a..9796599b 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs @@ -29,6 +29,8 @@ namespace PepperDash.Essentials.Devices.Common.Displays protected set { + if (_currentInputPort == value) return; + _currentInputPort = value; InputChanged?.Invoke(this, _currentInputPort); From f630d3f4100e68d33e879a5f3fedb65c91fc0eac Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 24 May 2024 16:13:35 -0500 Subject: [PATCH 4/4] fix: add missing interfaces --- .../Displays/MockDisplay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs b/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs index f281992a..ea7f3a5b 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs @@ -12,7 +12,7 @@ using Serilog.Events; namespace PepperDash.Essentials.Devices.Common.Displays { - public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, IBridgeAdvanced, IHasInputs + public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, IBridgeAdvanced, IHasInputs, IRoutingSinkWithSwitchingWithInputPort, IHasPowerControlWithFeedback { public ISelectableItems Inputs { get; private set; } @@ -79,7 +79,7 @@ namespace PepperDash.Essentials.Devices.Common.Displays eRoutingPortConnectionType.Hdmi, "HDMI2", this); var hdmiIn3 = new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, "HDMI3", this); - var hdmiIn4 = new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.AudioVideo, + var hdmiIn4 = new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, "HDMI4", this); var dpIn = new RoutingInputPort(RoutingPortNames.DisplayPortIn, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.DisplayPort, "DP", this);