feat: Add IEssentialsRoomFusionController and related configurations

- Introduced IEssentialsRoomFusionControllerFactory for creating Fusion Room Controller devices.
- Added IEssentialsRoomFusionControllerPropertiesConfig to define configuration properties for the Fusion Room Controller.
- Updated IFusionHelpRequest interface to include methods for cancelling and toggling help requests.
- Refactored RoomOnToDefaultSourceWhenOccupied to use IEssentialsRoomFusionController instead of EssentialsHuddleSpaceFusionSystemControllerBase.
- Modified EssentialsRoomBase to check for IEssentialsRoomFusionController in occupancy status provider.
This commit is contained in:
Neil Dorin
2025-10-28 16:49:29 -06:00
parent f27965ac29
commit 2e95f5337e
7 changed files with 179 additions and 50 deletions

1
.gitignore vendored
View File

@@ -396,3 +396,4 @@ _site/
api/
*.DS_Store
/._PepperDash.Essentials.4Series.sln
dotnet

View File

@@ -19,12 +19,12 @@ namespace PepperDash.Essentials.Core.Fusion
/// <summary>
/// Represents a EssentialsHuddleSpaceFusionSystemControllerBase
/// </summary>
public class EssentialsHuddleSpaceFusionSystemControllerBase : Device, IOccupancyStatusProvider, IFusionHelpRequest
public class IEssentialsRoomFusionController : EssentialsDevice, IOccupancyStatusProvider, IFusionHelpRequest
{
private readonly EssentialsHuddleSpaceRoomFusionRoomJoinMap JoinMap;
private EssentialsHuddleSpaceRoomFusionRoomJoinMap JoinMap;
private const string RemoteOccupancyXml = "<Occupancy><Type>Local</Type><State>{0}</State></Occupancy>";
private readonly bool _guidFileExists;
private bool _guidFileExists;
private readonly Dictionary<Device, BoolInputSig> _sourceToFeedbackSigs =
new Dictionary<Device, BoolInputSig>();
@@ -52,7 +52,7 @@ namespace PepperDash.Essentials.Core.Fusion
/// </summary>
protected Dictionary<int, FusionAsset> FusionStaticAssets;
private readonly long PushNotificationTimeout = 5000;
private readonly IEssentialsRoom Room;
private IEssentialsRoom Room;
private readonly long SchedulePollInterval = 300000;
private Event _currentMeeting;
@@ -74,8 +74,12 @@ namespace PepperDash.Essentials.Core.Fusion
private bool _helpRequestSent;
/// <inheritdoc />
public StringFeedback HelpRequestResponseFeedback { get; private set; }
/// <inheritdoc />
public BoolFeedback HelpRequestSentFeedback { get; private set; }
#region System Info Sigs
//StringSigData SystemName;
@@ -109,14 +113,48 @@ namespace PepperDash.Essentials.Core.Fusion
#endregion
/// <summary>
/// Constructor
/// </summary>
public IEssentialsRoomFusionController(IEssentialsRoomFusionControllerPropertiesConfig config)
: base("FusionRoomController")
{
AddPostActivationAction(() =>
{
var room = DeviceManager.GetDeviceForKey<IEssentialsRoom>(config.RoomKey);
if (room == null)
{
Debug.LogMessage(LogEventLevel.Error, this,
"Error Creating Fusion Room Controller. No room found with key '{0}'", config.RoomKey);
return;
}
ConstructorHelper(room, config.IpId, config.JoinMapKey);
var guidFilePath = GetGuidFilePath(config.IpId);
PostActivate(guidFilePath);
});
}
/// <summary>
///
/// </summary>
/// <param name="room"></param>
/// <param name="ipId"></param>
/// <param name="joinMapKey"></param>
public EssentialsHuddleSpaceFusionSystemControllerBase(IEssentialsRoom room, uint ipId, string joinMapKey)
public IEssentialsRoomFusionController(IEssentialsRoom room, uint ipId, string joinMapKey)
: base(room.Key + "-fusion")
{
ConstructorHelper(room, ipId, joinMapKey);
var guidFilePath = GetGuidFilePath(ipId);
AddPostActivationAction(() => PostActivate(guidFilePath));
}
private void ConstructorHelper(IEssentialsRoom room, uint ipId, string joinMapKey)
{
try
{
@@ -141,6 +179,37 @@ namespace PepperDash.Essentials.Core.Fusion
_guiDs = new FusionRoomGuids();
if (Room is IRoomOccupancy occupancyRoom)
{
if (occupancyRoom.RoomOccupancy != null)
{
if (occupancyRoom.OccupancyStatusProviderIsRemote)
{
SetUpRemoteOccupancy();
}
else
{
SetUpLocalOccupancy();
}
}
}
HelpRequestResponseFeedback = new StringFeedback("HelpRequestResponse", () => FusionRoom.Help.InputSig.StringValue);
HelpRequestResponseFeedback.LinkInputSig(FusionRoom.Help.InputSig);
}
catch (Exception e)
{
Debug.LogMessage(LogEventLevel.Information, this, "Error Building Fusion System Controller: {0}", e);
}
}
private string GetGuidFilePath(uint ipId)
{
var mac =
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 0);
@@ -164,45 +233,20 @@ namespace PepperDash.Essentials.Core.Fusion
_guidFileExists = File.Exists(guidFilePath);
// Check if file exists
if (!_guidFileExists)
{
// Does not exist. Create GUIDs
_guiDs = new FusionRoomGuids(Room.Name, ipId, _guiDs.GenerateNewRoomGuid(slot, mac),
FusionStaticAssets);
}
else
{
// Exists. Read GUIDs
ReadGuidFile(guidFilePath);
}
if (Room is IRoomOccupancy occupancyRoom)
{
if (occupancyRoom.RoomOccupancy != null)
{
if (occupancyRoom.OccupancyStatusProviderIsRemote)
{
SetUpRemoteOccupancy();
}
else
{
SetUpLocalOccupancy();
}
}
}
HelpRequestResponseFeedback = new StringFeedback("HelpRequestResponse", () => FusionRoom.Help.InputSig.StringValue);
HelpRequestResponseFeedback.LinkInputSig(FusionRoom.Help.InputSig);
AddPostActivationAction(() => PostActivate(guidFilePath));
}
catch (Exception e)
// Check if file exists
if (!_guidFileExists)
{
Debug.LogMessage(LogEventLevel.Information, this, "Error Building Fusion System Controller: {0}", e);
// Does not exist. Create GUIDs
_guiDs = new FusionRoomGuids(Room.Name, ipId, _guiDs.GenerateNewRoomGuid(slot, mac),
FusionStaticAssets);
}
else
{
// Exists. Read GUIDs
ReadGuidFile(guidFilePath);
}
return guidFilePath;
}
private void PostActivate(string guidFilePath)
@@ -1721,11 +1765,8 @@ namespace PepperDash.Essentials.Core.Fusion
}
}
/// <summary>
/// Sends a help request to Fusion with room name and timestamp
/// </summary>
/// <param name="isHtml"></param>
public void SendHelpRequest(bool isHtml)
/// <inheritdoc />
public void SendHelpRequest(bool isHtml = false)
{
var now = DateTime.Now;
@@ -1740,6 +1781,7 @@ namespace PepperDash.Essentials.Core.Fusion
_helpRequestSent = true;
}
/// <inheritdoc />
public void CancelHelpRequest()
{
if (_helpRequestSent)
@@ -1749,6 +1791,19 @@ namespace PepperDash.Essentials.Core.Fusion
Debug.LogMessage(LogEventLevel.Information, this, "Help request cancelled in Fusion for room '{0}'", Room.Name);
}
}
/// <inheritdoc />
public void ToggleHelpRequest(bool isHtml = false)
{
if (_helpRequestSent)
{
CancelHelpRequest();
}
else
{
SendHelpRequest(isHtml);
}
}
}
/// <summary>

View File

@@ -0,0 +1,33 @@
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Fusion;
/// <summary>
/// Factory for creating IEssentialsRoomFusionController devices
/// </summary>
public class IEssentialsRoomFusionControllerFactory : EssentialsDeviceFactory<IEssentialsRoomFusionController>
{
/// <summary>
/// Constructor
/// </summary>
public IEssentialsRoomFusionControllerFactory()
{
TypeNames = new List<string>() { "fusionRoom" };
}
/// <summary>
/// Builds the device
/// </summary>
/// <param name="dc"></param>
/// <returns></returns>
public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc)
{
Debug.LogDebug("Factory Attempting to create new IEssentialsRoomFusionController Device");
var properties = dc.Properties.ToObject<IEssentialsRoomFusionControllerPropertiesConfig>();
return new IEssentialsRoomFusionController(properties);
}
}

View File

@@ -0,0 +1,25 @@
using Newtonsoft.Json;
/// <summary>
/// Config properties for an IEssentialsRoomFusionController device
/// </summary>
public class IEssentialsRoomFusionControllerPropertiesConfig
{
/// <summary>
/// Gets or sets the IP ID of the Fusion Room Controller
/// </summary>
[JsonProperty("ipId")]
public uint IpId { get; set; }
/// <summary>
/// Gets or sets the join map key
/// </summary>
[JsonProperty("joinMapKey")]
public string JoinMapKey { get; set; }
/// <summary>
/// Gets or sets the room key associated with this Fusion Room Controller
/// </summary>
[JsonProperty("roomKey")]
public string RoomKey { get; set; }
}

View File

@@ -12,14 +12,29 @@ namespace PepperDash.Essentials.Core.Fusion
public interface IFusionHelpRequest
{
/// <summary>
/// Gets the HelpRequstResponseFeedback
/// Feedback containing the response to a help request
/// </summary>
StringFeedback HelpRequestResponseFeedback { get; }
/// <summary>
/// Indicates whether a help request has been sent
/// </summary>
BoolFeedback HelpRequestSentFeedback { get; }
/// <summary>
/// Sends a help request
/// </summary>
/// <param name="isHtml"></param>
void SendHelpRequest(bool isHtml);
/// <summary>
/// Clears the current help request status
/// </summary>
void CancelHelpRequest();
/// <summary>
/// Toggles between sending and cancelling a help request
/// </summary>
void ToggleHelpRequest(bool isHtml);
}
}

View File

@@ -49,7 +49,7 @@ namespace PepperDash.Essentials.Core
/// </summary>
public IRoomOccupancy Room { get; private set; }
private Fusion.EssentialsHuddleSpaceFusionSystemControllerBase FusionRoom;
private Fusion.IEssentialsRoomFusionController FusionRoom;
public RoomOnToDefaultSourceWhenOccupied(DeviceConfig config) :
base (config)
@@ -74,7 +74,7 @@ namespace PepperDash.Essentials.Core
var fusionRoomKey = PropertiesConfig.RoomKey + "-fusion";
FusionRoom = DeviceManager.GetDeviceForKey(fusionRoomKey) as Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase;
FusionRoom = DeviceManager.GetDeviceForKey(fusionRoomKey) as Core.Fusion.IEssentialsRoomFusionController;
if (FusionRoom == null)
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to get Fusion Room from Device Manager with key: {0}", fusionRoomKey);

View File

@@ -408,7 +408,7 @@ namespace PepperDash.Essentials.Core
Debug.LogMessage(LogEventLevel.Information, this, "Timeout Minutes from Config is: {0}", timeoutMinutes);
// If status provider is fusion, set flag to remote
if (statusProvider is Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase)
if (statusProvider is Core.Fusion.IEssentialsRoomFusionController)
OccupancyStatusProviderIsRemote = true;
if(timeoutMinutes > 0)