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/ api/
*.DS_Store *.DS_Store
/._PepperDash.Essentials.4Series.sln /._PepperDash.Essentials.4Series.sln
dotnet

View File

@@ -19,12 +19,12 @@ namespace PepperDash.Essentials.Core.Fusion
/// <summary> /// <summary>
/// Represents a EssentialsHuddleSpaceFusionSystemControllerBase /// Represents a EssentialsHuddleSpaceFusionSystemControllerBase
/// </summary> /// </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 const string RemoteOccupancyXml = "<Occupancy><Type>Local</Type><State>{0}</State></Occupancy>";
private readonly bool _guidFileExists; private bool _guidFileExists;
private readonly Dictionary<Device, BoolInputSig> _sourceToFeedbackSigs = private readonly Dictionary<Device, BoolInputSig> _sourceToFeedbackSigs =
new Dictionary<Device, BoolInputSig>(); new Dictionary<Device, BoolInputSig>();
@@ -52,7 +52,7 @@ namespace PepperDash.Essentials.Core.Fusion
/// </summary> /// </summary>
protected Dictionary<int, FusionAsset> FusionStaticAssets; protected Dictionary<int, FusionAsset> FusionStaticAssets;
private readonly long PushNotificationTimeout = 5000; private readonly long PushNotificationTimeout = 5000;
private readonly IEssentialsRoom Room; private IEssentialsRoom Room;
private readonly long SchedulePollInterval = 300000; private readonly long SchedulePollInterval = 300000;
private Event _currentMeeting; private Event _currentMeeting;
@@ -74,8 +74,12 @@ namespace PepperDash.Essentials.Core.Fusion
private bool _helpRequestSent; private bool _helpRequestSent;
/// <inheritdoc />
public StringFeedback HelpRequestResponseFeedback { get; private set; } public StringFeedback HelpRequestResponseFeedback { get; private set; }
/// <inheritdoc />
public BoolFeedback HelpRequestSentFeedback { get; private set; }
#region System Info Sigs #region System Info Sigs
//StringSigData SystemName; //StringSigData SystemName;
@@ -109,14 +113,48 @@ namespace PepperDash.Essentials.Core.Fusion
#endregion #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>
/// ///
/// </summary> /// </summary>
/// <param name="room"></param> /// <param name="room"></param>
/// <param name="ipId"></param> /// <param name="ipId"></param>
/// <param name="joinMapKey"></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") : 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 try
{ {
@@ -132,7 +170,7 @@ namespace PepperDash.Essentials.Core.Fusion
JoinMap.SetCustomJoinData(customJoins); JoinMap.SetCustomJoinData(customJoins);
} }
} }
Room = room; Room = room;
_ipId = ipId; _ipId = ipId;
@@ -141,41 +179,7 @@ namespace PepperDash.Essentials.Core.Fusion
_guiDs = new FusionRoomGuids(); _guiDs = new FusionRoomGuids();
var mac =
CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 0);
var slot = Global.ControlSystem.ProgramNumber;
var guidFilePath = Global.FilePathPrefix +
string.Format(@"{0}-FusionGuids-{1:X2}.json", InitialParametersClass.ProgramIDTag, _ipId);
var oldGuidFilePath = Global.FilePathPrefix +
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
if (File.Exists(oldGuidFilePath))
{
Debug.LogMessage(LogEventLevel.Information, this, "Migrating from old Fusion GUID file to new Fusion GUID File");
File.Copy(oldGuidFilePath, guidFilePath);
File.Delete(oldGuidFilePath);
}
_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 (Room is IRoomOccupancy occupancyRoom)
@@ -197,13 +201,53 @@ namespace PepperDash.Essentials.Core.Fusion
HelpRequestResponseFeedback.LinkInputSig(FusionRoom.Help.InputSig); HelpRequestResponseFeedback.LinkInputSig(FusionRoom.Help.InputSig);
AddPostActivationAction(() => PostActivate(guidFilePath));
} }
catch (Exception e) catch (Exception e)
{ {
Debug.LogMessage(LogEventLevel.Information, this, "Error Building Fusion System Controller: {0}", 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);
var slot = Global.ControlSystem.ProgramNumber;
var guidFilePath = Global.FilePathPrefix +
string.Format(@"{0}-FusionGuids-{1:X2}.json", InitialParametersClass.ProgramIDTag, _ipId);
var oldGuidFilePath = Global.FilePathPrefix +
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
if (File.Exists(oldGuidFilePath))
{
Debug.LogMessage(LogEventLevel.Information, this, "Migrating from old Fusion GUID file to new Fusion GUID File");
File.Copy(oldGuidFilePath, guidFilePath);
File.Delete(oldGuidFilePath);
}
_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);
}
return guidFilePath;
}
private void PostActivate(string guidFilePath) private void PostActivate(string guidFilePath)
{ {
@@ -1721,11 +1765,8 @@ namespace PepperDash.Essentials.Core.Fusion
} }
} }
/// <summary> /// <inheritdoc />
/// Sends a help request to Fusion with room name and timestamp public void SendHelpRequest(bool isHtml = false)
/// </summary>
/// <param name="isHtml"></param>
public void SendHelpRequest(bool isHtml)
{ {
var now = DateTime.Now; var now = DateTime.Now;
@@ -1740,6 +1781,7 @@ namespace PepperDash.Essentials.Core.Fusion
_helpRequestSent = true; _helpRequestSent = true;
} }
/// <inheritdoc />
public void CancelHelpRequest() public void CancelHelpRequest()
{ {
if (_helpRequestSent) 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); 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> /// <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 public interface IFusionHelpRequest
{ {
/// <summary> /// <summary>
/// Gets the HelpRequstResponseFeedback /// Feedback containing the response to a help request
/// </summary> /// </summary>
StringFeedback HelpRequestResponseFeedback { get; } StringFeedback HelpRequestResponseFeedback { get; }
/// <summary>
/// Indicates whether a help request has been sent
/// </summary>
BoolFeedback HelpRequestSentFeedback { get; }
/// <summary> /// <summary>
/// Sends a help request /// Sends a help request
/// </summary> /// </summary>
/// <param name="isHtml"></param> /// <param name="isHtml"></param>
void SendHelpRequest(bool isHtml); 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> /// </summary>
public IRoomOccupancy Room { get; private set; } public IRoomOccupancy Room { get; private set; }
private Fusion.EssentialsHuddleSpaceFusionSystemControllerBase FusionRoom; private Fusion.IEssentialsRoomFusionController FusionRoom;
public RoomOnToDefaultSourceWhenOccupied(DeviceConfig config) : public RoomOnToDefaultSourceWhenOccupied(DeviceConfig config) :
base (config) base (config)
@@ -74,7 +74,7 @@ namespace PepperDash.Essentials.Core
var fusionRoomKey = PropertiesConfig.RoomKey + "-fusion"; var fusionRoomKey = PropertiesConfig.RoomKey + "-fusion";
FusionRoom = DeviceManager.GetDeviceForKey(fusionRoomKey) as Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase; FusionRoom = DeviceManager.GetDeviceForKey(fusionRoomKey) as Core.Fusion.IEssentialsRoomFusionController;
if (FusionRoom == null) if (FusionRoom == null)
Debug.LogMessage(LogEventLevel.Debug, this, "Unable to get Fusion Room from Device Manager with key: {0}", fusionRoomKey); 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); Debug.LogMessage(LogEventLevel.Information, this, "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 Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase) if (statusProvider is Core.Fusion.IEssentialsRoomFusionController)
OccupancyStatusProviderIsRemote = true; OccupancyStatusProviderIsRemote = true;
if(timeoutMinutes > 0) if(timeoutMinutes > 0)