mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-15 20:54:55 +00:00
Mega refactor in progress
This commit is contained in:
@@ -1,526 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Scheduler;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Devices.Common.Occupancy;
|
||||
|
||||
namespace PepperDash.Essentials.Room.Behaviours
|
||||
{
|
||||
/// <summary>
|
||||
/// A device that when linked to a room can power the room on when enabled during scheduled hours.
|
||||
/// </summary>
|
||||
public class RoomOnToDefaultSourceWhenOccupied : ReconfigurableDevice
|
||||
{
|
||||
RoomOnToDefaultSourceWhenOccupiedConfig PropertiesConfig;
|
||||
|
||||
public bool FeatureEnabled { get; private set; }
|
||||
|
||||
public DateTime FeatureEnabledTime { get; private set; }
|
||||
|
||||
ScheduledEvent FeatureEnableEvent;
|
||||
|
||||
const string FeatureEnableEventName = "EnableRoomOnToDefaultSourceWhenOccupied";
|
||||
|
||||
public DateTime FeatureDisabledTime { get; private set; }
|
||||
|
||||
ScheduledEvent FeatureDisableEvent;
|
||||
|
||||
const string FeatureDisableEventName = "DisableRoomOnToDefaultSourceWhenOccupied";
|
||||
|
||||
ScheduledEventGroup FeatureEventGroup;
|
||||
|
||||
public EssentialsRoomBase Room { get; private set; }
|
||||
|
||||
private Fusion.EssentialsHuddleSpaceFusionSystemControllerBase FusionRoom;
|
||||
|
||||
public RoomOnToDefaultSourceWhenOccupied(DeviceConfig config) :
|
||||
base (config)
|
||||
{
|
||||
PropertiesConfig = JsonConvert.DeserializeObject<RoomOnToDefaultSourceWhenOccupiedConfig>(config.Properties.ToString());
|
||||
|
||||
FeatureEventGroup = new ScheduledEventGroup(this.Key);
|
||||
|
||||
FeatureEventGroup.RetrieveAllEvents();
|
||||
|
||||
// Add to the global class for tracking
|
||||
Scheduler.AddEventGroup(FeatureEventGroup);
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
// Subscribe to room event to know when RoomOccupancy is set and ready to be subscribed to
|
||||
if (Room != null)
|
||||
Room.RoomOccupancyIsSet += new EventHandler<EventArgs>(RoomOccupancyIsSet);
|
||||
|
||||
else
|
||||
Debug.Console(1, this, "Room has no RoomOccupancy object set");
|
||||
|
||||
var fusionRoomKey = PropertiesConfig.RoomKey + "-fusion";
|
||||
|
||||
FusionRoom = DeviceManager.GetDeviceForKey(fusionRoomKey) as Fusion.EssentialsHuddleSpaceFusionSystemControllerBase;
|
||||
|
||||
if (FusionRoom == null)
|
||||
Debug.Console(1, this, "Unable to get Fusion Room from Device Manager with key: {0}", fusionRoomKey);
|
||||
});
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
SetUpDevice();
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up device based on config values
|
||||
/// </summary>
|
||||
void SetUpDevice()
|
||||
{
|
||||
Room = DeviceManager.GetDeviceForKey(PropertiesConfig.RoomKey) as EssentialsRoomBase;
|
||||
|
||||
if (Room != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
FeatureEnabledTime = DateTime.Parse(PropertiesConfig.OccupancyStartTime);
|
||||
|
||||
if (FeatureEnabledTime != null)
|
||||
{
|
||||
Debug.Console(1, this, "Enabled Time: {0}", FeatureEnabledTime.ToString());
|
||||
}
|
||||
else
|
||||
Debug.Console(1, this, "Unable to parse {0} to DateTime", PropertiesConfig.OccupancyStartTime);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to parse OccupancyStartTime property: {0} \n Error: {1}", PropertiesConfig.OccupancyStartTime, e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
FeatureDisabledTime = DateTime.Parse(PropertiesConfig.OccupancyEndTime);
|
||||
|
||||
if (FeatureDisabledTime != null)
|
||||
{
|
||||
Debug.Console(1, this, "Disabled Time: {0}", FeatureDisabledTime.ToString());
|
||||
}
|
||||
else
|
||||
Debug.Console(1, this, "Unable to parse {0} to DateTime", PropertiesConfig.OccupancyEndTime);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to parse a DateTime config value \n Error: {1}", e);
|
||||
}
|
||||
|
||||
if (!PropertiesConfig.EnableRoomOnWhenOccupied)
|
||||
FeatureEventGroup.ClearAllEvents();
|
||||
else
|
||||
{
|
||||
AddEnableEventToGroup();
|
||||
|
||||
AddDisableEventToGroup();
|
||||
|
||||
FeatureEventGroup.UserGroupCallBack += new ScheduledEventGroup.UserEventGroupCallBack(FeatureEventGroup_UserGroupCallBack);
|
||||
|
||||
FeatureEventGroup.EnableAllEvents();
|
||||
}
|
||||
|
||||
FeatureEnabled = CheckIfFeatureShouldBeEnabled();
|
||||
}
|
||||
else
|
||||
Debug.Console(1, this, "Unable to get room from Device Manager with key: {0}", PropertiesConfig.RoomKey);
|
||||
}
|
||||
|
||||
|
||||
protected override void CustomSetConfig(DeviceConfig config)
|
||||
{
|
||||
var newPropertiesConfig = JsonConvert.DeserializeObject<RoomOnToDefaultSourceWhenOccupiedConfig>(config.Properties.ToString());
|
||||
|
||||
if(newPropertiesConfig != null)
|
||||
PropertiesConfig = newPropertiesConfig;
|
||||
|
||||
ConfigWriter.UpdateDeviceConfig(config);
|
||||
|
||||
SetUpDevice();
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
if (type == ScheduledEventCommon.eCallbackReason.NormalExpiration)
|
||||
{
|
||||
if (SchEvent.Name == FeatureEnableEventName)
|
||||
{
|
||||
if (PropertiesConfig.EnableRoomOnWhenOccupied)
|
||||
FeatureEnabled = true;
|
||||
|
||||
Debug.Console(1, this, "*****Feature Enabled by event.*****");
|
||||
}
|
||||
else if (SchEvent.Name == FeatureDisableEventName)
|
||||
{
|
||||
FeatureEnabled = false;
|
||||
|
||||
Debug.Console(1, this, "*****Feature Disabled by event.*****");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the feature should be currently enabled. Used on startup if processor starts after start time but before end time
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool CheckIfFeatureShouldBeEnabled()
|
||||
{
|
||||
bool enabled = false;
|
||||
|
||||
if(PropertiesConfig.EnableRoomOnWhenOccupied)
|
||||
{
|
||||
Debug.Console(1, this, "Current Time: {0} \n FeatureEnabledTime: {1} \n FeatureDisabledTime: {2}", DateTime.Now, FeatureEnabledTime, FeatureDisabledTime);
|
||||
|
||||
if (DateTime.Now.TimeOfDay.CompareTo(FeatureEnabledTime.TimeOfDay) >= 0 && FeatureDisabledTime.TimeOfDay.CompareTo(DateTime.Now.TimeOfDay) > 0)
|
||||
{
|
||||
if (SchedulerUtilities.CheckIfDayOfWeekMatchesRecurrenceDays(DateTime.Now, CalculateDaysOfWeekRecurrence()))
|
||||
{
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(enabled)
|
||||
Debug.Console(1, this, "*****Feature Enabled*****");
|
||||
else
|
||||
Debug.Console(1, this, "*****Feature Disabled*****");
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Respond to Occupancy status event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void RoomIsOccupiedFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
Debug.Console(1, this, "RoomIsOccupiedFeeback.OutputChange event fired. e.BoolValue: {0}", e.BoolValue);
|
||||
if(e.BoolValue)
|
||||
{
|
||||
// Occupancy detected
|
||||
|
||||
if (FeatureEnabled)
|
||||
{
|
||||
// Check room power state first
|
||||
if (!Room.OnFeedback.BoolValue)
|
||||
{
|
||||
Debug.Console(1, this, "Powering Room on to default source");
|
||||
Room.RunDefaultPresentRoute();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CreateEvent(ScheduledEvent schEvent, string name)
|
||||
{
|
||||
Debug.Console(1, this, "Adding Event: '{0}'", name);
|
||||
// Create the event
|
||||
if (schEvent == null)
|
||||
schEvent = new ScheduledEvent(name, FeatureEventGroup);
|
||||
|
||||
// Set up its initial properties
|
||||
|
||||
if(!schEvent.Acknowledgeable)
|
||||
schEvent.Acknowledgeable = true;
|
||||
|
||||
if(!schEvent.Persistent)
|
||||
schEvent.Persistent = true;
|
||||
|
||||
schEvent.DateAndTime.SetFirstDayOfWeek(ScheduledEventCommon.eFirstDayOfWeek.Sunday);
|
||||
|
||||
// Set config driven properties
|
||||
|
||||
if (schEvent.Name == FeatureEnableEventName)
|
||||
{
|
||||
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
|
||||
if (DateTime.Now.CompareTo(FeatureEnabledTime) > 0)
|
||||
eventTime = FeatureEnabledTime.AddDays(1);
|
||||
else
|
||||
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());
|
||||
|
||||
CalculateAndSetAcknowledgeExpirationTimeout(schEvent, FeatureEnabledTime, FeatureDisabledTime);
|
||||
|
||||
schEvent.Recurrence.Weekly(eventRecurrennce);
|
||||
|
||||
}
|
||||
else if (schEvent.Name == FeatureDisableEventName)
|
||||
{
|
||||
schEvent.Description = "Disables the RoomOnToDefaultSourceWhenOccupiedFeature";
|
||||
|
||||
// Check to make sure the date for this event is in the future
|
||||
if (DateTime.Now.CompareTo(FeatureDisabledTime) > 0)
|
||||
schEvent.DateAndTime.SetAbsoluteEventTime(FeatureDisabledTime.AddDays(1));
|
||||
else
|
||||
schEvent.DateAndTime.SetAbsoluteEventTime(FeatureDisabledTime);
|
||||
|
||||
Debug.Console(1, this, "Event '{0}' Absolute time set to {1}", schEvent.Name, schEvent.DateAndTime.ToString());
|
||||
|
||||
CalculateAndSetAcknowledgeExpirationTimeout(schEvent, FeatureDisabledTime, FeatureEnabledTime);
|
||||
|
||||
schEvent.Recurrence.Daily();
|
||||
}
|
||||
}
|
||||
|
||||
void CalculateAndSetAcknowledgeExpirationTimeout(ScheduledEvent schEvent, DateTime time1, DateTime time2)
|
||||
{
|
||||
Debug.Console(1, this, "time1.Hour = {0}", time1.Hour);
|
||||
Debug.Console(1, this, "time2.Hour = {0}", time2.Hour);
|
||||
Debug.Console(1, this, "time1.Minute = {0}", time1.Minute);
|
||||
Debug.Console(1, this, "time2.Minute = {0}", time2.Minute);
|
||||
|
||||
// Calculate the Acknowledge Expiration timer to be the time between the enable and dispable events, less one minute
|
||||
var ackHours = time2.Hour - time1.Hour;
|
||||
if(ackHours < 0)
|
||||
ackHours = ackHours + 24;
|
||||
var ackMinutes = time2.Minute - time1.Minute;
|
||||
|
||||
Debug.Console(1, this, "ackHours = {0}, ackMinutes = {1}", ackHours, ackMinutes);
|
||||
|
||||
var ackTotalMinutes = ((ackHours * 60) + ackMinutes) - 1;
|
||||
|
||||
var ackExpHour = ackTotalMinutes / 60;
|
||||
var ackExpMinutes = ackTotalMinutes % 60;
|
||||
|
||||
Debug.Console(1, this, "Acknowledge Expiration Timeout: {0} hours, {1} minutes", ackExpHour, ackExpMinutes);
|
||||
|
||||
schEvent.AcknowledgeExpirationTimeout.Hour = (ushort)(ackHours);
|
||||
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>
|
||||
/// Adds the Enable event to the local event group and sets its properties based on config
|
||||
/// </summary>
|
||||
void AddEnableEventToGroup()
|
||||
{
|
||||
if (!FeatureEventGroup.ScheduledEvents.ContainsKey(FeatureEnableEventName))
|
||||
{
|
||||
CreateEvent(FeatureEnableEvent, FeatureEnableEventName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if existing event has same time and recurrence as config values
|
||||
|
||||
FeatureEnableEvent = FeatureEventGroup.ScheduledEvents[FeatureEnableEventName];
|
||||
Debug.Console(1, this, "Enable event already found in group");
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the Enable event to the local event group and sets its properties based on config
|
||||
/// </summary>
|
||||
void AddDisableEventToGroup()
|
||||
{
|
||||
if (!FeatureEventGroup.ScheduledEvents.ContainsKey(FeatureDisableEventName))
|
||||
{
|
||||
CreateEvent(FeatureDisableEvent, FeatureDisableEventName);
|
||||
}
|
||||
else
|
||||
{
|
||||
FeatureDisableEvent = FeatureEventGroup.ScheduledEvents[FeatureDisableEventName];
|
||||
Debug.Console(1, this, "Disable event already found in group");
|
||||
|
||||
// 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>
|
||||
/// Calculates the correct bitfield enum value for the event recurrence based on the config values
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
ScheduledEventCommon.eWeekDays CalculateDaysOfWeekRecurrence()
|
||||
{
|
||||
ScheduledEventCommon.eWeekDays value = new ScheduledEventCommon.eWeekDays();
|
||||
|
||||
if (PropertiesConfig.EnableSunday)
|
||||
value = value | ScheduledEventCommon.eWeekDays.Sunday;
|
||||
if (PropertiesConfig.EnableMonday)
|
||||
value = value | ScheduledEventCommon.eWeekDays.Monday;
|
||||
if (PropertiesConfig.EnableTuesday)
|
||||
value = value | ScheduledEventCommon.eWeekDays.Tuesday;
|
||||
if (PropertiesConfig.EnableWednesday)
|
||||
value = value | ScheduledEventCommon.eWeekDays.Wednesday;
|
||||
if (PropertiesConfig.EnableThursday)
|
||||
value = value | ScheduledEventCommon.eWeekDays.Thursday;
|
||||
if (PropertiesConfig.EnableFriday)
|
||||
value = value | ScheduledEventCommon.eWeekDays.Friday;
|
||||
if (PropertiesConfig.EnableSaturday)
|
||||
value = value | ScheduledEventCommon.eWeekDays.Saturday;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for event that enables feature. Enables feature if config property is true
|
||||
/// </summary>
|
||||
/// <param name="SchEvent"></param>
|
||||
/// <param name="type"></param>
|
||||
void FeatureEnableEvent_UserCallBack(ScheduledEvent SchEvent, ScheduledEventCommon.eCallbackReason type)
|
||||
{
|
||||
if (type == ScheduledEventCommon.eCallbackReason.NormalExpiration)
|
||||
{
|
||||
if(PropertiesConfig.EnableRoomOnWhenOccupied)
|
||||
FeatureEnabled = true;
|
||||
|
||||
Debug.Console(1, this, "RoomOnToDefaultSourceWhenOccupied Feature Enabled.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for event that enables feature. Disables feature
|
||||
/// </summary>
|
||||
/// <param name="SchEvent"></param>
|
||||
/// <param name="type"></param>
|
||||
void FeatureDisableEvent_UserCallBack(ScheduledEvent SchEvent, ScheduledEventCommon.eCallbackReason type)
|
||||
{
|
||||
if (type == ScheduledEventCommon.eCallbackReason.NormalExpiration)
|
||||
{
|
||||
FeatureEnabled = false;
|
||||
|
||||
Debug.Console(1, this, "RoomOnToDefaultSourceWhenOccupied Feature Disabled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class RoomOnToDefaultSourceWhenOccupiedConfig
|
||||
{
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
[JsonProperty("enableRoomOnWhenOccupied")]
|
||||
public bool EnableRoomOnWhenOccupied { get; set; }
|
||||
|
||||
[JsonProperty("occupancyStartTime")]
|
||||
public string OccupancyStartTime { get; set; }
|
||||
|
||||
[JsonProperty("occupancyEndTime")]
|
||||
public string OccupancyEndTime { get; set; }
|
||||
|
||||
[JsonProperty("enableSunday")]
|
||||
public bool EnableSunday { get; set; }
|
||||
|
||||
[JsonProperty("enableMonday")]
|
||||
public bool EnableMonday { get; set; }
|
||||
|
||||
[JsonProperty("enableTuesday")]
|
||||
public bool EnableTuesday { get; set; }
|
||||
|
||||
[JsonProperty("enableWednesday")]
|
||||
public bool EnableWednesday { get; set; }
|
||||
|
||||
[JsonProperty("enableThursday")]
|
||||
public bool EnableThursday { get; set; }
|
||||
|
||||
[JsonProperty("enableFriday")]
|
||||
public bool EnableFriday { get; set; }
|
||||
|
||||
[JsonProperty("enableSaturday")]
|
||||
public bool EnableSaturday { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Room.Config
|
||||
{
|
||||
public class EssentialsDualDisplayRoomPropertiesConfig : EssentialsNDisplayRoomPropertiesConfig
|
||||
{
|
||||
|
||||
public const string LeftDisplayId = "leftDisplay";
|
||||
public const string RightDisplayId = "rightDisplay";
|
||||
}
|
||||
}
|
||||
@@ -8,19 +8,10 @@ using Newtonsoft.Json;
|
||||
namespace PepperDash.Essentials.Room.Config
|
||||
{
|
||||
|
||||
public class EssentialsHuddleVtc1PropertiesConfig : EssentialsRoomPropertiesConfig
|
||||
public class EssentialsHuddleVtc1PropertiesConfig : EssentialsConferenceRoomPropertiesConfig
|
||||
{
|
||||
[JsonProperty("defaultDisplayKey")]
|
||||
public string DefaultDisplayKey { get; set; }
|
||||
[JsonProperty("defaultAudioKey")]
|
||||
public string DefaultAudioKey { get; set; }
|
||||
[JsonProperty("sourceListKey")]
|
||||
public string SourceListKey { get; set; }
|
||||
[JsonProperty("defaultSourceItem")]
|
||||
public string DefaultSourceItem { get; set; }
|
||||
[JsonProperty("videoCodecKey")]
|
||||
public string VideoCodecKey { get; set; }
|
||||
[JsonProperty("audioCodecKey")]
|
||||
public string AudioCodecKey { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,22 +4,27 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Room.Config
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsNDisplayRoomPropertiesConfig : EssentialsRoomPropertiesConfig
|
||||
public class EssentialsNDisplayRoomPropertiesConfig : EssentialsConferenceRoomPropertiesConfig
|
||||
{
|
||||
[JsonProperty("defaultAudioBehavior")]
|
||||
public string DefaultAudioBehavior { get; set; }
|
||||
public string DefaultAudioKey { get; set; }
|
||||
[JsonProperty("defaultVideoBehavior")]
|
||||
public string DefaultVideoBehavior { get; set; }
|
||||
[JsonProperty("displays")]
|
||||
public Dictionary<string, string> Displays { get; set; }
|
||||
public string SourceListKey { get; set; }
|
||||
|
||||
public EssentialsNDisplayRoomPropertiesConfig()
|
||||
{
|
||||
Displays = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -76,7 +76,7 @@ namespace PepperDash.Essentials.Room.Config
|
||||
}
|
||||
// Get the MicrophonePrivacy device from the device manager
|
||||
var mP = (DeviceManager.GetDeviceForKey(props.MicrophonePrivacy.DeviceKey) as
|
||||
PepperDash.Essentials.Devices.Common.Microphones.MicrophonePrivacyController);
|
||||
Core.Privacy.MicrophonePrivacyController);
|
||||
// Set this room as the IPrivacy device
|
||||
if (mP == null)
|
||||
{
|
||||
@@ -175,6 +175,25 @@ namespace PepperDash.Essentials.Room.Config
|
||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
|
||||
}
|
||||
|
||||
public class EssentialsAvRoomPropertiesConfig : EssentialsRoomPropertiesConfig
|
||||
{
|
||||
[JsonProperty("defaultAudioKey")]
|
||||
public string DefaultAudioKey { get; set; }
|
||||
[JsonProperty("sourceListKey")]
|
||||
public string SourceListKey { get; set; }
|
||||
[JsonProperty("defaultSourceItem")]
|
||||
public string DefaultSourceItem { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class EssentialsConferenceRoomPropertiesConfig : EssentialsAvRoomPropertiesConfig
|
||||
{
|
||||
[JsonProperty("videoCodecKey")]
|
||||
public string VideoCodecKey { get; set; }
|
||||
[JsonProperty("audioCodecKey")]
|
||||
public string AudioCodecKey { get; set; }
|
||||
}
|
||||
|
||||
public class EssentialsEnvironmentPropertiesConfig
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
@@ -12,15 +12,7 @@ using PepperDash.Essentials.Room.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Room
|
||||
{
|
||||
public abstract class EssentialsRoomEmergencyBase : IKeyed
|
||||
{
|
||||
public string Key { get; private set; }
|
||||
|
||||
public EssentialsRoomEmergencyBase(string key)
|
||||
{
|
||||
Key = key;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase
|
||||
|
||||
68
PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs
Normal file
68
PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||
|
||||
namespace PepperDash.Essentials.Room.Types
|
||||
{
|
||||
public class EssentialsDualDisplayRoom : EssentialsNDisplayRoomBase, IHasCurrentVolumeControls,
|
||||
IRunRouteAction, IPrivacy, IPrivacy, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec
|
||||
{
|
||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
|
||||
public EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; private set; }
|
||||
|
||||
//************************
|
||||
// Call-related stuff
|
||||
|
||||
public BoolFeedback InCallFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis
|
||||
/// </summary>
|
||||
public IntFeedback CallTypeFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public BoolFeedback PrivacyModeIsOnFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// When something in the room is sharing with the far end or through other means
|
||||
/// </summary>
|
||||
public BoolFeedback IsSharingFeedback { get; private set; }
|
||||
|
||||
IRoutingSinkWithSwitching LeftDisplay { get; private set; }
|
||||
IRoutingSinkWithSwitching RightDisplay { get; private set; }
|
||||
|
||||
|
||||
protected override Func<bool> OnFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var leftDisp = LeftDisplay as DisplayBase;
|
||||
var rightDisp = RightDisplay as DisplayBase;
|
||||
var val = leftDisp != null && leftDisp.CurrentSourceInfo != null
|
||||
&& leftDisp.CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||
&& rightDisp != null && rightDisp.CurrentSourceInfo != null
|
||||
&& rightDisp.CurrentSourceInfo.Type == eSourceListItemType.Route;
|
||||
return val;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ namespace PepperDash.Essentials
|
||||
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasCurrentVolumeControls
|
||||
{
|
||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
protected override Func<bool> OnFeedbackFunc
|
||||
{
|
||||
@@ -76,11 +76,6 @@ namespace PepperDash.Essentials
|
||||
|
||||
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The config name of the source list
|
||||
/// </summary>
|
||||
public string SourceListKey { get; set; }
|
||||
|
||||
public string DefaultSourceItem { get; set; }
|
||||
|
||||
public ushort DefaultVolume { get; set; }
|
||||
@@ -128,7 +123,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSingleSourceChange;
|
||||
var handler = CurrentSourceChange;
|
||||
// remove from in-use tracker, if so equipped
|
||||
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||
@@ -251,7 +246,7 @@ namespace PepperDash.Essentials
|
||||
// Add Occupancy object from config
|
||||
if (PropertiesConfig.Occupancy != null)
|
||||
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
PepperDash.Essentials.Devices.Common.Occupancy.IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||
|
||||
this.LogoUrl = PropertiesConfig.Logo.GetUrl();
|
||||
this.SourceListKey = PropertiesConfig.SourceListKey;
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace PepperDash.Essentials
|
||||
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec
|
||||
{
|
||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
|
||||
//************************
|
||||
@@ -166,7 +166,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSingleSourceChange;
|
||||
var handler = CurrentSourceChange;
|
||||
// remove from in-use tracker, if so equipped
|
||||
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||
@@ -330,7 +330,7 @@ namespace PepperDash.Essentials
|
||||
// Add Occupancy object from config
|
||||
if (PropertiesConfig.Occupancy != null)
|
||||
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
PepperDash.Essentials.Devices.Common.Occupancy.IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||
|
||||
this.LogoUrl = PropertiesConfig.Logo.GetUrl();
|
||||
this.SourceListKey = PropertiesConfig.SourceListKey;
|
||||
|
||||
@@ -19,13 +19,10 @@ namespace PepperDash.Essentials.Room.Types
|
||||
/// </summary>
|
||||
public abstract class EssentialsNDisplayRoomBase : EssentialsRoomBase
|
||||
{
|
||||
public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||
//public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||
|
||||
public Dictionary<string, IRoutingSinkWithSwitching> Displays { get; protected set; }
|
||||
|
||||
protected override Func<bool> IsWarmingFeedbackFunc { get { return () => false; ; } }
|
||||
protected override Func<bool> IsCoolingFeedbackFunc { get { return () => false; } }
|
||||
|
||||
public EssentialsNDisplayRoomBase(DeviceConfig config)
|
||||
: base (config)
|
||||
{
|
||||
|
||||
@@ -1,297 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Scheduler;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Devices.Common.Occupancy;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class EssentialsRoomBase : ReconfigurableDevice
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public BoolFeedback OnFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fires when the RoomOccupancy object is set
|
||||
/// </summary>
|
||||
public event EventHandler<EventArgs> RoomOccupancyIsSet;
|
||||
|
||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||
public BoolFeedback IsCoolingDownFeedback { get; private set; }
|
||||
|
||||
public IOccupancyStatusProvider RoomOccupancy { get; private set; }
|
||||
|
||||
public bool OccupancyStatusProviderIsRemote { get; private set; }
|
||||
|
||||
protected abstract Func<bool> IsWarmingFeedbackFunc { get; }
|
||||
protected abstract Func<bool> IsCoolingFeedbackFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Timer used for informing the UIs of a shutdown
|
||||
/// </summary>
|
||||
public SecondsCountdownTimer ShutdownPromptTimer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int ShutdownPromptSeconds { get; set; }
|
||||
public int ShutdownVacancySeconds { get; set; }
|
||||
public eShutdownType ShutdownType { get; private set; }
|
||||
|
||||
public PepperDash.Essentials.Room.EssentialsRoomEmergencyBase Emergency { get; set; }
|
||||
|
||||
public PepperDash.Essentials.Devices.Common.Microphones.MicrophonePrivacyController MicrophonePrivacy { get; set; }
|
||||
|
||||
public string LogoUrl { get; set; }
|
||||
|
||||
protected SecondsCountdownTimer RoomVacancyShutdownTimer { get; private set; }
|
||||
|
||||
public eVacancyMode VacancyMode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Seconds after vacancy prompt is displayed until shutdown
|
||||
/// </summary>
|
||||
protected int RoomVacancyShutdownSeconds;
|
||||
|
||||
/// <summary>
|
||||
/// Seconds after vacancy detected until prompt is displayed
|
||||
/// </summary>
|
||||
protected int RoomVacancyShutdownPromptSeconds;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected abstract Func<bool> OnFeedbackFunc { get; }
|
||||
|
||||
protected Dictionary<IBasicVolumeWithFeedback, uint> SavedVolumeLevels = new Dictionary<IBasicVolumeWithFeedback, uint>();
|
||||
|
||||
/// <summary>
|
||||
/// When volume control devices change, should we zero the one that we are leaving?
|
||||
/// </summary>
|
||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; private set; }
|
||||
|
||||
|
||||
public EssentialsRoomBase(DeviceConfig config)
|
||||
: base(config)
|
||||
{
|
||||
// Setup the ShutdownPromptTimer
|
||||
ShutdownPromptTimer = new SecondsCountdownTimer(Key + "-offTimer");
|
||||
ShutdownPromptTimer.IsRunningFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!ShutdownPromptTimer.IsRunningFeedback.BoolValue)
|
||||
ShutdownType = eShutdownType.None;
|
||||
};
|
||||
ShutdownPromptTimer.HasFinished += (o, a) => Shutdown(); // Shutdown is triggered
|
||||
|
||||
ShutdownPromptSeconds = 60;
|
||||
ShutdownVacancySeconds = 120;
|
||||
ShutdownType = eShutdownType.None;
|
||||
|
||||
RoomVacancyShutdownTimer = new SecondsCountdownTimer(Key + "-vacancyOffTimer");
|
||||
//RoomVacancyShutdownTimer.IsRunningFeedback.OutputChange += (o, a) =>
|
||||
//{
|
||||
// if (!RoomVacancyShutdownTimer.IsRunningFeedback.BoolValue)
|
||||
// ShutdownType = ShutdownType.Vacancy;
|
||||
//};
|
||||
RoomVacancyShutdownTimer.HasFinished += new EventHandler<EventArgs>(RoomVacancyShutdownPromptTimer_HasFinished); // Shutdown is triggered
|
||||
|
||||
RoomVacancyShutdownPromptSeconds = 1500; // 25 min to prompt warning
|
||||
RoomVacancyShutdownSeconds = 240; // 4 min after prompt will trigger shutdown prompt
|
||||
VacancyMode = eVacancyMode.None;
|
||||
|
||||
OnFeedback = new BoolFeedback(OnFeedbackFunc);
|
||||
|
||||
IsWarmingUpFeedback = new BoolFeedback(IsWarmingFeedbackFunc);
|
||||
IsCoolingDownFeedback = new BoolFeedback(IsCoolingFeedbackFunc);
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
if (RoomOccupancy != null)
|
||||
OnRoomOccupancyIsSet();
|
||||
});
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
Debug.Console(0, this, "ShutdwonPromptTimer Started. Type: {0}. Seconds: {1}", ShutdownType, ShutdownPromptTimer.SecondsToCount);
|
||||
}
|
||||
|
||||
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. Mode: {0}. Seconds: {1}", VacancyMode, RoomVacancyShutdownTimer.SecondsToCount);
|
||||
}
|
||||
|
||||
/// <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;
|
||||
|
||||
Debug.Console(1, this, "RoomVacancyShutdownSeconds set to {0}", RoomVacancyShutdownSeconds);
|
||||
|
||||
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>
|
||||
/// To allow base class to power room on to default source
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool RunDefaultPresentRoute();
|
||||
|
||||
void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
|
||||
{
|
||||
Debug.Console(1, this, "Notice: Vacancy Detected");
|
||||
// Trigger the timer when the room is vacant
|
||||
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "Notice: Occupancy Detected");
|
||||
// Reset the timer when the room is occupied
|
||||
RoomVacancyShutdownTimer.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes when RoomVacancyShutdownTimer expires. Used to trigger specific room actions as needed. Must nullify the timer object when executed
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
public abstract void RoomVacatedForTimeoutPeriod(object o);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To describe the various ways a room may be shutting down
|
||||
/// </summary>
|
||||
public enum eShutdownType
|
||||
{
|
||||
None = 0,
|
||||
External,
|
||||
Manual,
|
||||
Vacancy
|
||||
}
|
||||
|
||||
public enum eVacancyMode
|
||||
{
|
||||
None = 0,
|
||||
InInitialVacancy,
|
||||
InShutdownWarning
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum eWarmingCoolingMode
|
||||
{
|
||||
None,
|
||||
Warming,
|
||||
Cooling
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user