mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-16 05:05:00 +00:00
Updates from bench testing RoomOnToDefaultSourceWhenOccupied. Now tested and working using config file values.
This commit is contained in:
@@ -43,19 +43,21 @@ namespace PepperDash.Essentials.Room.Behaviours
|
|||||||
public RoomOnToDefaultSourceWhenOccupied(string key, RoomOnToDefaultSourceWhenOccupiedConfig config)
|
public RoomOnToDefaultSourceWhenOccupied(string key, RoomOnToDefaultSourceWhenOccupiedConfig config)
|
||||||
: base(key)
|
: base(key)
|
||||||
{
|
{
|
||||||
|
|
||||||
CrestronConsole.AddNewConsoleCommand((o) => FeatureEventGroup.ClearAllEvents(), "ClearAllEvents", "Clears all scheduled events for this group", ConsoleAccessLevelEnum.AccessAdministrator);
|
|
||||||
|
|
||||||
Config = config;
|
Config = config;
|
||||||
|
|
||||||
FeatureEventGroup = new ScheduledEventGroup(this.Key);
|
FeatureEventGroup = new ScheduledEventGroup(this.Key);
|
||||||
|
|
||||||
FeatureEventGroup.RetrieveAllEvents();
|
FeatureEventGroup.RetrieveAllEvents();
|
||||||
|
|
||||||
|
// Add to the global class for tracking
|
||||||
|
//Global.Scheduler.AddEventGroup(FeatureEventGroup);
|
||||||
|
|
||||||
AddPostActivationAction(() =>
|
AddPostActivationAction(() =>
|
||||||
{
|
{
|
||||||
if (Room.RoomOccupancy != null)
|
// Subscribe to room event to know when RoomOccupancy is set and ready to be subscribed to
|
||||||
Room.RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += new EventHandler<FeedbackEventArgs>(RoomIsOccupiedFeedback_OutputChange);
|
if (Room != null)
|
||||||
|
Room.RoomOccupancyIsSet += new EventHandler<EventArgs>(RoomOccupancyIsSet);
|
||||||
|
|
||||||
else
|
else
|
||||||
Debug.Console(1, this, "Room has no RoomOccupancy object set");
|
Debug.Console(1, this, "Room has no RoomOccupancy object set");
|
||||||
|
|
||||||
@@ -74,11 +76,6 @@ namespace PepperDash.Essentials.Room.Behaviours
|
|||||||
|
|
||||||
if (Room != null)
|
if (Room != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
// Creates the event group and adds it to the Global Scheduler list
|
|
||||||
//Global.Scheduler.AddEventGroup(FeatureEventGroup);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FeatureEnabledTime = DateTime.Parse(Config.OccupancyStartTime);
|
FeatureEnabledTime = DateTime.Parse(Config.OccupancyStartTime);
|
||||||
@@ -127,6 +124,21 @@ namespace PepperDash.Essentials.Room.Behaviours
|
|||||||
return base.CustomActivate();
|
return base.CustomActivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Subscribe to feedback from RoomIsOccupiedFeedback on Room
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
void RoomOccupancyIsSet(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Room.RoomOccupancy != null)
|
||||||
|
{
|
||||||
|
Room.RoomOccupancy.RoomIsOccupiedFeedback.OutputChange -= RoomIsOccupiedFeedback_OutputChange;
|
||||||
|
Room.RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += new EventHandler<FeedbackEventArgs>(RoomIsOccupiedFeedback_OutputChange);
|
||||||
|
Debug.Console(1, this, "Subscribed to RoomOccupancy status from: '{0}'", Room.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FeatureEventGroup_UserGroupCallBack(ScheduledEvent SchEvent, ScheduledEventCommon.eCallbackReason type)
|
void FeatureEventGroup_UserGroupCallBack(ScheduledEvent SchEvent, ScheduledEventCommon.eCallbackReason type)
|
||||||
{
|
{
|
||||||
if (type == ScheduledEventCommon.eCallbackReason.NormalExpiration)
|
if (type == ScheduledEventCommon.eCallbackReason.NormalExpiration)
|
||||||
@@ -136,13 +148,13 @@ namespace PepperDash.Essentials.Room.Behaviours
|
|||||||
if (Config.EnableRoomOnWhenOccupied)
|
if (Config.EnableRoomOnWhenOccupied)
|
||||||
FeatureEnabled = true;
|
FeatureEnabled = true;
|
||||||
|
|
||||||
Debug.Console(1, this, "*****Feature Enabled.*****");
|
Debug.Console(1, this, "*****Feature Enabled by event.*****");
|
||||||
}
|
}
|
||||||
else if (SchEvent.Name == FeatureDisableEventName)
|
else if (SchEvent.Name == FeatureDisableEventName)
|
||||||
{
|
{
|
||||||
FeatureEnabled = false;
|
FeatureEnabled = false;
|
||||||
|
|
||||||
Debug.Console(1, this, "*****Feature Disabled.*****");
|
Debug.Console(1, this, "*****Feature Disabled by event.*****");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,7 +171,11 @@ namespace PepperDash.Essentials.Room.Behaviours
|
|||||||
{
|
{
|
||||||
if (DateTime.Now.CompareTo(FeatureEnabledTime) > 0 && FeatureDisabledTime.CompareTo(DateTime.Now) >= 0)
|
if (DateTime.Now.CompareTo(FeatureEnabledTime) > 0 && FeatureDisabledTime.CompareTo(DateTime.Now) >= 0)
|
||||||
{
|
{
|
||||||
enabled = true;
|
if (SchedulerUtilities.CheckIfDayOfWeekMatchesRecurrenceDays(DateTime.Now, FeatureEnableEvent.Recurrence.RecurrenceDays))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "*****Feature Enabled by startup check.*****");
|
||||||
|
enabled = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return enabled;
|
return enabled;
|
||||||
@@ -172,6 +188,7 @@ namespace PepperDash.Essentials.Room.Behaviours
|
|||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
void RoomIsOccupiedFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
void RoomIsOccupiedFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||||
{
|
{
|
||||||
|
Debug.Console(1, this, "RoomIsOccupiedFeeback.OutputChange event fired. e.BoolValue: {0}", e.BoolValue);
|
||||||
if(e.BoolValue)
|
if(e.BoolValue)
|
||||||
{
|
{
|
||||||
// Occupancy detected
|
// Occupancy detected
|
||||||
@@ -179,8 +196,11 @@ namespace PepperDash.Essentials.Room.Behaviours
|
|||||||
if (FeatureEnabled)
|
if (FeatureEnabled)
|
||||||
{
|
{
|
||||||
// Check room power state first
|
// Check room power state first
|
||||||
if(!Room.OnFeedback.BoolValue)
|
if (!Room.OnFeedback.BoolValue)
|
||||||
Room.PowerOnToDefaultOrLastSource();
|
{
|
||||||
|
Debug.Console(1, this, "Powering Room on to default source");
|
||||||
|
Room.RunDefaultPresentRoute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,17 +226,34 @@ namespace PepperDash.Essentials.Room.Behaviours
|
|||||||
{
|
{
|
||||||
schEvent.Description = "Enables the RoomOnToDefaultSourceWhenOccupiedFeature";
|
schEvent.Description = "Enables the RoomOnToDefaultSourceWhenOccupiedFeature";
|
||||||
|
|
||||||
|
var eventRecurrennce = CalculateDaysOfWeekRecurrence();
|
||||||
|
|
||||||
|
var eventTime = new DateTime();
|
||||||
|
|
||||||
// Check to make sure the date for this event is in the future
|
// Check to make sure the date for this event is in the future
|
||||||
if (DateTime.Now.CompareTo(FeatureEnabledTime) > 0)
|
if (DateTime.Now.CompareTo(FeatureEnabledTime) > 0)
|
||||||
schEvent.DateAndTime.SetAbsoluteEventTime(FeatureEnabledTime.AddDays(1));
|
eventTime = FeatureEnabledTime.AddDays(1);
|
||||||
else
|
else
|
||||||
schEvent.DateAndTime.SetAbsoluteEventTime(FeatureEnabledTime);
|
eventTime = FeatureEnabledTime;
|
||||||
|
|
||||||
|
Debug.Console(1, this, "eventTime (before recurrence check): {0}", eventTime);
|
||||||
|
|
||||||
|
// Check day of week against recurrence days and move date ahead as necessary to avoid throwing an exception by trying to set the event
|
||||||
|
// start date on a day of the week that doesn't match teh recurrence values
|
||||||
|
while(!SchedulerUtilities.CheckIfDayOfWeekMatchesRecurrenceDays(eventTime, eventRecurrennce))
|
||||||
|
{
|
||||||
|
eventTime = eventTime.AddDays(1);
|
||||||
|
Debug.Console(1, this, "eventTime does not fall on a recurrence weekday. eventTime: {0}", eventTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
schEvent.DateAndTime.SetAbsoluteEventTime(eventTime);
|
||||||
|
|
||||||
Debug.Console(1, this, "Event '{0}' Absolute time set to {1}", schEvent.Name, schEvent.DateAndTime.ToString());
|
Debug.Console(1, this, "Event '{0}' Absolute time set to {1}", schEvent.Name, schEvent.DateAndTime.ToString());
|
||||||
|
|
||||||
CalculateAndSetAcknowledgeExpirationTimeout(schEvent, FeatureEnabledTime, FeatureDisabledTime);
|
CalculateAndSetAcknowledgeExpirationTimeout(schEvent, FeatureEnabledTime, FeatureDisabledTime);
|
||||||
|
|
||||||
schEvent.Recurrence.Weekly((ScheduledEventCommon.eWeekDays)CalculateDaysEnum());
|
schEvent.Recurrence.Weekly(eventRecurrennce);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (schEvent.Name == FeatureDisableEventName)
|
else if (schEvent.Name == FeatureDisableEventName)
|
||||||
{
|
{
|
||||||
@@ -236,6 +273,8 @@ namespace PepperDash.Essentials.Room.Behaviours
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CalculateAndSetAcknowledgeExpirationTimeout(ScheduledEvent schEvent, DateTime time1, DateTime time2)
|
void CalculateAndSetAcknowledgeExpirationTimeout(ScheduledEvent schEvent, DateTime time1, DateTime time2)
|
||||||
{
|
{
|
||||||
Debug.Console(1, this, "time1.Hour = {0}", time1.Hour);
|
Debug.Console(1, this, "time1.Hour = {0}", time1.Hour);
|
||||||
@@ -262,6 +301,40 @@ namespace PepperDash.Essentials.Room.Behaviours
|
|||||||
schEvent.AcknowledgeExpirationTimeout.Minute = (ushort)(ackExpMinutes);
|
schEvent.AcknowledgeExpirationTimeout.Minute = (ushort)(ackExpMinutes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks existing event to see if it matches the execution time
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="existingEvent"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool CheckExistingEventTimeForMatch(ScheduledEvent existingEvent, DateTime newTime)
|
||||||
|
{
|
||||||
|
bool isMatch = true;
|
||||||
|
|
||||||
|
// Check to see if hour and minute match
|
||||||
|
if (existingEvent.DateAndTime.Hour != newTime.Hour || existingEvent.DateAndTime.Minute != newTime.Minute)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
return isMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks existing event to see if it matches the recurrence days
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="existingEvent"></param>
|
||||||
|
/// <param name="eWeekdays"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool CheckExistingEventRecurrenceForMatch(ScheduledEvent existingEvent, ScheduledEventCommon.eWeekDays eWeekdays)
|
||||||
|
{
|
||||||
|
bool isMatch = true;
|
||||||
|
|
||||||
|
// Check to see if recurrence matches
|
||||||
|
if (eWeekdays != existingEvent.Recurrence.RecurrenceDays)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return isMatch;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the Enable event to the local event group and sets its properties based on config
|
/// Adds the Enable event to the local event group and sets its properties based on config
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -273,11 +346,21 @@ namespace PepperDash.Essentials.Room.Behaviours
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Check if existing event has same time and recurrence as config values
|
||||||
|
|
||||||
FeatureEnableEvent = FeatureEventGroup.ScheduledEvents[FeatureEnableEventName];
|
FeatureEnableEvent = FeatureEventGroup.ScheduledEvents[FeatureEnableEventName];
|
||||||
Debug.Console(1, this, "Enable event already found in group");
|
Debug.Console(1, this, "Enable event already found in group");
|
||||||
|
|
||||||
// TODO: Check config times and days against DateAndTime of existing event. If different, may need to remove event and recreate?
|
// Check config times and days against DateAndTime of existing event. If different, delete existing event and create new event
|
||||||
|
if(!CheckExistingEventTimeForMatch(FeatureEnableEvent, FeatureEnabledTime) || !CheckExistingEventRecurrenceForMatch(FeatureEnableEvent, CalculateDaysOfWeekRecurrence()))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Existing event does not match new config properties. Deleting exisiting event: '{0}'", FeatureEnableEvent.Name);
|
||||||
|
FeatureEventGroup.DeleteEvent(FeatureEnableEvent);
|
||||||
|
|
||||||
|
FeatureEnableEvent = null;
|
||||||
|
|
||||||
|
CreateEvent(FeatureEnableEvent, FeatureEnableEventName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -296,34 +379,43 @@ namespace PepperDash.Essentials.Room.Behaviours
|
|||||||
FeatureDisableEvent = FeatureEventGroup.ScheduledEvents[FeatureDisableEventName];
|
FeatureDisableEvent = FeatureEventGroup.ScheduledEvents[FeatureDisableEventName];
|
||||||
Debug.Console(1, this, "Disable event already found in group");
|
Debug.Console(1, this, "Disable event already found in group");
|
||||||
|
|
||||||
// TODO: Check config times and days against DateAndTime of existing event. If different, may need to remove event and recreate?
|
// Check config times against DateAndTime of existing event. If different, delete existing event and create new event
|
||||||
}
|
if(!CheckExistingEventTimeForMatch(FeatureDisableEvent, FeatureDisabledTime))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Existing event does not match new config properties. Deleting exisiting event: '{0}'", FeatureDisableEvent.Name);
|
||||||
|
|
||||||
|
FeatureEventGroup.DeleteEvent(FeatureDisableEvent);
|
||||||
|
|
||||||
|
FeatureDisableEvent = null;
|
||||||
|
|
||||||
|
CreateEvent(FeatureDisableEvent, FeatureDisableEventName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Calculates the correct enum value for the event recurrence based on the config values
|
/// Calculates the correct bitfield enum value for the event recurrence based on the config values
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
ScheduledEventCommon.eWeekDays CalculateDaysEnum()
|
ScheduledEventCommon.eWeekDays CalculateDaysOfWeekRecurrence()
|
||||||
{
|
{
|
||||||
ScheduledEventCommon.eWeekDays value = new ScheduledEventCommon.eWeekDays();
|
ScheduledEventCommon.eWeekDays value = new ScheduledEventCommon.eWeekDays();
|
||||||
|
|
||||||
if (Config.EnableSunday)
|
if (Config.EnableSunday)
|
||||||
value = value + (int)ScheduledEventCommon.eWeekDays.Sunday;
|
value = value | ScheduledEventCommon.eWeekDays.Sunday;
|
||||||
if (Config.EnableMonday)
|
if (Config.EnableMonday)
|
||||||
value = value + (int)ScheduledEventCommon.eWeekDays.Monday;
|
value = value | ScheduledEventCommon.eWeekDays.Monday;
|
||||||
if (Config.EnableTuesday)
|
if (Config.EnableTuesday)
|
||||||
value = value + (int)ScheduledEventCommon.eWeekDays.Tuesday;
|
value = value | ScheduledEventCommon.eWeekDays.Tuesday;
|
||||||
if (Config.EnableWednesday)
|
if (Config.EnableWednesday)
|
||||||
value = value + (int)ScheduledEventCommon.eWeekDays.Wednesday;
|
value = value | ScheduledEventCommon.eWeekDays.Wednesday;
|
||||||
if (Config.EnableThursday)
|
if (Config.EnableThursday)
|
||||||
value = value + (int)ScheduledEventCommon.eWeekDays.Thursday;
|
value = value | ScheduledEventCommon.eWeekDays.Thursday;
|
||||||
if (Config.EnableFriday)
|
if (Config.EnableFriday)
|
||||||
value = value + (int)ScheduledEventCommon.eWeekDays.Friday;
|
value = value | ScheduledEventCommon.eWeekDays.Friday;
|
||||||
if (Config.EnableSaturday)
|
if (Config.EnableSaturday)
|
||||||
value = value + (int)ScheduledEventCommon.eWeekDays.Saturday;
|
value = value | ScheduledEventCommon.eWeekDays.Saturday;
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -212,10 +212,13 @@ namespace PepperDash.Essentials
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Routes the default source item, if any
|
/// Routes the default source item, if any
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool RunDefaultPresentRoute()
|
public override bool RunDefaultPresentRoute()
|
||||||
{
|
{
|
||||||
if(DefaultSourceItem == null)
|
if (DefaultSourceItem == null)
|
||||||
return false;
|
{
|
||||||
|
Debug.Console(0, this, "Unable to run default present route, DefaultSourceItem is null.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
RunRouteAction(DefaultSourceItem);
|
RunRouteAction(DefaultSourceItem);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -283,10 +283,11 @@ namespace PepperDash.Essentials
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Routes the default source item, if any. Returns true when default route exists
|
/// Routes the default source item, if any. Returns true when default route exists
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool RunDefaultPresentRoute()
|
public override bool RunDefaultPresentRoute()
|
||||||
{
|
{
|
||||||
//if (DefaultSourceItem != null)
|
if (DefaultSourceItem != null)
|
||||||
RunRouteAction(DefaultSourceItem);
|
RunRouteAction(DefaultSourceItem);
|
||||||
|
|
||||||
return DefaultSourceItem != null;
|
return DefaultSourceItem != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,273 +1,294 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
using Crestron.SimplSharp.Scheduler;
|
using Crestron.SimplSharp.Scheduler;
|
||||||
|
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Devices.Common.Occupancy;
|
using PepperDash.Essentials.Devices.Common.Occupancy;
|
||||||
|
|
||||||
namespace PepperDash.Essentials
|
namespace PepperDash.Essentials
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class EssentialsRoomBase : Device
|
public abstract class EssentialsRoomBase : Device
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BoolFeedback OnFeedback { get; private set; }
|
public BoolFeedback OnFeedback { get; private set; }
|
||||||
|
|
||||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
/// <summary>
|
||||||
public BoolFeedback IsCoolingDownFeedback { get; private set; }
|
/// Fires when the RoomOccupancy object is set
|
||||||
|
/// </summary>
|
||||||
public IOccupancyStatusProvider RoomOccupancy { get; private set; }
|
public event EventHandler<EventArgs> RoomOccupancyIsSet;
|
||||||
|
|
||||||
public bool OccupancyStatusProviderIsRemote { get; private set; }
|
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||||
|
public BoolFeedback IsCoolingDownFeedback { get; private set; }
|
||||||
protected abstract Func<bool> IsWarmingFeedbackFunc { get; }
|
|
||||||
protected abstract Func<bool> IsCoolingFeedbackFunc { get; }
|
public IOccupancyStatusProvider RoomOccupancy { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
public bool OccupancyStatusProviderIsRemote { get; private set; }
|
||||||
/// Timer used for informing the UIs of a shutdown
|
|
||||||
/// </summary>
|
protected abstract Func<bool> IsWarmingFeedbackFunc { get; }
|
||||||
public SecondsCountdownTimer ShutdownPromptTimer { get; private set; }
|
protected abstract Func<bool> IsCoolingFeedbackFunc { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Timer used for informing the UIs of a shutdown
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int ShutdownPromptSeconds { get; set; }
|
public SecondsCountdownTimer ShutdownPromptTimer { get; private set; }
|
||||||
public int ShutdownVacancySeconds { get; set; }
|
|
||||||
public eShutdownType ShutdownType { get; private set; }
|
/// <summary>
|
||||||
|
///
|
||||||
public PepperDash.Essentials.Room.EssentialsRoomEmergencyBase Emergency { get; set; }
|
/// </summary>
|
||||||
|
public int ShutdownPromptSeconds { get; set; }
|
||||||
public PepperDash.Essentials.Devices.Common.Microphones.MicrophonePrivacyController MicrophonePrivacy { get; set; }
|
public int ShutdownVacancySeconds { get; set; }
|
||||||
|
public eShutdownType ShutdownType { get; private set; }
|
||||||
public string LogoUrl { get; set; }
|
|
||||||
|
public PepperDash.Essentials.Room.EssentialsRoomEmergencyBase Emergency { get; set; }
|
||||||
protected SecondsCountdownTimer RoomVacancyShutdownTimer { get; private set; }
|
|
||||||
|
public PepperDash.Essentials.Devices.Common.Microphones.MicrophonePrivacyController MicrophonePrivacy { get; set; }
|
||||||
public eVacancyMode VacancyMode { get; private set; }
|
|
||||||
|
public string LogoUrl { get; set; }
|
||||||
/// <summary>
|
|
||||||
/// Seconds after vacancy prompt is displayed until shutdown
|
protected SecondsCountdownTimer RoomVacancyShutdownTimer { get; private set; }
|
||||||
/// </summary>
|
|
||||||
protected int RoomVacancyShutdownSeconds;
|
public eVacancyMode VacancyMode { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Seconds after vacancy detected until prompt is displayed
|
/// Seconds after vacancy prompt is displayed until shutdown
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
protected int RoomVacancyShutdownSeconds;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Seconds after vacancy detected until prompt is displayed
|
||||||
|
/// </summary>
|
||||||
protected int RoomVacancyShutdownPromptSeconds;
|
protected int RoomVacancyShutdownPromptSeconds;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected abstract Func<bool> OnFeedbackFunc { get; }
|
protected abstract Func<bool> OnFeedbackFunc { get; }
|
||||||
|
|
||||||
protected Dictionary<IBasicVolumeWithFeedback, uint> SavedVolumeLevels = new Dictionary<IBasicVolumeWithFeedback, uint>();
|
protected Dictionary<IBasicVolumeWithFeedback, uint> SavedVolumeLevels = new Dictionary<IBasicVolumeWithFeedback, uint>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When volume control devices change, should we zero the one that we are leaving?
|
/// When volume control devices change, should we zero the one that we are leaving?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; private set; }
|
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
/// <param name="name"></param>
|
/// <param name="name"></param>
|
||||||
public EssentialsRoomBase(string key, string name) : base(key, name)
|
public EssentialsRoomBase(string key, string name) : base(key, name)
|
||||||
{
|
{
|
||||||
// Setup the ShutdownPromptTimer
|
// Setup the ShutdownPromptTimer
|
||||||
ShutdownPromptTimer = new SecondsCountdownTimer(Key + "-offTimer");
|
ShutdownPromptTimer = new SecondsCountdownTimer(Key + "-offTimer");
|
||||||
ShutdownPromptTimer.IsRunningFeedback.OutputChange += (o, a) =>
|
ShutdownPromptTimer.IsRunningFeedback.OutputChange += (o, a) =>
|
||||||
{
|
{
|
||||||
if (!ShutdownPromptTimer.IsRunningFeedback.BoolValue)
|
if (!ShutdownPromptTimer.IsRunningFeedback.BoolValue)
|
||||||
ShutdownType = eShutdownType.None;
|
ShutdownType = eShutdownType.None;
|
||||||
};
|
};
|
||||||
ShutdownPromptTimer.HasFinished += (o, a) => Shutdown(); // Shutdown is triggered
|
ShutdownPromptTimer.HasFinished += (o, a) => Shutdown(); // Shutdown is triggered
|
||||||
|
|
||||||
ShutdownPromptSeconds = 60;
|
ShutdownPromptSeconds = 60;
|
||||||
ShutdownVacancySeconds = 120;
|
ShutdownVacancySeconds = 120;
|
||||||
ShutdownType = eShutdownType.None;
|
ShutdownType = eShutdownType.None;
|
||||||
|
|
||||||
RoomVacancyShutdownTimer = new SecondsCountdownTimer(Key + "-vacancyOffTimer");
|
RoomVacancyShutdownTimer = new SecondsCountdownTimer(Key + "-vacancyOffTimer");
|
||||||
//RoomVacancyShutdownTimer.IsRunningFeedback.OutputChange += (o, a) =>
|
//RoomVacancyShutdownTimer.IsRunningFeedback.OutputChange += (o, a) =>
|
||||||
//{
|
//{
|
||||||
// if (!RoomVacancyShutdownTimer.IsRunningFeedback.BoolValue)
|
// if (!RoomVacancyShutdownTimer.IsRunningFeedback.BoolValue)
|
||||||
// ShutdownType = ShutdownType.Vacancy;
|
// ShutdownType = ShutdownType.Vacancy;
|
||||||
//};
|
//};
|
||||||
RoomVacancyShutdownTimer.HasFinished += new EventHandler<EventArgs>(RoomVacancyShutdownPromptTimer_HasFinished); // Shutdown is triggered
|
RoomVacancyShutdownTimer.HasFinished += new EventHandler<EventArgs>(RoomVacancyShutdownPromptTimer_HasFinished); // Shutdown is triggered
|
||||||
|
|
||||||
RoomVacancyShutdownPromptSeconds = 1500; // 25 min to prompt warning
|
RoomVacancyShutdownPromptSeconds = 1500; // 25 min to prompt warning
|
||||||
RoomVacancyShutdownSeconds = 240; // 4 min after prompt will trigger shutdown prompt
|
RoomVacancyShutdownSeconds = 240; // 4 min after prompt will trigger shutdown prompt
|
||||||
VacancyMode = eVacancyMode.None;
|
VacancyMode = eVacancyMode.None;
|
||||||
|
|
||||||
OnFeedback = new BoolFeedback(OnFeedbackFunc);
|
OnFeedback = new BoolFeedback(OnFeedbackFunc);
|
||||||
|
|
||||||
IsWarmingUpFeedback = new BoolFeedback(IsWarmingFeedbackFunc);
|
IsWarmingUpFeedback = new BoolFeedback(IsWarmingFeedbackFunc);
|
||||||
IsCoolingDownFeedback = new BoolFeedback(IsCoolingFeedbackFunc);
|
IsCoolingDownFeedback = new BoolFeedback(IsCoolingFeedbackFunc);
|
||||||
}
|
|
||||||
|
AddPostActivationAction(() =>
|
||||||
void RoomVacancyShutdownPromptTimer_HasFinished(object sender, EventArgs e)
|
{
|
||||||
{
|
if (RoomOccupancy != null)
|
||||||
switch (VacancyMode)
|
OnRoomOccupancyIsSet();
|
||||||
{
|
});
|
||||||
case eVacancyMode.None:
|
|
||||||
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
|
|
||||||
break;
|
|
||||||
case eVacancyMode.InInitialVacancy:
|
|
||||||
StartRoomVacancyTimer(eVacancyMode.InShutdownWarning);
|
|
||||||
break;
|
|
||||||
case eVacancyMode.InShutdownWarning:
|
|
||||||
{
|
|
||||||
StartShutdown(eShutdownType.Vacancy);
|
|
||||||
Debug.Console(0, this, "Shutting Down due to vacancy.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type"></param>
|
|
||||||
public void StartShutdown(eShutdownType type)
|
|
||||||
{
|
|
||||||
// Check for shutdowns running. Manual should override other shutdowns
|
|
||||||
|
|
||||||
if (type == eShutdownType.Manual)
|
|
||||||
ShutdownPromptTimer.SecondsToCount = ShutdownPromptSeconds;
|
|
||||||
else if (type == eShutdownType.Vacancy)
|
|
||||||
ShutdownPromptTimer.SecondsToCount = ShutdownVacancySeconds;
|
|
||||||
ShutdownType = type;
|
|
||||||
ShutdownPromptTimer.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StartRoomVacancyTimer(eVacancyMode mode)
|
|
||||||
{
|
|
||||||
if (mode == eVacancyMode.None)
|
|
||||||
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownPromptSeconds;
|
|
||||||
else if (mode == eVacancyMode.InInitialVacancy)
|
|
||||||
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownSeconds;
|
|
||||||
VacancyMode = mode;
|
|
||||||
RoomVacancyShutdownTimer.Start();
|
|
||||||
|
|
||||||
Debug.Console(0, this, "Vacancy Timer Started.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Resets the vacancy mode and shutsdwon the room
|
|
||||||
/// </summary>
|
|
||||||
public void Shutdown()
|
|
||||||
{
|
|
||||||
VacancyMode = eVacancyMode.None;
|
|
||||||
EndShutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This method is for the derived class to define it's specific shutdown
|
|
||||||
/// requirements but should not be called directly. It is called by Shutdown()
|
|
||||||
/// </summary>
|
|
||||||
protected abstract void EndShutdown();
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Override this to implement a default volume level(s) method
|
|
||||||
/// </summary>
|
|
||||||
public abstract void SetDefaultLevels();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the object to be used as the IOccupancyStatusProvider for the room. Can be an Occupancy Aggregator or a specific device
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="statusProvider"></param>
|
|
||||||
public void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes)
|
|
||||||
{
|
|
||||||
if (statusProvider == null)
|
|
||||||
{
|
|
||||||
Debug.Console(0, this, "ERROR: Occupancy sensor device is null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If status provider is fusion, set flag to remote
|
|
||||||
if (statusProvider is PepperDash.Essentials.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase)
|
|
||||||
OccupancyStatusProviderIsRemote = true;
|
|
||||||
|
|
||||||
if(timeoutMinutes > 0)
|
|
||||||
RoomVacancyShutdownSeconds = timeoutMinutes * 60;
|
|
||||||
|
|
||||||
RoomOccupancy = statusProvider;
|
|
||||||
|
|
||||||
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RoomVacancyShutdownPromptTimer_HasFinished(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
switch (VacancyMode)
|
||||||
|
{
|
||||||
|
case eVacancyMode.None:
|
||||||
|
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
|
||||||
|
break;
|
||||||
|
case eVacancyMode.InInitialVacancy:
|
||||||
|
StartRoomVacancyTimer(eVacancyMode.InShutdownWarning);
|
||||||
|
break;
|
||||||
|
case eVacancyMode.InShutdownWarning:
|
||||||
|
{
|
||||||
|
StartShutdown(eShutdownType.Vacancy);
|
||||||
|
Debug.Console(0, this, "Shutting Down due to vacancy.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
public void StartShutdown(eShutdownType type)
|
||||||
|
{
|
||||||
|
// Check for shutdowns running. Manual should override other shutdowns
|
||||||
|
|
||||||
|
if (type == eShutdownType.Manual)
|
||||||
|
ShutdownPromptTimer.SecondsToCount = ShutdownPromptSeconds;
|
||||||
|
else if (type == eShutdownType.Vacancy)
|
||||||
|
ShutdownPromptTimer.SecondsToCount = ShutdownVacancySeconds;
|
||||||
|
ShutdownType = type;
|
||||||
|
ShutdownPromptTimer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartRoomVacancyTimer(eVacancyMode mode)
|
||||||
|
{
|
||||||
|
if (mode == eVacancyMode.None)
|
||||||
|
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownPromptSeconds;
|
||||||
|
else if (mode == eVacancyMode.InInitialVacancy)
|
||||||
|
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownSeconds;
|
||||||
|
VacancyMode = mode;
|
||||||
|
RoomVacancyShutdownTimer.Start();
|
||||||
|
|
||||||
|
Debug.Console(0, this, "Vacancy Timer Started.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resets the vacancy mode and shutsdwon the room
|
||||||
|
/// </summary>
|
||||||
|
public void Shutdown()
|
||||||
|
{
|
||||||
|
VacancyMode = eVacancyMode.None;
|
||||||
|
EndShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This method is for the derived class to define it's specific shutdown
|
||||||
|
/// requirements but should not be called directly. It is called by Shutdown()
|
||||||
|
/// </summary>
|
||||||
|
protected abstract void EndShutdown();
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Override this to implement a default volume level(s) method
|
||||||
|
/// </summary>
|
||||||
|
public abstract void SetDefaultLevels();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the object to be used as the IOccupancyStatusProvider for the room. Can be an Occupancy Aggregator or a specific device
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="statusProvider"></param>
|
||||||
|
public void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes)
|
||||||
|
{
|
||||||
|
if (statusProvider == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "ERROR: Occupancy sensor device is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If status provider is fusion, set flag to remote
|
||||||
|
if (statusProvider is PepperDash.Essentials.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase)
|
||||||
|
OccupancyStatusProviderIsRemote = true;
|
||||||
|
|
||||||
|
if(timeoutMinutes > 0)
|
||||||
|
RoomVacancyShutdownSeconds = timeoutMinutes * 60;
|
||||||
|
|
||||||
|
RoomOccupancy = statusProvider;
|
||||||
|
|
||||||
|
OnRoomOccupancyIsSet();
|
||||||
|
|
||||||
|
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange -= RoomIsOccupiedFeedback_OutputChange;
|
||||||
|
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
|
||||||
|
|
||||||
|
Debug.Console(0, this, "Room Occupancy set to device: '{0}'", (statusProvider as Device).Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnRoomOccupancyIsSet()
|
||||||
|
{
|
||||||
|
var handler = RoomOccupancyIsSet;
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, new EventArgs());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// To allow base class to power room on to last source
|
||||||
|
/// </summary>
|
||||||
|
public abstract void PowerOnToDefaultOrLastSource();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// To allow base class to power room on to default source
|
/// To allow base class to power room on to default source
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract void PowerOnToDefaultOrLastSource();
|
/// <returns></returns>
|
||||||
|
public abstract bool RunDefaultPresentRoute();
|
||||||
void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
|
|
||||||
{
|
void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
|
||||||
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
|
{
|
||||||
{
|
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
|
||||||
Debug.Console(1, this, "Notice: Vacancy Detected");
|
{
|
||||||
// Trigger the timer when the room is vacant
|
Debug.Console(1, this, "Notice: Vacancy Detected");
|
||||||
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
|
// Trigger the timer when the room is vacant
|
||||||
}
|
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
Debug.Console(1, this, "Notice: Occupancy Detected");
|
{
|
||||||
// Reset the timer when the room is occupied
|
Debug.Console(1, this, "Notice: Occupancy Detected");
|
||||||
RoomVacancyShutdownTimer.Cancel();
|
// Reset the timer when the room is occupied
|
||||||
}
|
RoomVacancyShutdownTimer.Cancel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets up events in the scheduler for the start and end times of the appropriate days to enable and disable the RoomOccupancyPowerOnIsEnabled flag
|
/// Executes when RoomVacancyShutdownTimer expires. Used to trigger specific room actions as needed. Must nullify the timer object when executed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void SetUpOccupancyRoomOnEventsInScheduler()
|
/// <param name="o"></param>
|
||||||
{
|
public abstract void RoomVacatedForTimeoutPeriod(object o);
|
||||||
|
}
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
/// <summary>
|
/// To describe the various ways a room may be shutting down
|
||||||
/// Executes when RoomVacancyShutdownTimer expires. Used to trigger specific room actions as needed. Must nullify the timer object when executed
|
/// </summary>
|
||||||
/// </summary>
|
public enum eShutdownType
|
||||||
/// <param name="o"></param>
|
{
|
||||||
public abstract void RoomVacatedForTimeoutPeriod(object o);
|
None = 0,
|
||||||
}
|
External,
|
||||||
|
Manual,
|
||||||
/// <summary>
|
Vacancy
|
||||||
/// To describe the various ways a room may be shutting down
|
}
|
||||||
/// </summary>
|
|
||||||
public enum eShutdownType
|
public enum eVacancyMode
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
External,
|
InInitialVacancy,
|
||||||
Manual,
|
InShutdownWarning
|
||||||
Vacancy
|
}
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
public enum eVacancyMode
|
///
|
||||||
{
|
/// </summary>
|
||||||
None = 0,
|
public enum eWarmingCoolingMode
|
||||||
InInitialVacancy,
|
{
|
||||||
InShutdownWarning
|
None,
|
||||||
}
|
Warming,
|
||||||
|
Cooling
|
||||||
/// <summary>
|
}
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public enum eWarmingCoolingMode
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Warming,
|
|
||||||
Cooling
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -29,3 +29,5 @@ devjson:1 {"deviceKey":"microphonePrivacyController-1", "methodName":"TogglePriv
|
|||||||
devjson:1 {"deviceKey":"room1.InCallFeedback","methodName":"SetTestValue", "params": [ true ]}
|
devjson:1 {"deviceKey":"room1.InCallFeedback","methodName":"SetTestValue", "params": [ true ]}
|
||||||
|
|
||||||
devjson:1 {"deviceKey":"room1.InCallFeedback","methodName":"ClearTestValue", "params": []}
|
devjson:1 {"deviceKey":"room1.InCallFeedback","methodName":"ClearTestValue", "params": []}
|
||||||
|
|
||||||
|
devjson:3 {"deviceKey":"room1.RoomOccupancy.RoomIsOccupiedFeedback","methodName":"SetTestValue", "params": [ true ]}
|
||||||
Reference in New Issue
Block a user