From 661f7b827a3df80cc526185618f50493a32f5110 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 18 Apr 2024 16:12:31 -0600 Subject: [PATCH 1/6] fix: Updates to scheduler to attempt to deal with exceptions modifying existing events. Adds console command to allow deletign event group --- .../Devices/DestinationListItem.cs | 6 + .../Global/Scheduler.cs | 154 ++++++++++-------- 2 files changed, 96 insertions(+), 64 deletions(-) diff --git a/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs b/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs index 946ece3b..0c21216a 100644 --- a/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs +++ b/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs @@ -52,5 +52,11 @@ namespace PepperDash.Essentials.Core [JsonProperty("sinkType")] public eRoutingSignalType SinkType { get; set; } + + [JsonProperty("isCodecContentDestination")] + public bool isCodecContentDestination { get; set; } + + [JsonProperty("isProgramAudioDestination")] + public bool isProgramAudioDestination { get; set; } } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Global/Scheduler.cs b/src/PepperDash.Essentials.Core/Global/Scheduler.cs index 2efefa36..e226ce5c 100644 --- a/src/PepperDash.Essentials.Core/Global/Scheduler.cs +++ b/src/PepperDash.Essentials.Core/Global/Scheduler.cs @@ -22,15 +22,31 @@ namespace PepperDash.Essentials.Core static Scheduler() { + CrestronConsole.AddNewConsoleCommand(DeleteEventGroup, "DeleteEventGroup", "Deletes the event group by key", ConsoleAccessLevelEnum.AccessOperator); + CrestronConsole.AddNewConsoleCommand(ClearEventsFromGroup, "ClearAllEvents", "Clears all scheduled events for this group", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(ListAllEventGroups, "ListAllEventGroups", "Lists all the event groups by key", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(ListAllEventsForGroup, "ListEventsForGroup", "Lists all events for the given group", ConsoleAccessLevelEnum.AccessOperator); - } + + static void DeleteEventGroup(string groupName) + { + if (EventGroups.ContainsKey(groupName)) + { + var group = EventGroups[groupName]; + + EventGroups.Remove(groupName); + + group.Dispose(); + + group = null; + } + } + /// /// Clears (deletes) all events from a group /// @@ -40,7 +56,7 @@ namespace PepperDash.Essentials.Core if (!EventGroups.ContainsKey(groupName)) { Debug.LogMessage(LogEventLevel.Information, - "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", + "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", null, groupName); return; } @@ -51,47 +67,47 @@ namespace PepperDash.Essentials.Core { group.ClearAllEvents(); - Debug.LogMessage(LogEventLevel.Information, "[Scheduler]: All events deleted from group '{0}'", groupName); + Debug.LogMessage(LogEventLevel.Information, "[Scheduler]: All events deleted from group '{0}'", null, groupName); } else Debug.LogMessage(LogEventLevel.Information, - "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", + "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", null, groupName); } static void ListAllEventGroups(string command) { - Debug.LogMessage(LogEventLevel.Information, "Event Groups:"); + CrestronConsole.ConsoleCommandResponse("Event Groups:"); foreach (var group in EventGroups) { - Debug.LogMessage(LogEventLevel.Information, "{0}", group.Key); + CrestronConsole.ConsoleCommandResponse($"{group.Key}"); } } static void ListAllEventsForGroup(string args) { - Debug.LogMessage(LogEventLevel.Information, "Getting events for group {0}...", args); + Debug.LogMessage(LogEventLevel.Information, "Getting events for group {0}...", null, args); ScheduledEventGroup group; if (!EventGroups.TryGetValue(args, out group)) { - Debug.LogMessage(LogEventLevel.Information, "Unabled to get event group for key {0}", args); + Debug.LogMessage(LogEventLevel.Information, "Unabled to get event group for key {0}", null, args); return; } foreach (var evt in group.ScheduledEvents) { - Debug.LogMessage(LogEventLevel.Information, - @" -****Event key {0}**** -Event date/time: {1} -Persistent: {2} -Acknowlegable: {3} -Recurrence: {4} -Recurrence Days: {5} -********************", evt.Key, evt.Value.DateAndTime, evt.Value.Persistent, evt.Value.Acknowledgeable, - evt.Value.Recurrence.Recurrence, evt.Value.Recurrence.RecurrenceDays); + CrestronConsole.ConsoleCommandResponse( +$@" +****Event key {evt.Key}**** +Event state: {evt.Value.EventState} +Event date/time: {evt.Value.DateAndTime} +Persistent: {evt.Value.Persistent} +Acknowlegable: {evt.Value.Acknowledgeable} +Recurrence: {evt.Value.Recurrence.Recurrence} +Recurrence Days: {evt.Value.Recurrence.RecurrenceDays} +********************"); } } @@ -138,10 +154,9 @@ Recurrence Days: {5} var dayOfWeek = eventTime.DayOfWeek; - Debug.LogMessage(LogEventLevel.Debug, "[Scheduler]: eventTime day of week is: {0}", dayOfWeek); - + Debug.LogMessage(LogEventLevel.Debug, "[Scheduler]: eventTime day of week is: {0}",null, dayOfWeek); switch (dayOfWeek) - { + { case DayOfWeek.Sunday: { if ((recurrence & ScheduledEventCommon.eWeekDays.Sunday) == ScheduledEventCommon.eWeekDays.Sunday) @@ -203,53 +218,64 @@ Recurrence Days: {5} public static void CreateEventFromConfig(ScheduledEventConfig config, ScheduledEventGroup group, ScheduledEvent.UserEventCallBack handler) { - if (group == null) + try { - Debug.LogMessage(LogEventLevel.Information, "Unable to create event. Group is null"); - return; + if (group == null) + { + Debug.LogMessage(LogEventLevel.Information, "Unable to create event. Group is null", null, null); + return; + } + var scheduledEvent = new ScheduledEvent(config.Key, group) + { + Acknowledgeable = config.Acknowledgeable, + Persistent = config.Persistent + }; + + scheduledEvent.UserCallBack += handler; + + scheduledEvent.DateAndTime.SetFirstDayOfWeek(ScheduledEventCommon.eFirstDayOfWeek.Sunday); + + var eventTime = DateTime.Parse(config.Time); + + if (DateTime.Now > eventTime) + { + eventTime = eventTime.AddDays(1); + } + + Debug.LogMessage(LogEventLevel.Verbose, "[Scheduler] Current Date day of week: {0} recurrence days: {1}", null, eventTime.DayOfWeek, + config.Days); + + var dayOfWeekConverted = ConvertDayOfWeek(eventTime); + + Debug.LogMessage(LogEventLevel.Debug, "[Scheduler] eventTime Day: {0}", null, dayOfWeekConverted); + + while (!dayOfWeekConverted.IsFlagSet(config.Days)) + { + eventTime = eventTime.AddDays(1); + + dayOfWeekConverted = ConvertDayOfWeek(eventTime); + } + + scheduledEvent.DateAndTime.SetAbsoluteEventTime(eventTime); + + scheduledEvent.Recurrence.Weekly(config.Days); + + Debug.LogMessage(LogEventLevel.Verbose, $"[Scheduler] Event State: {scheduledEvent.EventState}", null, null); + + if (config.Enable && scheduledEvent.EventState != ScheduledEventCommon.eEventState.Enabled) + { + scheduledEvent.Enable(); + } + else if (!config.Enable && scheduledEvent.EventState != ScheduledEventCommon.eEventState.Disabled) + { + scheduledEvent.Disable(); + } + } - var scheduledEvent = new ScheduledEvent(config.Key, group) + catch (Exception e) { - Acknowledgeable = config.Acknowledgeable, - Persistent = config.Persistent - }; - scheduledEvent.UserCallBack += handler; - - scheduledEvent.DateAndTime.SetFirstDayOfWeek(ScheduledEventCommon.eFirstDayOfWeek.Sunday); - - var eventTime = DateTime.Parse(config.Time); - - if (DateTime.Now > eventTime) - { - eventTime = eventTime.AddDays(1); - } - - Debug.LogMessage(LogEventLevel.Verbose, "[Scheduler] Current Date day of week: {0} recurrence days: {1}", eventTime.DayOfWeek, - config.Days); - - var dayOfWeekConverted = ConvertDayOfWeek(eventTime); - - Debug.LogMessage(LogEventLevel.Debug, "[Scheduler] eventTime Day: {0}", dayOfWeekConverted); - - while (!dayOfWeekConverted.IsFlagSet(config.Days)) - { - eventTime = eventTime.AddDays(1); - - dayOfWeekConverted = ConvertDayOfWeek(eventTime); - } - - scheduledEvent.DateAndTime.SetAbsoluteEventTime(eventTime); - - scheduledEvent.Recurrence.Weekly(config.Days); - - if (config.Enable) - { - scheduledEvent.Enable(); - } - else - { - scheduledEvent.Disable(); + Debug.LogMessage(LogEventLevel.Error, "Error creating scheduled event: {0}", null, e); } } From e5d5c90aa95becc17c77e44b84b89c5063039d51 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 24 Apr 2024 16:54:51 -0600 Subject: [PATCH 2/6] feat: Adds ITechPassword --- .../Room/Interfaces.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/PepperDash.Essentials.Core/Room/Interfaces.cs b/src/PepperDash.Essentials.Core/Room/Interfaces.cs index 190abeec..ca7df3ae 100644 --- a/src/PepperDash.Essentials.Core/Room/Interfaces.cs +++ b/src/PepperDash.Essentials.Core/Room/Interfaces.cs @@ -79,6 +79,32 @@ namespace PepperDash.Essentials.Core void SetShutdownPromptSeconds(int seconds); } + /// + /// Describes a room with a tech password + /// + public interface ITechPassword + { + event EventHandler TechPasswordValidateResult; + + event EventHandler TechPasswordChanged; + + int TechPasswordLength { get; } + + void ValidateTechPassword(string password); + + void SetTechPassword(string oldPassword, string newPassword); + } + + public class TechPasswordEventArgs : EventArgs + { + public bool IsValid { get; private set; } + + public TechPasswordEventArgs(bool isValid) + { + IsValid = isValid; + } + } + /// /// For rooms that default presentation only routing /// From fa9b493431af3b4be40f8ffb2c3177d464acdfa5 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 25 Apr 2024 16:31:54 -0600 Subject: [PATCH 3/6] feat: Adds IMobileControlTouchpanelController --- .../DeviceTypeInterfaces/IMobileControl.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IMobileControl.cs b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IMobileControl.cs index 7f1d1621..db070289 100644 --- a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IMobileControl.cs +++ b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IMobileControl.cs @@ -106,4 +106,10 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces Action Action { get; } } + public interface IMobileControlTouchpanelController + { + StringFeedback AppUrlFeedback { get; } + string DefaultRoomKey { get; } + string DeviceKey { get; } + } } \ No newline at end of file From d8d27949c34a71d90da2ab7d9c66c8e3d5c9d4a8 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 26 Apr 2024 09:31:27 -0600 Subject: [PATCH 4/6] fix: updates to IMobileControlTouchpanelController --- .../DeviceTypeInterfaces/IMobileControl.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IMobileControl.cs b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IMobileControl.cs index db070289..b856a7c0 100644 --- a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IMobileControl.cs +++ b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IMobileControl.cs @@ -106,10 +106,11 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces Action Action { get; } } - public interface IMobileControlTouchpanelController + public interface IMobileControlTouchpanelController : IKeyed { - StringFeedback AppUrlFeedback { get; } string DefaultRoomKey { get; } - string DeviceKey { get; } + void SetAppUrl(string url); + bool UseDirectServer { get; } + bool ZoomRoomController { get; } } } \ No newline at end of file From 82f78bf06861741ff614a21f631fdd1392993a01 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 26 Apr 2024 12:08:26 -0600 Subject: [PATCH 5/6] feat: adds StarShutdown method to IShutdownPromptTimer --- src/PepperDash.Essentials.Core/Room/Interfaces.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Core/Room/Interfaces.cs b/src/PepperDash.Essentials.Core/Room/Interfaces.cs index ca7df3ae..640dc91f 100644 --- a/src/PepperDash.Essentials.Core/Room/Interfaces.cs +++ b/src/PepperDash.Essentials.Core/Room/Interfaces.cs @@ -77,9 +77,11 @@ namespace PepperDash.Essentials.Core SecondsCountdownTimer ShutdownPromptTimer { get; } void SetShutdownPromptSeconds(int seconds); + + void StartShutdown(eShutdownType type); } - /// + /// /// Describes a room with a tech password /// public interface ITechPassword From 80b8cc638560ef9811f1c33de851a1350ddded5d Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 26 Apr 2024 13:15:15 -0600 Subject: [PATCH 6/6] feat: Adds SecondsRemainingFeedback to SecondsCountdownTimer --- src/PepperDash.Essentials.Core/Timers/CountdownTimer.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/PepperDash.Essentials.Core/Timers/CountdownTimer.cs b/src/PepperDash.Essentials.Core/Timers/CountdownTimer.cs index 28bd6811..1cac0a50 100644 --- a/src/PepperDash.Essentials.Core/Timers/CountdownTimer.cs +++ b/src/PepperDash.Essentials.Core/Timers/CountdownTimer.cs @@ -23,6 +23,8 @@ namespace PepperDash.Essentials.Core public IntFeedback PercentFeedback { get; private set; } public StringFeedback TimeRemainingFeedback { get; private set; } + public IntFeedback SecondsRemainingFeedback { get; private set; } + public bool CountsDown { get; set; } /// @@ -64,6 +66,8 @@ namespace PepperDash.Essentials.Core : String.Format("{0:00}:{1:00}", timeSpan.Minutes, timeSpan.Seconds); }); + SecondsRemainingFeedback = new IntFeedback(() => (int)(FinishTime - DateTime.Now).TotalSeconds); + PercentFeedback = new IntFeedback( () => @@ -144,6 +148,7 @@ namespace PepperDash.Essentials.Core PercentFeedback.FireUpdate(); TimeRemainingFeedback.FireUpdate(); + SecondsRemainingFeedback.FireUpdate(); } } } \ No newline at end of file