Mega refactor in progress

This commit is contained in:
Neil Dorin
2019-10-23 22:29:04 -06:00
parent 407a354cfe
commit 13132c29fc
38 changed files with 1068 additions and 1369 deletions

View File

@@ -19,42 +19,3 @@ namespace PepperDash.Essentials.Room.Cotija
}
}
namespace PepperDash.Essentials
{
/// <summary>
/// For rooms with a single presentation source, change event
/// </summary>
public interface IHasCurrentSourceInfoChange
{
string CurrentSourceInfoKey { get; }
SourceListItem CurrentSourceInfo { get; }
event SourceInfoChangeHandler CurrentSingleSourceChange;
}
/// <summary>
/// For rooms with routing
/// </summary>
public interface IRunRouteAction
{
void RunRouteAction(string routeKey);
void RunRouteAction(string routeKey, Action successCallback);
}
/// <summary>
/// For rooms that default presentation only routing
/// </summary>
public interface IRunDefaultPresentRoute
{
bool RunDefaultPresentRoute();
}
/// <summary>
/// For rooms that have default presentation and calling routes
/// </summary>
public interface IRunDefaultCallRoute : IRunDefaultPresentRoute
{
bool RunDefaultCallRoute();
}
}

View File

@@ -93,7 +93,7 @@ namespace PepperDash.Essentials
var sscRoom = Room as IHasCurrentSourceInfoChange;
if(sscRoom != null)
sscRoom.CurrentSingleSourceChange += new SourceInfoChangeHandler(Room_CurrentSingleSourceChange);
sscRoom.CurrentSingleDisplaySourceChange += new SourceInfoChangeHandler(Room_CurrentSingleSourceChange);
var vcRoom = Room as IHasVideoCodec;
if (vcRoom != null && vcRoom.VideoCodec != null)

View File

@@ -14,6 +14,7 @@ using PepperDash.Core;
using PepperDash.Essentials;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Core.Fusion;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.Devices.Common.Occupancy;
@@ -181,7 +182,7 @@ namespace PepperDash.Essentials.Fusion
// Moved to
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", eSigIoMask.InputSigOnly);
// Don't think we need to get current status of this as nothing should be alive yet.
(Room as EssentialsHuddleVtc1Room).CurrentSingleSourceChange += Room_CurrentSourceInfoChange;
(Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange;
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
@@ -220,7 +221,7 @@ namespace PepperDash.Essentials.Fusion
break;
}
var laptops = dict.Where(d => d.Value.SourceDevice is Laptop);
var laptops = dict.Where(d => d.Value.SourceDevice is Core.Devices.Laptop);
i = 1;
foreach (var kvp in laptops)
{

View File

@@ -173,16 +173,11 @@
<Compile Include="Devices\NUMERIC AppleTV.cs" />
<Compile Include="ControlSystem.cs" />
<Compile Include="Factory\UiDeviceFactory.cs" />
<Compile Include="FOR REFERENCE UI\OTHER\Fusion\EssentialsHuddleVtc1FusionController.cs" />
<Compile Include="FOR REFERENCE UI\OTHER\Fusion\FusionCustomPropertiesBridge.cs" />
<Compile Include="FOR REFERENCE UI\OTHER\Fusion\FusionEventHandlers.cs" />
<Compile Include="FOR REFERENCE UI\OTHER\Fusion\FusionProcessorQueries.cs" />
<Compile Include="FOR REFERENCE UI\OTHER\Fusion\FusionRviDataClasses.cs" />
<Compile Include="Fusion\EssentialsHuddleVtc1FusionController.cs" />
<Compile Include="REMOVE EssentialsApp.cs" />
<Compile Include="FOR REFERENCE UI\OTHER\Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs" />
<Compile Include="HttpApiHandler.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Room\Behaviours\RoomOnToDefaultSourceWhenOccupied.cs" />
<Compile Include="Room\Config\EssentialsDualDisplayRoomPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsNDisplayRoomPropertiesConfig.cs" />
<Compile Include="Room\Config\DDVC01RoomPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsPresentationPropertiesConfig.cs" />
@@ -206,10 +201,10 @@
<Compile Include="AppServer\RoomBridges\SourceDeviceMapDictionary.cs" />
<Compile Include="AppServer\Volumes.cs" />
<Compile Include="Room\Emergency\EsentialsRoomEmergencyContactClosure.cs" />
<Compile Include="Room\Types\EssentialsDualDisplayRoom.cs" />
<Compile Include="Room\Types\EssentialsHuddleVtc1Room.cs" />
<Compile Include="Room\Types\EssentialsNDisplayRoomBase.cs" />
<Compile Include="Room\Types\EssentialsPresentationRoom.cs" />
<Compile Include="Room\Types\EssentialsRoomBase.cs" />
<Compile Include="Room\Config\EssentialsRoomConfig.cs" />
<Compile Include="FOR REFERENCE UI\PageControllers\DevicePageControllerBase.cs" />
<Compile Include="FOR REFERENCE UI\PageControllers\PageControllerLaptop.cs" />
@@ -273,6 +268,9 @@
<Name>Essentials Devices Common</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="FOR REFERENCE UI\OTHER\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>

View File

@@ -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";
}
}

View File

@@ -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; }
}
}

View File

@@ -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>();
}
}
}

View File

@@ -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; }

View File

@@ -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

View 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;
};
}
}
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -25,8 +25,8 @@ namespace PepperDash.Essentials
public void RegisterForSourceChange(IHasCurrentSourceInfoChange room)
{
room.CurrentSingleSourceChange -= room_CurrentSourceInfoChange;
room.CurrentSingleSourceChange += room_CurrentSourceInfoChange;
room.CurrentSingleDisplaySourceChange -= room_CurrentSourceInfoChange;
room.CurrentSingleDisplaySourceChange += room_CurrentSourceInfoChange;
}
void room_CurrentSourceInfoChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)

View File

@@ -733,7 +733,7 @@ namespace PepperDash.Essentials
// Disconnect current room
_CurrentRoom.CurrentVolumeDeviceChange -= this.CurrentRoom_CurrentAudioDeviceChange;
ClearAudioDeviceConnections();
_CurrentRoom.CurrentSingleSourceChange -= this.CurrentRoom_SourceInfoChange;
_CurrentRoom.CurrentSourceChange -= this.CurrentRoom_SourceInfoChange;
DisconnectSource(_CurrentRoom.CurrentSourceInfo);
_CurrentRoom.ShutdownPromptTimer.HasStarted -= ShutdownPromptTimer_HasStarted;
_CurrentRoom.ShutdownPromptTimer.HasFinished -= ShutdownPromptTimer_HasFinished;
@@ -803,7 +803,7 @@ namespace PepperDash.Essentials
_CurrentRoom.CurrentVolumeDeviceChange += CurrentRoom_CurrentAudioDeviceChange;
RefreshAudioDeviceConnections();
_CurrentRoom.CurrentSingleSourceChange += CurrentRoom_SourceInfoChange;
_CurrentRoom.CurrentSourceChange += CurrentRoom_SourceInfoChange;
RefreshSourceInfo();
(Parent as EssentialsPanelMainInterfaceDriver).HeaderDriver.SetupHeaderButtons(this, CurrentRoom);

View File

@@ -885,7 +885,7 @@ namespace PepperDash.Essentials
// Disconnect current room
_CurrentRoom.CurrentVolumeDeviceChange -= this.CurrentRoom_CurrentAudioDeviceChange;
ClearAudioDeviceConnections();
_CurrentRoom.CurrentSingleSourceChange -= this.CurrentRoom_SourceInfoChange;
_CurrentRoom.CurrentSourceChange -= this.CurrentRoom_SourceInfoChange;
DisconnectSource(_CurrentRoom.CurrentSourceInfo);
_CurrentRoom.ShutdownPromptTimer.HasStarted -= ShutdownPromptTimer_HasStarted;
_CurrentRoom.ShutdownPromptTimer.HasFinished -= ShutdownPromptTimer_HasFinished;
@@ -924,7 +924,7 @@ namespace PepperDash.Essentials
_CurrentRoom.CurrentVolumeDeviceChange += CurrentRoom_CurrentAudioDeviceChange;
RefreshAudioDeviceConnections();
_CurrentRoom.CurrentSingleSourceChange += CurrentRoom_SourceInfoChange;
_CurrentRoom.CurrentSourceChange += CurrentRoom_SourceInfoChange;
RefreshSourceInfo();
if (_CurrentRoom.VideoCodec is IHasScheduleAwareness)
@@ -939,7 +939,7 @@ namespace PepperDash.Essentials
SetActiveCallListSharingContentStatus();
if (_CurrentRoom != null)
_CurrentRoom.CurrentSingleSourceChange += new SourceInfoChangeHandler(CurrentRoom_CurrentSingleSourceChange);
_CurrentRoom.CurrentSourceChange += new SourceInfoChangeHandler(CurrentRoom_CurrentSingleSourceChange);
TriList.SetSigFalseAction(UIBoolJoin.CallStopSharingPress, () => _CurrentRoom.RunRouteAction("codecOsd"));

View File

@@ -64,7 +64,7 @@ namespace PepperDash.Essentials
parent.SetItemMainText(index, room.Name);
UpdateItem(room.CurrentSourceInfo);
// Watch for later changes
room.CurrentSingleSourceChange += new SourceInfoChangeHandler(room_CurrentSourceInfoChange);
room.CurrentSourceChange += new SourceInfoChangeHandler(room_CurrentSourceInfoChange);
parent.SetItemButtonAction(index, buttonAction);
}

View File

@@ -9,8 +9,8 @@ using PepperDash.Essentials.Core;
namespace PepperDash.Essentials
{
/// <summary>
/// The handler type for a Room's SourceInfoChange
/// </summary>
public delegate void SourceInfoChangeHandler(EssentialsRoomBase room, SourceListItem info, ChangeType type);
///// <summary>
///// The handler type for a Room's SourceInfoChange
///// </summary>
//public delegate void SourceInfoChangeHandler(EssentialsRoomBase room, SourceListItem info, ChangeType type);
}

View File

@@ -7,7 +7,7 @@ using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Routing;
using PepperDash.Core;
namespace PepperDash.Essentials.Devices.Common
namespace PepperDash.Essentials.Core.Devices
{
/// <summary>
/// This DVD class should cover most IR, one-way DVD and Bluray fuctions

View File

@@ -7,7 +7,7 @@ using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Routing;
using PepperDash.Core;
namespace PepperDash.Essentials.Devices.Common
namespace PepperDash.Essentials.Core.Devices
{
/// <summary>
/// This DVD class should cover most IR, one-way DVD and Bluray fuctions

View File

@@ -18,6 +18,11 @@ namespace PepperDash.Essentials.Core
/// </summary>
public abstract class DisplayBase : Device, IHasFeedback, IRoutingSinkWithSwitching, IPower, IWarmingCooling, IUsageTracking
{
public event SourceInfoChangeHandler CurrentSourceChange;
public string CurrentSourceInfoKey { get; protected set; }
public SourceListItem CurrentSourceInfo { get; protected set; }
public BoolFeedback PowerIsOnFeedback { get; protected set; }
public BoolFeedback IsCoolingDownFeedback { get; protected set; }
public BoolFeedback IsWarmingUpFeedback { get; private set; }

View File

@@ -18,12 +18,10 @@ using PepperDash.Core;
using PepperDash.Essentials;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.Devices.Common.Occupancy;
namespace PepperDash.Essentials.Fusion
namespace PepperDash.Essentials.Core.Fusion
{
public class EssentialsHuddleSpaceFusionSystemControllerBase : Device, IOccupancyStatusProvider
{
@@ -330,11 +328,11 @@ namespace PepperDash.Essentials.Fusion
// Moved to
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", eSigIoMask.InputSigOnly);
// Don't think we need to get current status of this as nothing should be alive yet.
(Room as EssentialsHuddleSpaceRoom).CurrentSingleSourceChange += new SourceInfoChangeHandler(Room_CurrentSourceInfoChange);
(Room as IHasCurrentSourceInfoChange).CurrentSourceChange += new SourceInfoChangeHandler(Room_CurrentSourceInfoChange);
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleSpaceRoom).PowerOnToDefaultOrLastSource);
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff"));
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsRoomBase).PowerOnToDefaultOrLastSource);
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as IRunRouteAction).RunRouteAction("roomOff"));
// NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
FusionRoom.ErrorMessage.InputSig.StringValue =
"3: 7 Errors: This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;";
@@ -990,7 +988,7 @@ namespace PepperDash.Essentials.Fusion
protected virtual void SetUpSources()
{
// Sources
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleSpaceRoom).SourceListKey);
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsRoomBase).SourceListKey);
if (dict != null)
{
// NEW PROCESS:
@@ -1015,7 +1013,7 @@ namespace PepperDash.Essentials.Fusion
break;
}
var laptops = dict.Where(d => d.Value.SourceDevice is Laptop);
var laptops = dict.Where(d => d.Value.SourceDevice is Devices.Laptop);
i = 1;
foreach (var kvp in laptops)
{
@@ -1041,7 +1039,7 @@ namespace PepperDash.Essentials.Fusion
else
{
Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
(Room as EssentialsHuddleSpaceRoom).SourceListKey, Room.Key);
(Room as EssentialsRoomBase).SourceListKey, Room.Key);
}
}
@@ -1088,7 +1086,7 @@ namespace PepperDash.Essentials.Fusion
SourceToFeedbackSigs.Add(pSrc, sigD.InputSig);
// And respond to selection in Fusion
sigD.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleSpaceRoom).RunRouteAction(routeKey));
sigD.OutputSig.SetSigFalseAction(() => (Room as IRunRouteAction).RunRouteAction(routeKey));
}
catch (Exception)
{
@@ -1290,7 +1288,7 @@ namespace PepperDash.Essentials.Fusion
// Current Source
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b => { if (!b) (Room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff"); }); ;
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b => { if (!b) (Room as IRunRouteAction).RunRouteAction("roomOff"); }); ;
}
}

View File

@@ -10,9 +10,8 @@ using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Room.Behaviours;
namespace PepperDash.Essentials.Fusion
namespace PepperDash.Essentials.Core.Fusion
{
/// <summary>
/// Handles mapping Fusion Custom Property values to system properties

View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Fusion
namespace PepperDash.Essentials.Core.Fusion
{
public class ScheduleChangeEventArgs : EventArgs
{

View File

@@ -4,9 +4,8 @@ using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Fusion
namespace PepperDash.Essentials.Core.Fusion
{
/// <summary>
/// When created, runs progcomments on every slot and stores the program names in a list

View File

@@ -7,7 +7,7 @@ using Crestron.SimplSharpPro.Fusion;
using PepperDash.Core;
namespace PepperDash.Essentials.Fusion
namespace PepperDash.Essentials.Core.Fusion
{
// Helper Classes for GUIDs

View File

@@ -1,377 +0,0 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using Crestron.SimplSharp;
//using Crestron.SimplSharpPro;
//using Crestron.SimplSharpPro.DeviceSupport;
//using Crestron.SimplSharpPro.Fusion;
//using PepperDash.Essentials.Core;
//using PepperDash.Core;
//namespace PepperDash.Essentials.Core.Fusion
//{
// public class EssentialsHuddleSpaceFusionSystemController : Device
// {
// FusionRoom FusionRoom;
// Room Room;
// Dictionary<IPresentationSource, BoolInputSig> SourceToFeedbackSigs = new Dictionary<IPresentationSource, BoolInputSig>();
// StatusMonitorCollection ErrorMessageRollUp;
// public EssentialsHuddleSpaceFusionSystemController(HuddleSpaceRoom room, uint ipId)
// : base(room.Key + "-fusion")
// {
// Room = room;
// FusionRoom = new FusionRoom(ipId, Global.ControlSystem, room.Name, "awesomeGuid-" + room.Key);
// FusionRoom.Register();
// FusionRoom.FusionStateChange += new FusionStateEventHandler(FusionRoom_FusionStateChange);
// // Room to fusion room
// room.RoomIsOn.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
// var srcName = FusionRoom.CreateOffsetStringSig(50, "Source - Name", eSigIoMask.InputSigOnly);
// room.CurrentSourceName.LinkInputSig(srcName.InputSig);
// FusionRoom.SystemPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (b) room.RoomOn(null); });
// FusionRoom.SystemPowerOff.OutputSig.UserObject = new Action<bool>(b => { if (b) room.RoomOff(); });
// // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
// FusionRoom.ErrorMessage.InputSig.StringValue = "3: 7 Errors: This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;";
// // Sources
// foreach (var src in room.Sources)
// {
// var srcNum = src.Key;
// var pSrc = src.Value as IPresentationSource;
// var keyNum = ExtractNumberFromKey(pSrc.Key);
// if (keyNum == -1)
// {
// Debug.Console(1, this, "WARNING: Cannot link source '{0}' to numbered Fusion attributes", pSrc.Key);
// continue;
// }
// string attrName = null;
// uint attrNum = Convert.ToUInt32(keyNum);
// switch (pSrc.Type)
// {
// case PresentationSourceType.None:
// break;
// case PresentationSourceType.SetTopBox:
// attrName = "Source - TV " + keyNum;
// attrNum += 115; // TV starts at 116
// break;
// case PresentationSourceType.Dvd:
// attrName = "Source - DVD " + keyNum;
// attrNum += 120; // DVD starts at 121
// break;
// case PresentationSourceType.PC:
// attrName = "Source - PC " + keyNum;
// attrNum += 110; // PC starts at 111
// break;
// case PresentationSourceType.Laptop:
// attrName = "Source - Laptop " + keyNum;
// attrNum += 100; // Laptops start at 101
// break;
// case PresentationSourceType.VCR:
// attrName = "Source - VCR " + keyNum;
// attrNum += 125; // VCRs start at 126
// break;
// }
// if (attrName == null)
// {
// Debug.Console(1, this, "Source type {0} does not have corresponsing Fusion attribute type, skipping", pSrc.Type);
// continue;
// }
// Debug.Console(2, this, "Creating attribute '{0}' with join {1} for source {2}", attrName, attrNum, pSrc.Key);
// var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputOutputSig);
// // Need feedback when this source is selected
// // Event handler, added below, will compare source changes with this sig dict
// SourceToFeedbackSigs.Add(pSrc, sigD.InputSig);
// // And respond to selection in Fusion
// sigD.OutputSig.UserObject = new Action<bool>(b => { if(b) room.SelectSource(pSrc); });
// }
// // Attach to all room's devices with monitors.
// //foreach (var dev in DeviceManager.Devices)
// foreach (var dev in DeviceManager.GetDevices())
// {
// if (!(dev is ICommunicationMonitor))
// continue;
// var keyNum = ExtractNumberFromKey(dev.Key);
// if (keyNum == -1)
// {
// Debug.Console(1, this, "WARNING: Cannot link device '{0}' to numbered Fusion monitoring attributes", dev.Key);
// continue;
// }
// string attrName = null;
// uint attrNum = Convert.ToUInt32(keyNum);
// //if (dev is SmartGraphicsTouchpanelControllerBase)
// //{
// // if (attrNum > 10)
// // continue;
// // attrName = "Device Ok - Touch Panel " + attrNum;
// // attrNum += 200;
// //}
// //// add xpanel here
// //else
// if (dev is DisplayBase)
// {
// if (attrNum > 10)
// continue;
// attrName = "Device Ok - Display " + attrNum;
// attrNum += 240;
// }
// //else if (dev is DvdDeviceBase)
// //{
// // if (attrNum > 5)
// // continue;
// // attrName = "Device Ok - DVD " + attrNum;
// // attrNum += 260;
// //}
// // add set top box
// // add Cresnet roll-up
// // add DM-devices roll-up
// if (attrName != null)
// {
// // Link comm status to sig and update
// var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputSigOnly);
// var smd = dev as ICommunicationMonitor;
// sigD.InputSig.BoolValue = smd.CommunicationMonitor.Status == MonitorStatus.IsOk;
// smd.CommunicationMonitor.StatusChange += (o, a) => { sigD.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; };
// Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", dev.Key, attrName);
// }
// }
// // Don't think we need to get current status of this as nothing should be alive yet.
// room.PresentationSourceChange += Room_PresentationSourceChange;
// // these get used in multiple places
// var display = room.Display;
// var dispPowerOnAction = new Action<bool>(b => { if (!b) display.PowerOn(); });
// var dispPowerOffAction = new Action<bool>(b => { if (!b) display.PowerOff(); });
// // Display to fusion room sigs
// FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
// FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
// display.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
// if (display is IDisplayUsage)
// (display as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
// // Roll up ALL device errors
// ErrorMessageRollUp = new StatusMonitorCollection(this);
// foreach (var dev in DeviceManager.GetDevices())
// {
// var md = dev as ICommunicationMonitor;
// if (md != null)
// {
// ErrorMessageRollUp.AddMonitor(md.CommunicationMonitor);
// Debug.Console(2, this, "Adding '{0}' to room's overall error monitor", md.CommunicationMonitor.Parent.Key);
// }
// }
// ErrorMessageRollUp.Start();
// FusionRoom.ErrorMessage.InputSig.StringValue = ErrorMessageRollUp.Message;
// ErrorMessageRollUp.StatusChange += (o, a) => {
// FusionRoom.ErrorMessage.InputSig.StringValue = ErrorMessageRollUp.Message; };
// // static assets --------------- testing
// // test assets --- THESE ARE BOTH WIRED TO AssetUsage somewhere internally.
// var ta1 = FusionRoom.CreateStaticAsset(1, "Test asset 1", "Awesome Asset", "Awesome123");
// ta1.AssetError.InputSig.StringValue = "This should be error";
// var ta2 = FusionRoom.CreateStaticAsset(2, "Test asset 2", "Awesome Asset", "Awesome1232");
// ta2.AssetUsage.InputSig.StringValue = "This should be usage";
// // Make a display asset
// var dispAsset = FusionRoom.CreateStaticAsset(3, display.Name, "Display", "awesomeDisplayId" + room.Key);
// dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
// dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
// display.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
// // NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
// // Use extension methods
// dispAsset.TrySetMakeModel(display);
// dispAsset.TryLinkAssetErrorToCommunication(display);
// // Make it so!
// FusionRVI.GenerateFileForAllFusionDevices();
// }
// /// <summary>
// /// Helper to get the number from the end of a device's key string
// /// </summary>
// /// <returns>-1 if no number matched</returns>
// int ExtractNumberFromKey(string key)
// {
// var capture = System.Text.RegularExpressions.Regex.Match(key, @"\D+(\d+)");
// if (!capture.Success)
// return -1;
// else return Convert.ToInt32(capture.Groups[1].Value);
// }
// void Room_PresentationSourceChange(object sender, EssentialsRoomSourceChangeEventArgs e)
// {
// if (e.OldSource != null)
// {
// if (SourceToFeedbackSigs.ContainsKey(e.OldSource))
// SourceToFeedbackSigs[e.OldSource].BoolValue = false;
// }
// if (e.NewSource != null)
// {
// if (SourceToFeedbackSigs.ContainsKey(e.NewSource))
// SourceToFeedbackSigs[e.NewSource].BoolValue = true;
// }
// }
// void FusionRoom_FusionStateChange(FusionBase device, FusionStateEventArgs args)
// {
// // The sig/UO method: Need separate handlers for fixed and user sigs, all flavors,
// // even though they all contain sigs.
// var sigData = (args.UserConfiguredSigDetail as BooleanSigDataFixedName);
// if (sigData != null)
// {
// var outSig = sigData.OutputSig;
// if (outSig.UserObject is Action<bool>)
// (outSig.UserObject as Action<bool>).Invoke(outSig.BoolValue);
// else if (outSig.UserObject is Action<ushort>)
// (outSig.UserObject as Action<ushort>).Invoke(outSig.UShortValue);
// else if (outSig.UserObject is Action<string>)
// (outSig.UserObject as Action<string>).Invoke(outSig.StringValue);
// return;
// }
// var attrData = (args.UserConfiguredSigDetail as BooleanSigData);
// if (attrData != null)
// {
// var outSig = attrData.OutputSig;
// if (outSig.UserObject is Action<bool>)
// (outSig.UserObject as Action<bool>).Invoke(outSig.BoolValue);
// else if (outSig.UserObject is Action<ushort>)
// (outSig.UserObject as Action<ushort>).Invoke(outSig.UShortValue);
// else if (outSig.UserObject is Action<string>)
// (outSig.UserObject as Action<string>).Invoke(outSig.StringValue);
// return;
// }
// }
// }
// public static class FusionRoomExtensions
// {
// /// <summary>
// /// Creates and returns a fusion attribute. The join number will match the established Simpl
// /// standard of 50+, and will generate a 50+ join in the RVI. It calls
// /// FusionRoom.AddSig with join number - 49
// /// </summary>
// /// <returns>The new attribute</returns>
// public static BooleanSigData CreateOffsetBoolSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
// {
// if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
// number -= 49;
// fr.AddSig(eSigType.Bool, number, name, mask);
// return fr.UserDefinedBooleanSigDetails[number];
// }
// /// <summary>
// /// Creates and returns a fusion attribute. The join number will match the established Simpl
// /// standard of 50+, and will generate a 50+ join in the RVI. It calls
// /// FusionRoom.AddSig with join number - 49
// /// </summary>
// /// <returns>The new attribute</returns>
// public static UShortSigData CreateOffsetUshortSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
// {
// if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
// number -= 49;
// fr.AddSig(eSigType.UShort, number, name, mask);
// return fr.UserDefinedUShortSigDetails[number];
// }
// /// <summary>
// /// Creates and returns a fusion attribute. The join number will match the established Simpl
// /// standard of 50+, and will generate a 50+ join in the RVI. It calls
// /// FusionRoom.AddSig with join number - 49
// /// </summary>
// /// <returns>The new attribute</returns>
// public static StringSigData CreateOffsetStringSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
// {
// if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
// number -= 49;
// fr.AddSig(eSigType.String, number, name, mask);
// return fr.UserDefinedStringSigDetails[number];
// }
// /// <summary>
// /// Creates and returns a static asset
// /// </summary>
// /// <returns>the new asset</returns>
// public static FusionStaticAsset CreateStaticAsset(this FusionRoom fr, uint number, string name, string type, string instanceId)
// {
// fr.AddAsset(eAssetType.StaticAsset, number, name, type, instanceId);
// return fr.UserConfigurableAssetDetails[number].Asset as FusionStaticAsset;
// }
// }
// //************************************************************************************************
// /// <summary>
// /// Extensions to enhance Fusion room, asset and signal creation.
// /// </summary>
// public static class FusionStaticAssetExtensions
// {
// /// <summary>
// /// Tries to set a Fusion asset with the make and model of a device.
// /// If the provided Device is IMakeModel, will set the corresponding parameters on the fusion static asset.
// /// Otherwise, does nothing.
// /// </summary>
// public static void TrySetMakeModel(this FusionStaticAsset asset, Device device)
// {
// var mm = device as IMakeModel;
// if (mm != null)
// {
// asset.ParamMake.Value = mm.DeviceMake;
// asset.ParamModel.Value = mm.DeviceModel;
// }
// }
// /// <summary>
// /// Tries to attach the AssetError input on a Fusion asset to a Device's
// /// CommunicationMonitor.StatusChange event. Does nothing if the device is not
// /// IStatusMonitor
// /// </summary>
// /// <param name="asset"></param>
// /// <param name="device"></param>
// public static void TryLinkAssetErrorToCommunication(this FusionStaticAsset asset, Device device)
// {
// if (device is ICommunicationMonitor)
// {
// var monitor = (device as ICommunicationMonitor).CommunicationMonitor;
// monitor.StatusChange += (o, a) =>
// {
// // Link connected and error inputs on asset
// asset.Connected.InputSig.BoolValue = a.Status == MonitorStatus.IsOk;
// asset.AssetError.InputSig.StringValue = a.Status.ToString();
// };
// // set current value
// asset.Connected.InputSig.BoolValue = monitor.Status == MonitorStatus.IsOk;
// asset.AssetError.InputSig.StringValue = monitor.Status.ToString();
// }
// }
// }
//}

View File

@@ -9,7 +9,7 @@ using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.CrestronIO;
namespace PepperDash.Essentials.Devices.Common.Microphones
namespace PepperDash.Essentials.Core.Privacy
{
/// <summary>
/// Used for applications where one or more microphones with momentary contact closure outputs are used to

View File

@@ -6,7 +6,7 @@ using Crestron.SimplSharp;
using PepperDash.Essentials.Core.CrestronIO;
namespace PepperDash.Essentials.Devices.Common.Microphones
namespace PepperDash.Essentials.Core.Privacy
{
public class MicrophonePrivacyControllerConfig
{

View File

@@ -123,6 +123,8 @@
<Compile Include="Devices\CodecInterfaces.cs" />
<Compile Include="Devices\CrestronProcessor.cs" />
<Compile Include="Devices\DeviceApiBase.cs" />
<Compile Include="Devices\PC\InRoomPc.cs" />
<Compile Include="Devices\PC\Laptop.cs" />
<Compile Include="Devices\ReconfigurableDevice.cs" />
<Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" />
<Compile Include="Factory\DeviceFactory.cs" />
@@ -132,12 +134,19 @@
<Compile Include="Feedbacks\IntFeedback.cs" />
<Compile Include="Feedbacks\SerialFeedback.cs" />
<Compile Include="Feedbacks\StringFeedback.cs" />
<Compile Include="Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs" />
<Compile Include="Fusion\FusionCustomPropertiesBridge.cs" />
<Compile Include="Fusion\FusionEventHandlers.cs" />
<Compile Include="Fusion\FusionProcessorQueries.cs" />
<Compile Include="Fusion\FusionRviDataClasses.cs" />
<Compile Include="Global\JobTimer.cs" />
<Compile Include="Global\Scheduler.cs" />
<Compile Include="JoinMaps\JoinMapBase.cs" />
<Compile Include="Lighting\Lighting Interfaces.cs" />
<Compile Include="Lighting\LightingBase.cs" />
<Compile Include="Monitoring\SystemMonitorController.cs" />
<Compile Include="Microphone Privacy\MicrophonePrivacyController.cs" />
<Compile Include="Microphone Privacy\MicrophonePrivacyControllerConfig.cs" />
<Compile Include="Ramps and Increments\ActionIncrementer.cs" />
<Compile Include="Comm and IR\CommFactory.cs" />
<Compile Include="Comm and IR\CommunicationExtras.cs" />
@@ -173,6 +182,10 @@
<Compile Include="Feedbacks\BoolFeedbackOneShot.cs" />
<Compile Include="Ramps and Increments\NumericalHelpers.cs" />
<Compile Include="Ramps and Increments\UshortSigIncrementer.cs" />
<Compile Include="Room\Behaviours\RoomOnToDefaultSourceWhenOccupied.cs" />
<Compile Include="Room\EssentialsRoomBase.cs" />
<Compile Include="Room\Interfaces.cs" />
<Compile Include="Room\iOccupancyStatusProvider.cs" />
<Compile Include="Routing\DummyRoutingInputsDevice.cs" />
<Compile Include="Routing\ICardPortsDevice.cs" />
<Compile Include="InUseTracking\IInUseTracking.cs" />
@@ -191,7 +204,6 @@
<Compile Include="Display\DELETE IRDisplayBase.cs" />
<Compile Include="Display\MockDisplay.cs" />
<Compile Include="Ethernet\EthernetStatistics.cs" />
<Compile Include="Fusion\MOVED FusionSystemController.cs" />
<Compile Include="Global\Global.cs" />
<Compile Include="License\EssentialsLicenseManager.cs" />
<Compile Include="Feedbacks\BoolOutputLogicals.cs" />
@@ -238,7 +250,6 @@
<Compile Include="Feedbacks\FeedbackBase.cs" />
<Compile Include="Room\Room.cs" />
<Compile Include="Room\RoomCues.cs" />
<Compile Include="Room\MOVED RoomEventArgs.cs" />
<Compile Include="SmartObjects\SubpageReferencList\SourceListSubpageReferenceList.cs" />
<Compile Include="Touchpanels\ModalDialog.cs" />
<Compile Include="Touchpanels\SmartGraphicsTouchpanelControllerBase.cs" />

View File

@@ -1,297 +1,311 @@
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
}
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;
namespace PepperDash.Essentials.Core
{
/// <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>
/// The config name of the source list
/// </summary>
public string SourceListKey { get; set; }
/// <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 EssentialsRoomEmergencyBase Emergency { get; set; }
public Core.Privacy.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 Core.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
}
public abstract class EssentialsRoomEmergencyBase : IKeyed
{
public string Key { get; private set; }
public EssentialsRoomEmergencyBase(string key)
{
Key = key;
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// For rooms with routing
/// </summary>
public interface IRunRouteAction
{
void RunRouteAction(string routeKey);
void RunRouteAction(string routeKey, Action successCallback);
}
/// <summary>
/// For rooms that default presentation only routing
/// </summary>
public interface IRunDefaultPresentRoute
{
bool RunDefaultPresentRoute();
}
/// <summary>
/// For rooms that have default presentation and calling routes
/// </summary>
public interface IRunDefaultCallRoute : IRunDefaultPresentRoute
{
bool RunDefaultCallRoute();
}
}

View File

@@ -1,41 +0,0 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using Crestron.SimplSharp;
//namespace PepperDash.Essentials.Core
//{
// public class EssentialsRoomSourceChangeEventArgs : EventArgs
// {
// public EssentialsRoom Room { get; private set; }
// public IPresentationSource OldSource { get; private set; }
// public IPresentationSource NewSource { get; private set; }
// public EssentialsRoomSourceChangeEventArgs(EssentialsRoom room,
// IPresentationSource oldSource, IPresentationSource newSource)
// {
// Room = room;
// OldSource = oldSource;
// NewSource = newSource;
// }
// }
// public class EssentialsRoomAudioDeviceChangeEventArgs : EventArgs
// {
// public EssentialsRoom Room { get; private set; }
// public IBasicVolumeControls OldDevice { get; private set; }
// public IBasicVolumeControls NewDevice { get; private set; }
// public EssentialsRoomAudioDeviceChangeEventArgs(EssentialsRoom room,
// IBasicVolumeControls oldDevice, IBasicVolumeControls newDevice)
// {
// Room = room;
// OldDevice = oldDevice;
// NewDevice = newDevice;
// }
// }
//}

View File

@@ -6,7 +6,7 @@ using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Occupancy
namespace PepperDash.Essentials.Core
{
public interface IOccupancyStatusProvider
{

View File

@@ -11,9 +11,26 @@ using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// The handler type for a Room's SourceInfoChange
/// </summary>
public delegate void SourceInfoChangeHandler(EssentialsRoomBase room, SourceListItem info, ChangeType type);
//*******************************************************************************************
// Interfaces
/// <summary>
/// For rooms with a single presentation source, change event
/// </summary>
public interface IHasCurrentSourceInfoChange
{
string CurrentSourceInfoKey { get; }
SourceListItem CurrentSourceInfo { get; }
event SourceInfoChangeHandler CurrentSourceChange;
}
/// <summary>
/// Defines a class that has a collection of RoutingInputPorts
@@ -43,7 +60,7 @@ namespace PepperDash.Essentials.Core
/// <summary>
/// Endpoint device like a display, that selects inputs
/// </summary>
public interface IRoutingSinkWithSwitching : IRoutingSinkNoSwitching
public interface IRoutingSinkWithSwitching : IRoutingSinkNoSwitching, IHasCurrentSourceInfoChange
{
//void ClearRoute();
void ExecuteSwitch(object inputSelector);

View File

@@ -150,13 +150,8 @@
<Compile Include="Environment\Somfy\RelayControlledShade.cs" />
<Compile Include="Factory\DeviceFactory.cs" />
<Compile Include="Generic\GenericSource.cs" />
<Compile Include="Microphone\MicrophonePrivacyController.cs" />
<Compile Include="Microphone\MicrophonePrivacyControllerConfig.cs" />
<Compile Include="Occupancy\GlsOccupancySensorBaseController.cs" />
<Compile Include="Occupancy\IOccupancyStatusProviderAggregator.cs" />
<Compile Include="Occupancy\iOccupancyStatusProvider.cs" />
<Compile Include="PC\InRoomPc.cs" />
<Compile Include="PC\Laptop.cs" />
<Compile Include="SetTopBox\SetTopBoxPropertiesConfig.cs" />
<Compile Include="Streaming\AppleTV.cs" />
<Compile Include="Audio\GenericAudioOut.cs" />