mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-15 12:44:58 +00:00
refactoring room classes
This commit is contained in:
@@ -1,9 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Collections.Generic;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
@@ -11,59 +9,15 @@ using PepperDash.Essentials.Room.Config;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials
|
namespace PepperDash.Essentials
|
||||||
{
|
{
|
||||||
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasCurrentVolumeControls, IHasDefaultDisplay
|
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IRunRouteAction,
|
||||||
{
|
IRunDefaultPresentRoute, IHasCurrentVolumeControls, IHasDefaultDisplay
|
||||||
//
|
{
|
||||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
public EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; private set; }
|
||||||
|
|
||||||
public EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; private set; }
|
/// <summary>
|
||||||
|
/// If room is off, enables power on to last source. Default true
|
||||||
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
/// </summary>
|
||||||
public IRoutingSink DefaultAudioDevice { get; private set; }
|
public bool EnablePowerOnToLastSource { get; set; }
|
||||||
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
|
||||||
|
|
||||||
public bool ExcludeFromGlobalFunctions { get; set; }
|
|
||||||
|
|
||||||
public string DefaultSourceItem { get; set; }
|
|
||||||
|
|
||||||
public ushort DefaultVolume { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// If room is off, enables power on to last source. Default true
|
|
||||||
/// </summary>
|
|
||||||
public bool EnablePowerOnToLastSource { get; set; }
|
|
||||||
string _lastSourceKey;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The SourceListItem last run - containing names and icons
|
|
||||||
/// </summary>
|
|
||||||
public SourceListItem CurrentSourceInfo
|
|
||||||
{
|
|
||||||
get { return _currentSourceInfo; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value == _currentSourceInfo) return;
|
|
||||||
|
|
||||||
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");
|
|
||||||
|
|
||||||
if (handler != null)
|
|
||||||
handler(_currentSourceInfo, ChangeType.WillChange);
|
|
||||||
|
|
||||||
_currentSourceInfo = value;
|
|
||||||
|
|
||||||
// add to in-use tracking
|
|
||||||
if (_currentSourceInfo != null && _currentSourceInfo.SourceDevice is IInUseTracking)
|
|
||||||
(_currentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
|
||||||
if (handler != null)
|
|
||||||
handler( _currentSourceInfo, ChangeType.DidChange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SourceListItem _currentSourceInfo;
|
|
||||||
|
|
||||||
public string CurrentSourceInfoKey { get; set; }
|
|
||||||
|
|
||||||
public EssentialsHuddleSpaceRoom(DeviceConfig config)
|
public EssentialsHuddleSpaceRoom(DeviceConfig config)
|
||||||
: base(config)
|
: base(config)
|
||||||
@@ -72,10 +26,12 @@ namespace PepperDash.Essentials
|
|||||||
{
|
{
|
||||||
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>
|
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>
|
||||||
(config.Properties.ToString());
|
(config.Properties.ToString());
|
||||||
DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
DefaultDisplay =
|
||||||
|
DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
||||||
|
|
||||||
|
|
||||||
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching;
|
DefaultAudioDevice =
|
||||||
|
DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching;
|
||||||
|
|
||||||
Initialize();
|
Initialize();
|
||||||
}
|
}
|
||||||
@@ -85,30 +41,36 @@ namespace PepperDash.Essentials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Initialize()
|
private void Initialize()
|
||||||
{
|
{
|
||||||
if (DefaultAudioDevice is IBasicVolumeControls)
|
if (DefaultAudioDevice is IBasicVolumeControls)
|
||||||
|
{
|
||||||
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||||
|
}
|
||||||
else if (DefaultAudioDevice is IHasVolumeDevice)
|
else if (DefaultAudioDevice is IHasVolumeDevice)
|
||||||
|
{
|
||||||
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
|
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
|
||||||
|
}
|
||||||
CurrentVolumeControls = DefaultVolumeControls;
|
CurrentVolumeControls = DefaultVolumeControls;
|
||||||
|
|
||||||
SourceListKey = "default";
|
SourceListKey = "default";
|
||||||
EnablePowerOnToLastSource = true;
|
EnablePowerOnToLastSource = true;
|
||||||
|
|
||||||
var disp = DefaultDisplay as DisplayBase;
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
if (disp == null) return;
|
if (disp == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
IsWarmingFeedbackFunc = () => disp.IsWarmingUpFeedback.BoolValue;
|
IsWarmingFeedbackFunc = () => disp.IsWarmingUpFeedback.BoolValue;
|
||||||
|
|
||||||
IsCoolingFeedbackFunc = () => disp.IsCoolingDownFeedback.BoolValue;
|
IsCoolingFeedbackFunc = () => disp.IsCoolingDownFeedback.BoolValue;
|
||||||
|
|
||||||
OnFeedbackFunc = () => CurrentSourceInfo != null
|
OnFeedbackFunc = () => CurrentSourceInfo != null
|
||||||
&& CurrentSourceInfo.Type == eSourceListItemType.Route;
|
&& CurrentSourceInfo.Type == eSourceListItemType.Route;
|
||||||
|
|
||||||
InitializeDisplay(disp);
|
InitializeDisplay(disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected override void IsCoolingDownFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
|
protected override void IsCoolingDownFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
|
||||||
{
|
{
|
||||||
@@ -119,7 +81,10 @@ namespace PepperDash.Essentials
|
|||||||
{
|
{
|
||||||
var display = sender as DisplayBase;
|
var display = sender as DisplayBase;
|
||||||
|
|
||||||
if (display == null) return;
|
if (display == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (display.PowerIsOnFeedback.BoolValue == OnFeedback.BoolValue)
|
if (display.PowerIsOnFeedback.BoolValue == OnFeedback.BoolValue)
|
||||||
{
|
{
|
||||||
@@ -156,10 +121,13 @@ namespace PepperDash.Essentials
|
|||||||
|
|
||||||
protected override void CustomSetConfig(DeviceConfig config)
|
protected override void CustomSetConfig(DeviceConfig config)
|
||||||
{
|
{
|
||||||
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>(config.Properties.ToString());
|
var newPropertiesConfig =
|
||||||
|
JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>(config.Properties.ToString());
|
||||||
|
|
||||||
if (newPropertiesConfig != null)
|
if (newPropertiesConfig != null)
|
||||||
|
{
|
||||||
PropertiesConfig = newPropertiesConfig;
|
PropertiesConfig = newPropertiesConfig;
|
||||||
|
}
|
||||||
|
|
||||||
ConfigWriter.UpdateRoomConfig(config);
|
ConfigWriter.UpdateRoomConfig(config);
|
||||||
}
|
}
|
||||||
@@ -173,7 +141,7 @@ namespace PepperDash.Essentials
|
|||||||
|
|
||||||
RunDefaultPresentRoute();
|
RunDefaultPresentRoute();
|
||||||
|
|
||||||
CrestronEnvironment.Sleep(1000);
|
//CrestronEnvironment.Sleep(1000); //why?
|
||||||
|
|
||||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room");
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room");
|
||||||
|
|
||||||
@@ -192,218 +160,38 @@ namespace PepperDash.Essentials
|
|||||||
}
|
}
|
||||||
|
|
||||||
RunRouteAction(DefaultSourceItem);
|
RunRouteAction(DefaultSourceItem);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CustomActivate()
|
public override bool CustomActivate()
|
||||||
{
|
{
|
||||||
// Add Occupancy object from config
|
// Add Occupancy object from config
|
||||||
if (PropertiesConfig.Occupancy != null)
|
if (PropertiesConfig.Occupancy != null)
|
||||||
|
{
|
||||||
SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||||
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||||
|
}
|
||||||
|
|
||||||
LogoUrl = PropertiesConfig.Logo.GetUrl();
|
LogoUrl = PropertiesConfig.Logo.GetUrl();
|
||||||
SourceListKey = PropertiesConfig.SourceListKey;
|
SourceListKey = PropertiesConfig.SourceListKey;
|
||||||
DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||||
DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
DefaultVolume = (ushort) (PropertiesConfig.Volumes.Master.Level*65535/100);
|
||||||
|
|
||||||
return base.CustomActivate();
|
return base.CustomActivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Will power the room on with the last-used source
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="routeKey"></param>
|
public override void PowerOnToDefaultOrLastSource()
|
||||||
public void RunRouteAction(string routeKey)
|
|
||||||
{
|
|
||||||
RunRouteAction(routeKey, () => { });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="routeKey"></param>
|
|
||||||
/// <param name="sourceListKey"></param>
|
|
||||||
public void RunRouteAction(string routeKey, string sourceListKey)
|
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="routeKey"></param>
|
|
||||||
/// <param name="sourceListKey"></param>
|
|
||||||
/// <param name="successCallback"></param>
|
|
||||||
public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
|
||||||
/// route or commands
|
|
||||||
/// </summary>
|
|
||||||
public void RunRouteAction(string routeKey, Action successCallback)
|
|
||||||
{
|
|
||||||
// Run this on a separate thread
|
|
||||||
//new CTimer
|
|
||||||
CrestronInvoke.BeginInvoke(o =>
|
|
||||||
{
|
{
|
||||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Run route action '{0}'", routeKey);
|
return;
|
||||||
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
}
|
||||||
if (dict == null)
|
RunRouteAction(LastSourceKey);
|
||||||
{
|
|
||||||
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to get the list item by it's string key
|
|
||||||
if (!dict.ContainsKey(routeKey))
|
|
||||||
{
|
|
||||||
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
|
||||||
routeKey, SourceListKey);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var item = dict[routeKey];
|
|
||||||
//Debug.Console(2, this, "Action {0} has {1} steps",
|
|
||||||
// item.SourceKey, item.RouteList.Count);
|
|
||||||
|
|
||||||
// End usage timer on last source
|
|
||||||
if (!string.IsNullOrEmpty(_lastSourceKey))
|
|
||||||
{
|
|
||||||
var lastSource = dict[_lastSourceKey].SourceDevice;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (lastSource is IUsageTracking)
|
|
||||||
(lastSource as IUsageTracking).UsageTracker.EndDeviceUsage();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking (257):\r{0}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let's run it
|
|
||||||
if (routeKey.ToLower() != "roomoff")
|
|
||||||
{
|
|
||||||
_lastSourceKey = routeKey;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CurrentSourceInfoKey = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var route in item.RouteList)
|
|
||||||
{
|
|
||||||
// if there is a $defaultAll on route, run two separate
|
|
||||||
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
// Going to assume a single-path route for now
|
|
||||||
var tempVideo = new SourceRouteListItem
|
|
||||||
{
|
|
||||||
DestinationKey = "$defaultDisplay",
|
|
||||||
SourceKey = route.SourceKey,
|
|
||||||
Type = eRoutingSignalType.Video
|
|
||||||
};
|
|
||||||
DoRoute(tempVideo);
|
|
||||||
|
|
||||||
//var tempAudio = new SourceRouteListItem
|
|
||||||
//{
|
|
||||||
// DestinationKey = "$defaultAudio",
|
|
||||||
// SourceKey = route.SourceKey,
|
|
||||||
// Type = eRoutingSignalType.Audio
|
|
||||||
//};
|
|
||||||
//DoRoute(tempAudio);
|
|
||||||
//continue; -- not sure why this was here
|
|
||||||
}
|
|
||||||
else
|
|
||||||
DoRoute(route);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start usage timer on routed source
|
|
||||||
if (item.SourceDevice is IUsageTracking)
|
|
||||||
{
|
|
||||||
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Set volume control, using default if non provided
|
|
||||||
IBasicVolumeControls volDev = null;
|
|
||||||
// Handle special cases for volume control
|
|
||||||
if (string.IsNullOrEmpty(item.VolumeControlKey)
|
|
||||||
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
|
|
||||||
volDev = DefaultVolumeControls;
|
|
||||||
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
|
||||||
volDev = DefaultDisplay as IBasicVolumeControls;
|
|
||||||
// Or a specific device, probably rarely used.
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
|
|
||||||
if (dev is IBasicVolumeControls)
|
|
||||||
volDev = dev as IBasicVolumeControls;
|
|
||||||
else if (dev is IHasVolumeDevice)
|
|
||||||
volDev = (dev as IHasVolumeDevice).VolumeDevice;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (volDev != CurrentVolumeControls)
|
|
||||||
{
|
|
||||||
// zero the volume on the device we are leaving.
|
|
||||||
// Set the volume to default on device we are entering
|
|
||||||
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
|
||||||
{
|
|
||||||
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
|
||||||
SavedVolumeLevels[vd] = (uint) vd.VolumeLevelFeedback.IntValue;
|
|
||||||
vd.SetVolume(0);
|
|
||||||
}
|
|
||||||
CurrentVolumeControls = volDev;
|
|
||||||
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
|
||||||
{
|
|
||||||
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
|
||||||
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort) SavedVolumeLevels[vd] : DefaultVolume);
|
|
||||||
vd.SetVolume(vol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// store the name and UI info for routes
|
|
||||||
if (item.SourceKey == "$off")
|
|
||||||
{
|
|
||||||
CurrentSourceInfoKey = routeKey;
|
|
||||||
CurrentSourceInfo = null;
|
|
||||||
}
|
|
||||||
else if (item.SourceKey != null)
|
|
||||||
{
|
|
||||||
CurrentSourceInfoKey = routeKey;
|
|
||||||
CurrentSourceInfo = item;
|
|
||||||
}
|
|
||||||
// And finally, set the "control". This will trigger event
|
|
||||||
//CurrentControlDevice = DeviceManager.GetDeviceForKey(item.SourceKey) as Device;
|
|
||||||
|
|
||||||
OnFeedback.FireUpdate();
|
|
||||||
|
|
||||||
// report back when done
|
|
||||||
if (successCallback != null)
|
|
||||||
successCallback();
|
|
||||||
|
|
||||||
}, 0); // end of CTimer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Will power the room on with the last-used source
|
|
||||||
/// </summary>
|
|
||||||
public override void PowerOnToDefaultOrLastSource()
|
|
||||||
{
|
|
||||||
if (!EnablePowerOnToLastSource || _lastSourceKey == null)
|
|
||||||
return;
|
|
||||||
RunRouteAction(_lastSourceKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Does what it says
|
/// Does what it says
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -412,64 +200,14 @@ namespace PepperDash.Essentials
|
|||||||
Debug.Console(1, this, "Restoring default levels");
|
Debug.Console(1, this, "Restoring default levels");
|
||||||
var vc = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
var vc = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
if (vc != null)
|
if (vc != null)
|
||||||
|
{
|
||||||
vc.SetVolume(DefaultVolume);
|
vc.SetVolume(DefaultVolume);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="route"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private bool DoRoute(SourceRouteListItem route)
|
|
||||||
{
|
|
||||||
IRoutingSink dest;
|
|
||||||
|
|
||||||
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
|
||||||
dest = DefaultAudioDevice;
|
|
||||||
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
|
||||||
dest = DefaultDisplay;
|
|
||||||
else
|
|
||||||
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink;
|
|
||||||
|
|
||||||
if (dest == null)
|
|
||||||
{
|
|
||||||
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
dest.ReleaseRoute();
|
|
||||||
if (dest is IPower)
|
|
||||||
(dest as IPower).PowerOff();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
|
||||||
if (source == null)
|
|
||||||
{
|
|
||||||
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
dest.ReleaseAndMakeRoute(source, route.Type);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void RoomVacatedForTimeoutPeriod(object o)
|
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||||
{
|
{
|
||||||
//Implement this
|
//TODO: Implement RoomVacatedForTimeoutPeriod
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// <summary>
|
|
||||||
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
|
||||||
/// </summary>
|
|
||||||
public static void AllRoomsOff()
|
|
||||||
{
|
|
||||||
var allRooms = DeviceManager.AllDevices.OfType<EssentialsHuddleSpaceRoom>().Where(d =>
|
|
||||||
!d.ExcludeFromGlobalFunctions);
|
|
||||||
foreach (var room in allRooms)
|
|
||||||
room.RunRouteAction("roomOff");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -331,7 +331,7 @@ namespace PepperDash.Essentials
|
|||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="routeKey"></param>
|
/// <param name="routeKey"></param>
|
||||||
public void RunRouteAction(string routeKey)
|
public override void RunRouteAction(string routeKey)
|
||||||
{
|
{
|
||||||
RunRouteAction(routeKey, () => { });
|
RunRouteAction(routeKey, () => { });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using PepperDash.Essentials.Core.Devices;
|
using PepperDash.Essentials.Core.Devices;
|
||||||
@@ -9,9 +11,21 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class EssentialsRoomBase : ReconfigurableDevice
|
public abstract class EssentialsRoomBase : ReconfigurableDevice, IHasCurrentSourceInfoChange
|
||||||
{
|
{
|
||||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||||
|
public string CurrentSourceInfoKey { get; set; }
|
||||||
|
|
||||||
|
public IRoutingSinkWithSwitching DefaultDisplay { get; protected set; }
|
||||||
|
public IRoutingSink DefaultAudioDevice { get; protected set; }
|
||||||
|
public IBasicVolumeControls DefaultVolumeControls { get; protected set; }
|
||||||
|
|
||||||
|
protected CCriticalSection RoutingLock = new CCriticalSection();
|
||||||
|
|
||||||
|
public string DefaultSourceItem { get; set; }
|
||||||
|
|
||||||
|
public ushort DefaultVolume { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the volume control device, and attaches/removes InUseTrackers with "audio"
|
/// Sets the volume control device, and attaches/removes InUseTrackers with "audio"
|
||||||
@@ -31,8 +45,10 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
{
|
{
|
||||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(CurrentAudioDevice, value, ChangeType.WillChange));
|
CurrentVolumeDeviceChange(this,
|
||||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(CurrentAudioDevice, value, ChangeType.DidChange));
|
new VolumeDeviceChangeEventArgs(CurrentAudioDevice, value, ChangeType.WillChange));
|
||||||
|
CurrentVolumeDeviceChange(this,
|
||||||
|
new VolumeDeviceChangeEventArgs(CurrentAudioDevice, value, ChangeType.DidChange));
|
||||||
}
|
}
|
||||||
|
|
||||||
var oldDevice = value as IInUseTracking;
|
var oldDevice = value as IInUseTracking;
|
||||||
@@ -43,6 +59,52 @@ namespace PepperDash.Essentials.Core
|
|||||||
CurrentAudioDevice = value;
|
CurrentAudioDevice = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected string LastSourceKey;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The SourceListItem last run - containing names and icons
|
||||||
|
/// </summary>
|
||||||
|
public SourceListItem CurrentSourceInfo
|
||||||
|
{
|
||||||
|
get { return _currentSourceInfo; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _currentSourceInfo)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
handler(_currentSourceInfo, ChangeType.WillChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentSourceInfo = value;
|
||||||
|
|
||||||
|
// add to in-use tracking
|
||||||
|
if (_currentSourceInfo != null && _currentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
{
|
||||||
|
(_currentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||||
|
}
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
handler(_currentSourceInfo, ChangeType.DidChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private SourceListItem _currentSourceInfo;
|
||||||
|
|
||||||
|
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||||
|
|
||||||
protected IBasicVolumeControls CurrentAudioDevice;
|
protected IBasicVolumeControls CurrentAudioDevice;
|
||||||
|
|
||||||
public BoolFeedback OnFeedback { get; private set; }
|
public BoolFeedback OnFeedback { get; private set; }
|
||||||
@@ -61,6 +123,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
protected Func<bool> IsWarmingFeedbackFunc;
|
protected Func<bool> IsWarmingFeedbackFunc;
|
||||||
protected Func<bool> IsCoolingFeedbackFunc;
|
protected Func<bool> IsCoolingFeedbackFunc;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The config name of the source list
|
/// The config name of the source list
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -100,42 +163,21 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected Func<bool> OnFeedbackFunc;
|
protected Func<bool> OnFeedbackFunc;
|
||||||
|
|
||||||
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; }
|
||||||
|
|
||||||
|
|
||||||
protected EssentialsRoomBase(DeviceConfig config)
|
protected EssentialsRoomBase(DeviceConfig config)
|
||||||
: base(config)
|
: base(config)
|
||||||
{
|
{
|
||||||
// Setup the ShutdownPromptTimer
|
SetupShutdownPrompt();
|
||||||
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;
|
SetupRoomVacancyShutdown();
|
||||||
ShutdownVacancySeconds = 120;
|
|
||||||
|
|
||||||
ShutdownType = eShutdownType.None;
|
|
||||||
|
|
||||||
RoomVacancyShutdownTimer = new SecondsCountdownTimer(Key + "-vacancyOffTimer");
|
|
||||||
//RoomVacancyShutdownTimer.IsRunningFeedback.OutputChange += (o, a) =>
|
|
||||||
//{
|
|
||||||
// if (!RoomVacancyShutdownTimer.IsRunningFeedback.BoolValue)
|
|
||||||
// ShutdownType = ShutdownType.Vacancy;
|
|
||||||
//};
|
|
||||||
RoomVacancyShutdownTimer.HasFinished += 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);
|
OnFeedback = new BoolFeedback(OnFeedbackFunc);
|
||||||
|
|
||||||
@@ -145,10 +187,42 @@ namespace PepperDash.Essentials.Core
|
|||||||
AddPostActivationAction(() =>
|
AddPostActivationAction(() =>
|
||||||
{
|
{
|
||||||
if (RoomOccupancy != null)
|
if (RoomOccupancy != null)
|
||||||
|
{
|
||||||
OnRoomOccupancyIsSet();
|
OnRoomOccupancyIsSet();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetupRoomVacancyShutdown()
|
||||||
|
{
|
||||||
|
RoomVacancyShutdownTimer = new SecondsCountdownTimer(Key + "-vacancyOffTimer");
|
||||||
|
|
||||||
|
RoomVacancyShutdownTimer.HasFinished += 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupShutdownPrompt()
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
protected void InitializeDisplay(DisplayBase display)
|
protected void InitializeDisplay(DisplayBase display)
|
||||||
{
|
{
|
||||||
// Link power, warming, cooling to display
|
// Link power, warming, cooling to display
|
||||||
@@ -188,11 +262,11 @@ namespace PepperDash.Essentials.Core
|
|||||||
StartRoomVacancyTimer(eVacancyMode.InShutdownWarning);
|
StartRoomVacancyTimer(eVacancyMode.InShutdownWarning);
|
||||||
break;
|
break;
|
||||||
case eVacancyMode.InShutdownWarning:
|
case eVacancyMode.InShutdownWarning:
|
||||||
{
|
{
|
||||||
StartShutdown(eShutdownType.Vacancy);
|
StartShutdown(eShutdownType.Vacancy);
|
||||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting Down due to vacancy.");
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting Down due to vacancy.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +290,8 @@ namespace PepperDash.Essentials.Core
|
|||||||
ShutdownType = type;
|
ShutdownType = type;
|
||||||
ShutdownPromptTimer.Start();
|
ShutdownPromptTimer.Start();
|
||||||
|
|
||||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "ShutdownPromptTimer Started. Type: {0}. Seconds: {1}", ShutdownType, ShutdownPromptTimer.SecondsToCount);
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "ShutdownPromptTimer Started. Type: {0}. Seconds: {1}",
|
||||||
|
ShutdownType, ShutdownPromptTimer.SecondsToCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartRoomVacancyTimer(eVacancyMode mode)
|
public void StartRoomVacancyTimer(eVacancyMode mode)
|
||||||
@@ -236,7 +311,8 @@ namespace PepperDash.Essentials.Core
|
|||||||
VacancyMode = mode;
|
VacancyMode = mode;
|
||||||
RoomVacancyShutdownTimer.Start();
|
RoomVacancyShutdownTimer.Start();
|
||||||
|
|
||||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Vacancy Timer Started. Mode: {0}. Seconds: {1}", VacancyMode, RoomVacancyShutdownTimer.SecondsToCount);
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Vacancy Timer Started. Mode: {0}. Seconds: {1}",
|
||||||
|
VacancyMode, RoomVacancyShutdownTimer.SecondsToCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -269,23 +345,28 @@ namespace PepperDash.Essentials.Core
|
|||||||
{
|
{
|
||||||
var provider = statusProvider as IKeyed;
|
var provider = statusProvider as IKeyed;
|
||||||
|
|
||||||
if (provider == null)
|
if (provider == null)
|
||||||
{
|
{
|
||||||
Debug.Console(0, this, "ERROR: Occupancy sensor device is null");
|
Debug.Console(0, this, "ERROR: Occupancy sensor device is null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Room Occupancy set to device: '{0}'", provider.Key);
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Room Occupancy set to device: '{0}'", provider.Key);
|
||||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Timeout Minutes from Config is: {0}", timeoutMinutes);
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Timeout Minutes from Config is: {0}", timeoutMinutes);
|
||||||
|
|
||||||
// If status provider is fusion, set flag to remote
|
// If status provider is fusion, set flag to remote
|
||||||
if (statusProvider is Fusion.EssentialsHuddleSpaceFusionSystemControllerBase)
|
if (statusProvider is Fusion.EssentialsHuddleSpaceFusionSystemControllerBase)
|
||||||
|
{
|
||||||
OccupancyStatusProviderIsRemote = true;
|
OccupancyStatusProviderIsRemote = true;
|
||||||
|
}
|
||||||
|
|
||||||
if(timeoutMinutes > 0)
|
if (timeoutMinutes > 0)
|
||||||
RoomVacancyShutdownSeconds = timeoutMinutes * 60;
|
{
|
||||||
|
RoomVacancyShutdownSeconds = timeoutMinutes*60;
|
||||||
|
}
|
||||||
|
|
||||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "RoomVacancyShutdownSeconds set to {0}", RoomVacancyShutdownSeconds);
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "RoomVacancyShutdownSeconds set to {0}",
|
||||||
|
RoomVacancyShutdownSeconds);
|
||||||
|
|
||||||
RoomOccupancy = statusProvider;
|
RoomOccupancy = statusProvider;
|
||||||
|
|
||||||
@@ -295,11 +376,13 @@ namespace PepperDash.Essentials.Core
|
|||||||
OnRoomOccupancyIsSet();
|
OnRoomOccupancyIsSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnRoomOccupancyIsSet()
|
private void OnRoomOccupancyIsSet()
|
||||||
{
|
{
|
||||||
var handler = RoomOccupancyIsSet;
|
var handler = RoomOccupancyIsSet;
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
|
{
|
||||||
handler(this, new EventArgs());
|
handler(this, new EventArgs());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -313,7 +396,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public abstract bool RunDefaultPresentRoute();
|
public abstract bool RunDefaultPresentRoute();
|
||||||
|
|
||||||
void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
|
private void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
|
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
|
||||||
{
|
{
|
||||||
@@ -334,8 +417,303 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="o"></param>
|
/// <param name="o"></param>
|
||||||
public abstract void RoomVacatedForTimeoutPeriod(object o);
|
public abstract void RoomVacatedForTimeoutPeriod(object o);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
public virtual void RunRouteAction(string routeKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, String.Empty, () => { });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||||
|
/// route or commands
|
||||||
|
/// </summary>
|
||||||
|
public virtual void RunRouteAction(string routeKey, Action successCallback)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, String.Empty, successCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
/// <param name="sourceListKey"></param>
|
||||||
|
public virtual void RunRouteAction(string routeKey, string sourceListKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, sourceListKey, () => { });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
/// <param name="sourceListKey"></param>
|
||||||
|
/// <param name="successCallback"></param>
|
||||||
|
public virtual void RunRouteAction(string routeKey, string sourceListKey, Action successCallback)
|
||||||
|
{
|
||||||
|
var routeObject =
|
||||||
|
new {RouteKey = routeKey, SourceListKey = sourceListKey, SuccessCallback = successCallback};
|
||||||
|
CrestronInvoke.BeginInvoke(RunRouteAction, routeObject); // end of BeginInvoke
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void RunRouteAction(object routeObject)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RoutingLock.Enter();
|
||||||
|
|
||||||
|
var routeObj = new {RouteKey = "", SourceListKey = "", SuccessCallback = new Action(() => { })};
|
||||||
|
|
||||||
|
routeObj = Cast(routeObj, routeObject);
|
||||||
|
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Run route action '{0}'", routeObj.RouteKey);
|
||||||
|
var sourceList = GetSourceListForKey(routeObj.RouteKey, routeObj.SourceListKey);
|
||||||
|
|
||||||
|
if (sourceList == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "No source list found for key {0}", routeObj.SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = sourceList[routeObj.RouteKey];
|
||||||
|
|
||||||
|
// End usage timer on last source
|
||||||
|
StopUsageTrackingOnCurrentSource(sourceList);
|
||||||
|
|
||||||
|
// Let's run it
|
||||||
|
if (routeObj.RouteKey.ToLower() != "roomoff")
|
||||||
|
{
|
||||||
|
LastSourceKey = routeObj.RouteKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var route in item.RouteList)
|
||||||
|
{
|
||||||
|
var tempVideo = new SourceRouteListItem
|
||||||
|
{
|
||||||
|
DestinationKey = "$defaultDisplay",
|
||||||
|
SourceKey = route.SourceKey,
|
||||||
|
Type = eRoutingSignalType.Video
|
||||||
|
};
|
||||||
|
|
||||||
|
var routeItem = route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase)
|
||||||
|
? tempVideo
|
||||||
|
: route;
|
||||||
|
|
||||||
|
DoRoute(routeItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start usage timer on routed source
|
||||||
|
if (item.SourceDevice is IUsageTracking)
|
||||||
|
{
|
||||||
|
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set volume control, using default if non provided
|
||||||
|
SetVolumeControl(item);
|
||||||
|
|
||||||
|
// store the name and UI info for routes
|
||||||
|
if (item.SourceKey == "$off")
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeObj.RouteKey;
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
}
|
||||||
|
else if (item.SourceKey != null)
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeObj.RouteKey;
|
||||||
|
CurrentSourceInfo = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
// report back when done
|
||||||
|
if (routeObj.SuccessCallback != null)
|
||||||
|
{
|
||||||
|
routeObj.SuccessCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
RoutingLock.Leave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static T Cast<T>(T typeHolder, object m)
|
||||||
|
{
|
||||||
|
return (T) m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected void DoRoute(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
var dest = GetDestination(route);
|
||||||
|
|
||||||
|
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest.ReleaseRoute();
|
||||||
|
if (dest is IPower)
|
||||||
|
{
|
||||||
|
(dest as IPower).PowerOff();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey,
|
||||||
|
route.DestinationKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IRoutingSink GetDestination(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
IRoutingSink dest;
|
||||||
|
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest = DefaultAudioDevice;
|
||||||
|
}
|
||||||
|
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest = DefaultDisplay;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dest != null)
|
||||||
|
{
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetVolumeControl(SourceListItem item)
|
||||||
|
{
|
||||||
|
IBasicVolumeControls volDev = null;
|
||||||
|
// Handle special cases for volume control
|
||||||
|
if (string.IsNullOrEmpty(item.VolumeControlKey)
|
||||||
|
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
volDev = DefaultVolumeControls;
|
||||||
|
}
|
||||||
|
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
volDev = DefaultDisplay as IBasicVolumeControls;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
|
||||||
|
if (dev is IBasicVolumeControls)
|
||||||
|
{
|
||||||
|
volDev = dev as IBasicVolumeControls;
|
||||||
|
}
|
||||||
|
else if (dev is IHasVolumeDevice)
|
||||||
|
{
|
||||||
|
volDev = (dev as IHasVolumeDevice).VolumeDevice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volDev == CurrentVolumeControls)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IBasicVolumeWithFeedback vd;
|
||||||
|
// zero the volume on the device we are leaving.
|
||||||
|
// Set the volume to default on device we are entering
|
||||||
|
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||||
|
{
|
||||||
|
vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
SavedVolumeLevels[vd] = (uint) vd.VolumeLevelFeedback.IntValue;
|
||||||
|
vd.SetVolume(0);
|
||||||
|
}
|
||||||
|
CurrentVolumeControls = volDev;
|
||||||
|
if (!ZeroVolumeWhenSwtichingVolumeDevices || !(CurrentVolumeControls is IBasicVolumeWithFeedback))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
var vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort) SavedVolumeLevels[vd] : DefaultVolume);
|
||||||
|
vd.SetVolume(vol);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StopUsageTrackingOnCurrentSource(Dictionary<string, SourceListItem> sourceList)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(LastSourceKey))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastSource = sourceList[LastSourceKey].SourceDevice;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (lastSource is IUsageTracking)
|
||||||
|
{
|
||||||
|
(lastSource as IUsageTracking).UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking (257):\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, SourceListItem> GetSourceListForKey(string routeKey, string sourceListKey)
|
||||||
|
{
|
||||||
|
var slKey = String.IsNullOrEmpty(sourceListKey) ? SourceListKey : sourceListKey;
|
||||||
|
|
||||||
|
var sourceList = ConfigReader.ConfigObject.GetSourceListForKey(slKey);
|
||||||
|
|
||||||
|
if (sourceList == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", slKey);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get the list item by it's string key
|
||||||
|
if (sourceList.ContainsKey(routeKey))
|
||||||
|
{
|
||||||
|
return sourceList;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(1, this, "WARNING: No source list '{0}' found in config source lists '{1}'",
|
||||||
|
routeKey, SourceListKey);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||||
|
/// </summary>
|
||||||
|
public static void AllRoomsOff()
|
||||||
|
{
|
||||||
|
var allRooms = DeviceManager.AllDevices.OfType<EssentialsRoomBase>().Where(d =>
|
||||||
|
!d.ExcludeFromGlobalFunctions);
|
||||||
|
foreach (var room in allRooms)
|
||||||
|
{
|
||||||
|
room.RunRouteAction("roomOff");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// To describe the various ways a room may be shutting down
|
/// To describe the various ways a room may be shutting down
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RoutingOutputPort : RoutingPort
|
public class RoutingOutputPort : RoutingPort, IInUseTracking
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The IRoutingOutputs object this port lives on
|
/// The IRoutingOutputs object this port lives on
|
||||||
|
|||||||
Reference in New Issue
Block a user