Compare commits

...

28 Commits

Author SHA1 Message Date
Nick Genovese
1e8591b3e0 fix: update Crestron.SimplSharp.SDK.Library and ProgramLibrary versions to 2.21.133 2025-08-08 13:21:35 -04:00
Andrew Welker
bb4b2f88b6 Merge pull request #1304 from PepperDash/temp-to-dev
Temp to dev
2025-08-05 16:39:38 -05:00
Andrew Welker
88466818ce Merge pull request #1303 from PepperDash/debug-fixes
fix: use correct overload for logging at levels
2025-07-31 13:03:14 -05:00
Andrew Welker
0871a902e1 fix: use correct overload for logging at levels
Some overloads that had the first argument as an Exception were calling the _logger.Write method with a null where the message template should have been, causing messages logged with that overload to be swallowed and not logged.
2025-07-31 12:50:41 -05:00
aknous
2efab4f196 Merge pull request #1301 from PepperDash/mc-tp-ip-fix
fix: only adjust IP if processor is a CS processor
2025-07-28 12:57:24 -04:00
Andrew Welker
a41aba1904 Merge pull request #1300 from PepperDash/temp-to-dev
Temp to dev
2025-07-28 11:54:11 -05:00
Andrew Welker
d0ca6721f5 fix: only adjust IP if processor is a CS processor 2025-07-28 11:48:00 -05:00
Andrew Welker
c732eb48f2 Merge pull request #1299 from PepperDash/factory-updates
Multiple Updates
2025-07-25 10:38:15 -05:00
Andrew Welker
efe70208d3 fix: check for null assembly name 2025-07-25 10:32:43 -05:00
Andrew Welker
615f640ebb fix: use continue instead of return
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-25 10:27:50 -05:00
Andrew Welker
ee6f9416a3 chore: remove unused configSnippet 2025-07-25 10:24:32 -05:00
Andrew Welker
4fc6ecbd0b style: switch to auto property for attributes 2025-07-25 09:56:39 -05:00
Neil Dorin
b47f1d6b77 Merge pull request #1293 from PepperDash/to-dev 2025-07-23 07:53:44 -06:00
Andrew Welker
fda4a5a816 Merge pull request #1282 from PepperDash/main
Update Dev
2025-07-04 10:45:35 -05:00
Andrew Welker
9f70e3c721 Merge pull request #1276 from PepperDash/temp-to-dev
Temp to dev
2025-06-26 14:16:36 -04:00
Andrew Welker
ec6aeb17f6 Merge pull request #1271 from PepperDash/temp-to-dev
Temp to dev
2025-05-19 16:52:45 -05:00
Neil Dorin
91dc655103 Merge pull request #1269 from PepperDash/camera-preset-fix 2025-05-14 09:42:11 -06:00
Andrew Welker
bf31fb10eb fix: use correct join for preset select 2025-05-14 10:39:42 -05:00
Neil Dorin
5e21bad596 Merge pull request #1266 from PepperDash/temp-to-dev 2025-05-02 12:23:51 -06:00
Neil Dorin
2368f0c8cc Merge pull request #1262 from PepperDash/temp-to-dev 2025-04-28 11:37:01 -06:00
Neil Dorin
be58a0bc29 Merge pull request #1260 from PepperDash/temp-to-dev 2025-04-24 09:32:32 -06:00
Neil Dorin
8406f69e0d Merge pull request #1257 from PepperDash/temp-to-dev 2025-04-18 11:46:18 -06:00
Andrew Welker
116d83394a Merge pull request #1255 from PepperDash/temp-to-dev
Temp to dev
2025-04-14 11:15:27 -05:00
Neil Dorin
9b8e452eb4 Merge pull request #1251 from PepperDash/temp-to-dev 2025-04-11 14:00:02 -06:00
Neil Dorin
c9d86bd5dd Merge pull request #1248 from PepperDash/temp-to-dev 2025-04-11 11:55:35 -06:00
Neil Dorin
b2b257020f Merge pull request #1246 from PepperDash/temp-to-dev 2025-04-08 13:48:10 -06:00
Neil Dorin
6f58e18d14 Merge pull request #1244 from PepperDash/temp-to-dev
Temp to dev
2025-04-04 10:30:10 -06:00
Neil Dorin
60fc0298ec Merge pull request #1242 from PepperDash/temp-to-dev
Temp to dev
2025-04-02 11:14:45 -06:00
14 changed files with 186 additions and 237 deletions

View File

@@ -1,4 +1,8 @@
using Crestron.SimplSharp;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronDataStore;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.CrestronLogger;
@@ -11,10 +15,6 @@ using Serilog.Events;
using Serilog.Formatting.Compact;
using Serilog.Formatting.Json;
using Serilog.Templates;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;
namespace PepperDash.Core
{
@@ -48,6 +48,9 @@ namespace PepperDash.Core
private static readonly LoggingLevelSwitch _fileLevelSwitch;
/// <summary>
/// Gets the minimum log level for the websocket sink.
/// </summary>
public static LogEventLevel WebsocketMinimumLogLevel
{
get { return _websocketLoggingLevelSwitch.MinimumLevel; }
@@ -55,6 +58,9 @@ namespace PepperDash.Core
private static readonly DebugWebsocketSink _websocketSink;
/// <summary>
/// Gets the websocket sink for debug logging.
/// </summary>
public static DebugWebsocketSink WebsocketSink
{
get { return _websocketSink; }
@@ -91,29 +97,33 @@ namespace PepperDash.Core
private const int SaveTimeoutMs = 30000;
/// <summary>
/// Indicates whether the system is running on an appliance.
/// </summary>
public static bool IsRunningOnAppliance = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance;
/// <summary>
/// Gets or sets the PepperDashCoreVersion
/// </summary>
public static string PepperDashCoreVersion { get; private set; }
public static string PepperDashCoreVersion { get; private set; }
private static CTimer _saveTimer;
/// <summary>
/// When true, the IncludedExcludedKeys dict will contain keys to include.
/// When false (default), IncludedExcludedKeys will contain keys to exclude.
/// </summary>
private static bool _excludeAllMode;
/// <summary>
/// When true, the IncludedExcludedKeys dict will contain keys to include.
/// When false (default), IncludedExcludedKeys will contain keys to exclude.
/// </summary>
private static bool _excludeAllMode;
//static bool ExcludeNoKeyMessages;
private static readonly Dictionary<string, object> IncludedExcludedKeys;
private static readonly Dictionary<string, object> IncludedExcludedKeys;
private static readonly LoggerConfiguration _defaultLoggerConfiguration;
private static LoggerConfiguration _loggerConfiguration;
/// <summary>
/// Gets the logger configuration for the debug logging.
/// </summary>
public static LoggerConfiguration LoggerConfiguration => _loggerConfiguration;
static Debug()
@@ -128,7 +138,7 @@ namespace PepperDash.Core
var defaultFileLogLevel = GetStoredLogEventLevel(FileLevelStoreKey);
_consoleLoggingLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultConsoleLevel);
_consoleLoggingLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultConsoleLevel);
_websocketLoggingLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultWebsocketLevel);
@@ -144,7 +154,7 @@ namespace PepperDash.Core
CrestronConsole.PrintLine($"Saving log files to {logFilePath}");
var errorLogTemplate = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance
var errorLogTemplate = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance
? "{@t:fff}ms [{@l:u4}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}"
: "[{@t:yyyy-MM-dd HH:mm:ss.fff}][{@l:u4}][{App}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}";
@@ -155,7 +165,7 @@ namespace PepperDash.Core
.WriteTo.Sink(new DebugConsoleSink(new ExpressionTemplate("[{@t:yyyy-MM-dd HH:mm:ss.fff}][{@l:u4}][{App}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}")), levelSwitch: _consoleLoggingLevelSwitch)
.WriteTo.Sink(_websocketSink, levelSwitch: _websocketLoggingLevelSwitch)
.WriteTo.Sink(new DebugErrorLogSink(new ExpressionTemplate(errorLogTemplate)), levelSwitch: _errorLogLevelSwitch)
.WriteTo.File(new RenderedCompactJsonFormatter(), logFilePath,
.WriteTo.File(new RenderedCompactJsonFormatter(), logFilePath,
rollingInterval: RollingInterval.Day,
restrictedToMinimumLevel: LogEventLevel.Debug,
retainedFileCountLimit: CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? 30 : 60,
@@ -193,27 +203,27 @@ namespace PepperDash.Core
CrestronConsole.PrintLine(msg);
LogMessage(LogEventLevel.Information,msg);
LogMessage(LogEventLevel.Information, msg);
IncludedExcludedKeys = new Dictionary<string, object>();
IncludedExcludedKeys = new Dictionary<string, object>();
if (CrestronEnvironment.RuntimeEnvironment == eRuntimeEnvironment.SimplSharpPro)
{
// Add command to console
CrestronConsole.AddNewConsoleCommand(SetDoNotLoadOnNextBootFromConsole, "donotloadonnextboot",
CrestronConsole.AddNewConsoleCommand(SetDoNotLoadOnNextBootFromConsole, "donotloadonnextboot",
"donotloadonnextboot:P [true/false]: Should the application load on next boot", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(SetDebugFromConsole, "appdebug",
"appdebug:P [0-5]: Sets the application's console debug message level",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ShowDebugLog, "appdebuglog",
"appdebuglog:P [all] Use \"all\" for full log.",
"appdebuglog:P [all] Use \"all\" for full log.",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => CrestronLogger.Clear(false), "appdebugclear",
"appdebugclear:P Clears the current custom log",
"appdebugclear:P Clears the current custom log",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(SetDebugFilterFromConsole, "appdebugfilter",
"appdebugfilter [params]", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(SetDebugFilterFromConsole, "appdebugfilter",
"appdebugfilter [params]", ConsoleAccessLevelEnum.AccessOperator);
}
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
@@ -224,7 +234,7 @@ namespace PepperDash.Core
Level = context.Level;
DoNotLoadConfigOnNextBoot = context.DoNotLoadOnNextBoot;
if(DoNotLoadConfigOnNextBoot)
if (DoNotLoadConfigOnNextBoot)
CrestronConsole.PrintLine(string.Format("Program {0} will not load config after next boot. Use console command go:{0} to load the config manually", InitialParametersClass.ApplicationNumber));
_consoleLoggingLevelSwitch.MinimumLevelChanged += (sender, args) =>
@@ -257,7 +267,7 @@ namespace PepperDash.Core
{
try
{
var result = CrestronDataStoreStatic.GetLocalIntValue(levelStoreKey, out int logLevel);
var result = CrestronDataStoreStatic.GetLocalIntValue(levelStoreKey, out int logLevel);
if (result != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
{
@@ -265,14 +275,15 @@ namespace PepperDash.Core
return LogEventLevel.Information;
}
if(logLevel < 0 || logLevel > 5)
if (logLevel < 0 || logLevel > 5)
{
CrestronConsole.PrintLine($"Stored Log level not valid for {levelStoreKey}: {logLevel}. Setting level to {LogEventLevel.Information}");
return LogEventLevel.Information;
}
return (LogEventLevel)logLevel;
} catch (Exception ex)
}
catch (Exception ex)
{
CrestronConsole.PrintLine($"Exception retrieving log level for {levelStoreKey}: {ex.Message}");
return LogEventLevel.Information;
@@ -284,7 +295,7 @@ namespace PepperDash.Core
var assembly = Assembly.GetExecutingAssembly();
var ver =
assembly
.GetCustomAttributes(typeof (AssemblyInformationalVersionAttribute), false);
.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false);
if (ver != null && ver.Length > 0)
{
@@ -351,25 +362,25 @@ namespace PepperDash.Core
return;
}
if(int.TryParse(levelString, out var levelInt))
if (int.TryParse(levelString, out var levelInt))
{
if(levelInt < 0 || levelInt > 5)
if (levelInt < 0 || levelInt > 5)
{
CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelString} to valid log level. If using a number, value must be between 0-5");
return;
}
SetDebugLevel((uint) levelInt);
SetDebugLevel((uint)levelInt);
return;
}
if(Enum.TryParse<LogEventLevel>(levelString, out var levelEnum))
if (Enum.TryParse<LogEventLevel>(levelString, out var levelEnum))
{
SetDebugLevel(levelEnum);
return;
}
CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelString} to valid log level");
}
}
catch
{
CrestronConsole.ConsoleCommandResponse("Usage: appdebug:P [0-5]");
@@ -385,7 +396,7 @@ namespace PepperDash.Core
/// </summary>
public static void SetDebugLevel(uint level)
{
if(!_logLevels.TryGetValue(level, out var logLevel))
if (!_logLevels.TryGetValue(level, out var logLevel))
{
logLevel = LogEventLevel.Information;
@@ -407,9 +418,9 @@ namespace PepperDash.Core
CrestronConsole.ConsoleCommandResponse("[Application {0}], Debug level set to {1}\r\n",
InitialParametersClass.ApplicationNumber, _consoleLoggingLevelSwitch.MinimumLevel);
CrestronConsole.ConsoleCommandResponse($"Storing level {level}:{(int) level}");
CrestronConsole.ConsoleCommandResponse($"Storing level {level}:{(int)level}");
var err = CrestronDataStoreStatic.SetLocalIntValue(LevelStoreKey, (int) level);
var err = CrestronDataStoreStatic.SetLocalIntValue(LevelStoreKey, (int)level);
CrestronConsole.ConsoleCommandResponse($"Store result: {err}:{(int)level}");
@@ -422,9 +433,9 @@ namespace PepperDash.Core
/// </summary>
public static void SetWebSocketMinimumDebugLevel(LogEventLevel level)
{
_websocketLoggingLevelSwitch.MinimumLevel = level;
_websocketLoggingLevelSwitch.MinimumLevel = level;
var err = CrestronDataStoreStatic.SetLocalUintValue(WebSocketLevelStoreKey, (uint) level);
var err = CrestronDataStoreStatic.SetLocalUintValue(WebSocketLevelStoreKey, (uint)level);
if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
LogMessage(LogEventLevel.Information, "Error saving websocket debug level setting: {erro}", err);
@@ -491,83 +502,83 @@ namespace PepperDash.Core
/// Callback for console command
/// </summary>
/// <param name="items"></param>
/// <summary>
/// SetDebugFilterFromConsole method
/// </summary>
public static void SetDebugFilterFromConsole(string items)
{
var str = items.Trim();
if (str == "?")
{
CrestronConsole.ConsoleCommandResponse("Usage:\r APPDEBUGFILTER key1 key2 key3....\r " +
"+all: at beginning puts filter into 'default include' mode\r" +
" All keys that follow will be excluded from output.\r" +
"-all: at beginning puts filter into 'default exclude all' mode.\r" +
" All keys that follow will be the only keys that are shown\r" +
"+nokey: Enables messages with no key (default)\r" +
"-nokey: Disables messages with no key.\r" +
"(nokey settings are independent of all other settings)");
return;
}
var keys = Regex.Split(str, @"\s*");
foreach (var keyToken in keys)
{
var lkey = keyToken.ToLower();
if (lkey == "+all")
{
IncludedExcludedKeys.Clear();
_excludeAllMode = false;
}
else if (lkey == "-all")
{
IncludedExcludedKeys.Clear();
_excludeAllMode = true;
}
//else if (lkey == "+nokey")
//{
// ExcludeNoKeyMessages = false;
//}
//else if (lkey == "-nokey")
//{
// ExcludeNoKeyMessages = true;
//}
else
{
string key;
if (lkey.StartsWith("-"))
{
key = lkey.Substring(1);
// if in exclude all mode, we need to remove this from the inclusions
if (_excludeAllMode)
{
if (IncludedExcludedKeys.ContainsKey(key))
IncludedExcludedKeys.Remove(key);
}
// otherwise include all mode, add to the exclusions
else
{
IncludedExcludedKeys[key] = new object();
}
}
else if (lkey.StartsWith("+"))
{
key = lkey.Substring(1);
// if in exclude all mode, we need to add this as inclusion
if (_excludeAllMode)
{
/// <summary>
/// SetDebugFilterFromConsole method
/// </summary>
public static void SetDebugFilterFromConsole(string items)
{
var str = items.Trim();
if (str == "?")
{
CrestronConsole.ConsoleCommandResponse("Usage:\r APPDEBUGFILTER key1 key2 key3....\r " +
"+all: at beginning puts filter into 'default include' mode\r" +
" All keys that follow will be excluded from output.\r" +
"-all: at beginning puts filter into 'default exclude all' mode.\r" +
" All keys that follow will be the only keys that are shown\r" +
"+nokey: Enables messages with no key (default)\r" +
"-nokey: Disables messages with no key.\r" +
"(nokey settings are independent of all other settings)");
return;
}
var keys = Regex.Split(str, @"\s*");
foreach (var keyToken in keys)
{
var lkey = keyToken.ToLower();
if (lkey == "+all")
{
IncludedExcludedKeys.Clear();
_excludeAllMode = false;
}
else if (lkey == "-all")
{
IncludedExcludedKeys.Clear();
_excludeAllMode = true;
}
//else if (lkey == "+nokey")
//{
// ExcludeNoKeyMessages = false;
//}
//else if (lkey == "-nokey")
//{
// ExcludeNoKeyMessages = true;
//}
else
{
string key;
if (lkey.StartsWith("-"))
{
key = lkey.Substring(1);
// if in exclude all mode, we need to remove this from the inclusions
if (_excludeAllMode)
{
if (IncludedExcludedKeys.ContainsKey(key))
IncludedExcludedKeys.Remove(key);
}
// otherwise include all mode, add to the exclusions
else
{
IncludedExcludedKeys[key] = new object();
}
}
else if (lkey.StartsWith("+"))
{
key = lkey.Substring(1);
// if in exclude all mode, we need to add this as inclusion
if (_excludeAllMode)
{
IncludedExcludedKeys[key] = new object();
}
// otherwise include all mode, remove this from exclusions
else
{
if (IncludedExcludedKeys.ContainsKey(key))
IncludedExcludedKeys.Remove(key);
}
}
}
}
}
IncludedExcludedKeys[key] = new object();
}
// otherwise include all mode, remove this from exclusions
else
{
if (IncludedExcludedKeys.ContainsKey(key))
IncludedExcludedKeys.Remove(key);
}
}
}
}
}
@@ -595,7 +606,7 @@ namespace PepperDash.Core
public static object GetDeviceDebugSettingsForKey(string deviceKey)
{
return _contexts.GetDebugSettingsForKey(deviceKey);
}
}
/// <summary>
/// Sets the flag to prevent application starting on next boot
@@ -654,9 +665,15 @@ namespace PepperDash.Core
}
}
/// <summary>
/// Logs a message at the specified log level.
/// </summary>
/// <param name="level">Level to log at</param>
/// <param name="message">Message template</param>
/// <param name="args">Args to put into message template</param>
public static void LogMessage(LogEventLevel level, string message, params object[] args)
{
_logger.Write(level, message, args);
_logger.Write(level, message, args);
}
/// <summary>
@@ -692,7 +709,7 @@ namespace PepperDash.Core
/// </summary>
public static void LogVerbose(IKeyed keyed, string message, params object[] args)
{
using(LogContext.PushProperty("Key", keyed?.Key))
using (LogContext.PushProperty("Key", keyed?.Key))
{
_logger.Write(LogEventLevel.Verbose, message, args);
}
@@ -703,7 +720,7 @@ namespace PepperDash.Core
/// </summary>
public static void LogVerbose(Exception ex, IKeyed keyed, string message, params object[] args)
{
using(LogContext.PushProperty("Key", keyed?.Key))
using (LogContext.PushProperty("Key", keyed?.Key))
{
_logger.Write(LogEventLevel.Verbose, ex, message, args);
}
@@ -722,7 +739,7 @@ namespace PepperDash.Core
/// </summary>
public static void LogVerbose(Exception ex, string message, params object[] args)
{
_logger.Write(LogEventLevel.Verbose, ex, null, message, args);
_logger.Write(LogEventLevel.Verbose, ex, message, args);
}
/// <summary>
@@ -798,7 +815,7 @@ namespace PepperDash.Core
/// </summary>
public static void LogInformation(Exception ex, string message, params object[] args)
{
_logger.Write(LogEventLevel.Information, ex, null, message, args);
_logger.Write(LogEventLevel.Information, ex, message, args);
}
/// <summary>
@@ -836,7 +853,7 @@ namespace PepperDash.Core
/// </summary>
public static void LogWarning(Exception ex, string message, params object[] args)
{
_logger.Write(LogEventLevel.Warning, ex, null, message, args);
_logger.Write(LogEventLevel.Warning, ex, message, args);
}
/// <summary>
@@ -874,7 +891,7 @@ namespace PepperDash.Core
/// </summary>
public static void LogError(Exception ex, string message, params object[] args)
{
_logger.Write(LogEventLevel.Error, ex, null, message, args);
_logger.Write(LogEventLevel.Error, ex, message, args);
}
/// <summary>
@@ -912,7 +929,7 @@ namespace PepperDash.Core
/// </summary>
public static void LogFatal(Exception ex, string message, params object[] args)
{
_logger.Write(LogEventLevel.Fatal, ex, null, message, args);
_logger.Write(LogEventLevel.Fatal, ex, message, args);
}
#endregion
@@ -923,7 +940,7 @@ namespace PepperDash.Core
if (!_logLevels.ContainsKey(level)) return;
var logLevel = _logLevels[level];
LogMessage(logLevel, format, items);
}
@@ -978,7 +995,7 @@ namespace PepperDash.Core
[Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
public static void Console(uint level, IKeyed dev, ErrorLogLevel errorLogLevel,
string format, params object[] items)
{
{
LogMessage(level, dev, format, items);
}
@@ -1122,7 +1139,7 @@ namespace PepperDash.Core
return string.Format(@"\user\debugSettings\program{0}", InitialParametersClass.ApplicationNumber);
}
return string.Format("{0}{1}user{1}debugSettings{1}{2}.json",Directory.GetApplicationRootDirectory(), Path.DirectorySeparatorChar, InitialParametersClass.RoomId);
return string.Format("{0}{1}user{1}debugSettings{1}{2}.json", Directory.GetApplicationRootDirectory(), Path.DirectorySeparatorChar, InitialParametersClass.RoomId);
}
/// <summary>
@@ -1133,15 +1150,15 @@ namespace PepperDash.Core
/// <summary>
/// Error
/// </summary>
Error,
Error,
/// <summary>
/// Warning
/// </summary>
Warning,
Warning,
/// <summary>
/// Notice
/// </summary>
Notice,
Notice,
/// <summary>
/// None
/// </summary>

View File

@@ -43,7 +43,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BouncyCastle.Cryptography" Version="2.4.0" />
<PackageReference Include="Crestron.SimplSharp.SDK.Library" Version="2.21.90" />
<PackageReference Include="Crestron.SimplSharp.SDK.Library" Version="2.21.133" />
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.Expressions" Version="4.0.0" />
<PackageReference Include="Serilog.Formatting.Compact" Version="2.0.0" />

View File

@@ -8,26 +8,20 @@ namespace PepperDash.Essentials.Core
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class ConfigSnippetAttribute : Attribute
{
private string _ConfigSnippet;
/// <summary>
/// Represents a configuration snippet for the device.
/// </summary>
/// <param name="configSnippet"></param>
public ConfigSnippetAttribute(string configSnippet)
{
//Debug.LogMessage(LogEventLevel.Verbose, "Setting Config Snippet {0}", configSnippet);
_ConfigSnippet = configSnippet;
ConfigSnippet = configSnippet;
}
/// <summary>
/// Gets the configuration snippet for the device.
/// This snippet can be used in the DeviceConfig to instantiate the device.
/// </summary>
public string ConfigSnippet
{
get { return _ConfigSnippet; }
}
public string ConfigSnippet { get; }
}
}

View File

@@ -8,25 +8,19 @@ namespace PepperDash.Essentials.Core
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class DescriptionAttribute : Attribute
{
private string _Description;
/// <summary>
/// Represents a description attribute for a device.
/// </summary>
/// <param name="description"></param>
public DescriptionAttribute(string description)
{
//Debug.LogMessage(LogEventLevel.Verbose, "Setting Description: {0}", description);
_Description = description;
Description = description;
}
/// <summary>
/// Gets the description for the device.
/// </summary>
public string Description
{
get { return _Description; }
}
public string Description { get; }
}
}

View File

@@ -1,8 +1,14 @@
using System;
using System.Collections.Generic;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Represents a factory for creating processor extension devices.
/// </summary>
/// <typeparam name="T">The type of the processor extension device.</typeparam>
[Obsolete("will be removed in a future version")]
public abstract class ProcessorExtensionDeviceFactory<T> : IProcessorExtensionDeviceFactory where T : EssentialsDevice
{
#region IProcessorExtensionDeviceFactory Members
@@ -19,11 +25,10 @@ namespace PepperDash.Essentials.Core
{
foreach (var typeName in TypeNames)
{
var descriptionAttribute = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
string description = descriptionAttribute != null && descriptionAttribute.Length > 0
string description = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) is DescriptionAttribute[] descriptionAttribute && descriptionAttribute.Length > 0
? descriptionAttribute[0].Description
: "No description available";
var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
ProcessorExtensionDeviceFactory.AddFactoryForType(typeName.ToLower(), description, typeof(T), BuildDevice);
}
}

View File

@@ -53,9 +53,9 @@ namespace PepperDash.Essentials.Core
// Loop through all loaded assemblies that contain at least 1 type that implements IDeviceFactory
foreach (var assembly in loadedAssemblies)
{
Debug.LogDebug("loaded assembly: {assemblyName}", assembly.GetName().Name);
Debug.LogDebug("loaded assembly: {assemblyName}", assembly.GetName()?.Name ?? "Unknown");
PluginLoader.AddLoadedAssembly(assembly.GetName().Name, assembly);
PluginLoader.AddLoadedAssembly(assembly.GetName()?.Name ?? "Unknown", assembly);
var types = assembly.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract);
@@ -92,12 +92,10 @@ namespace PepperDash.Essentials.Core
{
foreach (var typeName in deviceFactory.TypeNames)
{
var descriptionAttribute = deviceFactory.FactoryType.GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
string description = descriptionAttribute != null && descriptionAttribute.Length > 0
? descriptionAttribute[0].Description
string description = deviceFactory.FactoryType.GetCustomAttributes(typeof(DescriptionAttribute), true) is DescriptionAttribute[] descriptionAttribute && descriptionAttribute.Length > 0
? descriptionAttribute[0].Description
: "No description available";
var snippetAttribute = deviceFactory.FactoryType.GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
AddFactoryForType(typeName.ToLower(), description, deviceFactory.FactoryType, deviceFactory.BuildDevice);
}
}
@@ -157,7 +155,7 @@ namespace PepperDash.Essentials.Core
prop.Parent.Replace(secret);
}
if (!(prop.Value is JObject recurseProp)) return;
if (!(prop.Value is JObject recurseProp)) continue;
CheckForSecrets(recurseProp.Properties());
}

View File

@@ -25,7 +25,7 @@
<DocumentationFile>bin\$(Configuration)\PepperDash_Essentials_Core.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.90" />
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.133" />
</ItemGroup>
<ItemGroup>
<None Include="Crestron\CrestronGenericBaseDevice.cs.orig" />

View File

@@ -523,62 +523,14 @@ namespace PepperDash.Essentials
{
foreach (var typeName in deviceFactory.TypeNames)
{
var descriptionAttribute = deviceFactory.FactoryType.GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
string description = descriptionAttribute != null && descriptionAttribute.Length > 0
? descriptionAttribute[0].Description
string description = deviceFactory.FactoryType.GetCustomAttributes(typeof(DescriptionAttribute), true) is DescriptionAttribute[] descriptionAttribute && descriptionAttribute.Length > 0
? descriptionAttribute[0].Description
: "No description available";
var snippetAttribute = deviceFactory.FactoryType.GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
DeviceFactory.AddFactoryForType(typeName.ToLower(), description, deviceFactory.FactoryType, deviceFactory.BuildDevice);
}
}
/// <summary>
/// Loads a a custom plugin via the legacy method
/// </summary>
/// <param name="type"></param>
/// <param name="loadPlugin"></param>
static void LoadCustomLegacyPlugin(Type type, MethodInfo loadPlugin, LoadedAssembly loadedAssembly)
{
Debug.LogMessage(LogEventLevel.Verbose, "LoadPlugin method found in {0}", type.Name);
var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
var minimumVersion = fields.FirstOrDefault(p => p.Name.Equals("MinimumEssentialsFrameworkVersion"));
if (minimumVersion != null)
{
Debug.LogMessage(LogEventLevel.Verbose, "MinimumEssentialsFrameworkVersion found");
var minimumVersionString = minimumVersion.GetValue(null) as string;
if (!string.IsNullOrEmpty(minimumVersionString))
{
var passed = Global.IsRunningMinimumVersionOrHigher(minimumVersionString);
if (!passed)
{
Debug.LogMessage(LogEventLevel.Information, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", minimumVersionString);
return;
}
else
{
Debug.LogMessage(LogEventLevel.Information, "Passed plugin passed dependency check (required version {0})", minimumVersionString);
}
}
else
{
Debug.LogMessage(LogEventLevel.Information, "MinimumEssentialsFrameworkVersion found but not set. Loading plugin, but your mileage may vary.");
}
}
else
{
Debug.LogMessage(LogEventLevel.Information, "MinimumEssentialsFrameworkVersion not found. Loading plugin, but your mileage may vary.");
}
Debug.LogMessage(LogEventLevel.Information, "Loading legacy plugin: {0}", loadedAssembly.Name);
loadPlugin.Invoke(null, null);
}
/// <summary>
/// LoadPlugins method

View File

@@ -51,11 +51,10 @@ namespace PepperDash.Essentials.Devices.Common
foreach (var typeName in deviceFactory.TypeNames)
{
//Debug.LogMessage(LogEventLevel.Verbose, "Getting Description Attribute from class: '{0}'", typeof(T).FullName);
var descriptionAttribute = deviceFactory.FactoryType.GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
string description = (descriptionAttribute != null && descriptionAttribute.Length > 0)
? descriptionAttribute[0].Description
string description = (deviceFactory.FactoryType.GetCustomAttributes(typeof(DescriptionAttribute), true) is DescriptionAttribute[] descriptionAttribute && descriptionAttribute.Length > 0)
? descriptionAttribute[0].Description
: "No description available";
var snippetAttribute = deviceFactory.FactoryType.GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
Core.DeviceFactory.AddFactoryForType(typeName.ToLower(), description, deviceFactory.FactoryType, deviceFactory.BuildDevice);
}
}

View File

@@ -29,6 +29,6 @@
<ProjectReference Include="..\PepperDash.Essentials.Core\PepperDash.Essentials.Core.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.90" />
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.133" />
</ItemGroup>
</Project>

View File

@@ -50,13 +50,11 @@ namespace PepperDash.Essentials
{
foreach (var typeName in deviceFactory.TypeNames)
{
//Debug.LogMessage(LogEventLevel.Verbose, "Getting Description Attribute from class: '{0}'", typeof(T).FullName);
var descriptionAttribute = deviceFactory.FactoryType.GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
string description = (descriptionAttribute != null && descriptionAttribute.Length > 0)
? descriptionAttribute[0].Description
: string.Empty; // Default value if no DescriptionAttribute is found
var snippetAttribute = deviceFactory.FactoryType.GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
Core.DeviceFactory.AddFactoryForType(typeName.ToLower(), description, deviceFactory.FactoryType, deviceFactory.BuildDevice);
string description = (deviceFactory.FactoryType.GetCustomAttributes(typeof(DescriptionAttribute), true) is DescriptionAttribute[] descriptionAttribute && descriptionAttribute.Length > 0)
? descriptionAttribute[0].Description
: "No description available"; // Default value if no DescriptionAttribute is found
DeviceFactory.AddFactoryForType(typeName.ToLower(), description, deviceFactory.FactoryType, deviceFactory.BuildDevice);
}
}
}

View File

@@ -327,7 +327,7 @@ namespace PepperDash.Essentials.WebSocketServer
}
string ip = processorIp;
if (touchpanel.Touchpanel is IMobileControlCrestronTouchpanelController crestronTouchpanel)
if (touchpanel.Touchpanel is IMobileControlCrestronTouchpanelController crestronTouchpanel && csIpAddress != null)
{
ip = crestronTouchpanel.ConnectedIps.Any(ipInfo =>
{

View File

@@ -1,17 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials
{
@@ -59,12 +53,10 @@ namespace PepperDash.Essentials
{
foreach (var typeName in deviceFactory.TypeNames)
{
var descriptionAttribute = deviceFactory.FactoryType.GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
string description = (descriptionAttribute != null && descriptionAttribute.Length > 0)
? descriptionAttribute[0].Description
string description = (deviceFactory.FactoryType.GetCustomAttributes(typeof(DescriptionAttribute), true) is DescriptionAttribute[] descriptionAttribute && descriptionAttribute.Length > 0)
? descriptionAttribute[0].Description
: "No description available";
var snippetAttribute = deviceFactory.FactoryType.GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
Core.DeviceFactory.AddFactoryForType(typeName.ToLower(), description, deviceFactory.FactoryType, deviceFactory.BuildDevice);
}
}

View File

@@ -48,7 +48,7 @@
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Crestron.SimplSharp.SDK.Program" Version="2.21.90" />
<PackageReference Include="Crestron.SimplSharp.SDK.Program" Version="2.21.133" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PepperDash.Core\PepperDash.Core.csproj" />