diff --git a/.gitignore b/.gitignore
index db1e92a3..d64977d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -396,3 +396,4 @@ _site/
api/
*.DS_Store
/._PepperDash.Essentials.4Series.sln
+dotnet
diff --git a/src/PepperDash.Essentials.Core/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs b/src/PepperDash.Essentials.Core/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs
index d6a7bffa..ba638623 100644
--- a/src/PepperDash.Essentials.Core/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs
+++ b/src/PepperDash.Essentials.Core/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs
@@ -16,121 +16,201 @@ namespace PepperDash.Essentials.Core.Fusion
{
// Processor Attributes
+ ///
+ /// Processor IP 1
+ ///
[JoinName("ProcessorIp1")]
public JoinDataComplete ProcessorIp1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Info - Processor - IP 1" },
new JoinMetadata { Description = "Info - Processor - IP 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+ ///
+ /// Processor IP 2
+ ///
[JoinName("ProcessorIp2")]
public JoinDataComplete ProcessorIp2 = new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1, AttributeName = "Info - Processor - IP 2" },
new JoinMetadata { Description = "Info - Processor - IP 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+ ///
+ /// Processor Gateway
+ ///
[JoinName("ProcessorGateway")]
public JoinDataComplete ProcessorGateway = new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1, AttributeName = "Info - Processor - Gateway" },
new JoinMetadata { Description = "Info - Processor - Gateway", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+ ///
+ /// Processor Hostname
+ ///
[JoinName("ProcessorHostname")]
public JoinDataComplete ProcessorHostname = new JoinDataComplete(new JoinData { JoinNumber = 53, JoinSpan = 1, AttributeName = "Info - Processor - Hostname" },
new JoinMetadata { Description = "Info - Processor - Hostname", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+ ///
+ /// Processor Domain
+ ///
[JoinName("ProcessorDomain")]
public JoinDataComplete ProcessorDomain = new JoinDataComplete(new JoinData { JoinNumber = 54, JoinSpan = 1, AttributeName = "Info - Processor - Domain" },
new JoinMetadata { Description = "Info - Processor - Domain", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+ ///
+ /// Processor DNS 1
+ ///
[JoinName("ProcessorDns1")]
public JoinDataComplete ProcessorDns1 = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1, AttributeName = "Info - Processor - DNS 1" },
new JoinMetadata { Description = "Info - Processor - DNS 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+ ///
+ /// Processor DNS 2
+ ///
[JoinName("ProcessorDns2")]
public JoinDataComplete ProcessorDns2 = new JoinDataComplete(new JoinData { JoinNumber = 56, JoinSpan = 1, AttributeName = "Info - Processor - DNS 2" },
new JoinMetadata { Description = "Info - Processor - DNS 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+ ///
+ /// Processor MAC 1
+ ///
[JoinName("ProcessorMac1")]
public JoinDataComplete ProcessorMac1 = new JoinDataComplete(new JoinData { JoinNumber = 57, JoinSpan = 1, AttributeName = "Info - Processor - MAC 1" },
new JoinMetadata { Description = "Info - Processor - MAC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+ ///
+ /// Processor MAC 2
+ ///
[JoinName("ProcessorMac2")]
public JoinDataComplete ProcessorMac2 = new JoinDataComplete(new JoinData { JoinNumber = 58, JoinSpan = 1, AttributeName = "Info - Processor - MAC 2" },
new JoinMetadata { Description = "Info - Processor - MAC 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+ ///
+ /// Processor Net Mask 1
+ ///
[JoinName("ProcessorNetMask1")]
public JoinDataComplete ProcessorNetMask1 = new JoinDataComplete(new JoinData { JoinNumber = 59, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 1" },
new JoinMetadata { Description = "Info - Processor - Net Mask 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+ ///
+ /// Processor Net Mask 2
+ ///
[JoinName("ProcessorNetMask2")]
public JoinDataComplete ProcessorNetMask2 = new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 2" },
new JoinMetadata { Description = "Info - Processor - Net Mask 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+ ///
+ /// Processor Firmware
+ ///
[JoinName("ProcessorFirmware")]
public JoinDataComplete ProcessorFirmware = new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1, AttributeName = "Info - Processor - Firmware" },
new JoinMetadata { Description = "Info - Processor - Firmware", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+ ///
+ /// Program Name Start
+ ///
[JoinName("ProgramNameStart")]
public JoinDataComplete ProgramNameStart = new JoinDataComplete(new JoinData { JoinNumber = 62, JoinSpan = 10, AttributeName = "Info - Processor - Program" },
new JoinMetadata { Description = "Info - Processor - Program", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+ ///
+ /// Processor Reboot
+ ///
[JoinName("ProcessorReboot")]
public JoinDataComplete ProcessorReboot = new JoinDataComplete(new JoinData { JoinNumber = 74, JoinSpan = 1, AttributeName = "Processor - Reboot" },
new JoinMetadata { Description = "Processor - Reboot", JoinCapabilities = eJoinCapabilities.FromFusion, JoinType = eJoinType.Digital });
// Volume Controls
+ ///
+ /// Volume Fader 1
+ ///
[JoinName("VolumeFader1")]
public JoinDataComplete VolumeFader1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Volume - Fader01" },
new JoinMetadata { Description = "Volume - Fader01", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Analog });
// Codec Info
+ ///
+ /// VC Codec In Call
+ ///
[JoinName("VcCodecInCall")]
public JoinDataComplete VcCodecInCall = new JoinDataComplete(new JoinData { JoinNumber = 69, JoinSpan = 1, AttributeName = "Conf - VC 1 In Call" },
new JoinMetadata { Description = "Conf - VC 1 In Call", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
+ ///
+ /// VC Codec Online
+ ///
[JoinName("VcCodecOnline")]
public JoinDataComplete VcCodecOnline = new JoinDataComplete(new JoinData { JoinNumber = 122, JoinSpan = 1, AttributeName = "Online - VC 1" },
new JoinMetadata { Description = "Online - VC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
+ ///
+ /// VC Codec IP Address
+ ///
[JoinName("VcCodecIpAddress")]
public JoinDataComplete VcCodecIpAddress = new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1, AttributeName = "IP Address - VC" },
new JoinMetadata { Description = "IP Address - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
+ ///
+ /// VC Codec IP Port
+ ///
[JoinName("VcCodecIpPort")]
public JoinDataComplete VcCodecIpPort = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 1, AttributeName = "IP Port - VC" },
new JoinMetadata { Description = "IP Port - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
// Source Attributes
+ ///
+ /// Display 1 Current Source Name
+ ///
[JoinName("Display1CurrentSourceName")]
public JoinDataComplete Display1CurrentSourceName = new JoinDataComplete(new JoinData { JoinNumber = 84, JoinSpan = 1, AttributeName = "Display 1 - Current Source" },
new JoinMetadata { Description = "Display 1 - Current Source", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
// Device Online Status
+ ///
+ /// Touchpanel Online Start
+ ///
[JoinName("TouchpanelOnlineStart")]
public JoinDataComplete TouchpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 10, AttributeName = "Online - Touch Panel" },
new JoinMetadata { Description = "Online - Touch Panel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
+ ///
+ /// Xpanel Online Start
+ ///
[JoinName("XpanelOnlineStart")]
public JoinDataComplete XpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 5, AttributeName = "Online - XPanel" },
new JoinMetadata { Description = "Online - XPanel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
+ ///
+ /// Display Online Start
+ ///
[JoinName("DisplayOnlineStart")]
public JoinDataComplete DisplayOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 170, JoinSpan = 10, AttributeName = "Online - Display" },
new JoinMetadata { Description = "Online - Display", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
+ ///
+ /// Display 1 Laptop Source Start
+ ///
[JoinName("Display1LaptopSourceStart")]
- public JoinDataComplete Display1LaptopSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 166, JoinSpan = 5, AttributeName = "Display 1 - Source Laptop" },
+ public JoinDataComplete Display1LaptopSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 165, JoinSpan = 5, AttributeName = "Display 1 - Source Laptop" },
new JoinMetadata { Description = "Display 1 - Source Laptop", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
+ ///
+ /// Display 1 Disc Player Source Start
+ ///
[JoinName("Display1DiscPlayerSourceStart")]
- public JoinDataComplete Display1DiscPlayerSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 181, JoinSpan = 5, AttributeName = "Display 1 - Source Disc Player" },
+ public JoinDataComplete Display1DiscPlayerSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 180, JoinSpan = 5, AttributeName = "Display 1 - Source Disc Player" },
new JoinMetadata { Description = "Display 1 - Source Disc Player", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
+ ///
+ /// Display 1 Set Top Box Source Start
+ ///
[JoinName("Display1SetTopBoxSourceStart")]
- public JoinDataComplete Display1SetTopBoxSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 188, JoinSpan = 5, AttributeName = "Display 1 - Source TV" },
+ public JoinDataComplete Display1SetTopBoxSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 185, JoinSpan = 5, AttributeName = "Display 1 - Source TV" },
new JoinMetadata { Description = "Display 1 - Source TV", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
// Display 1
+ ///
+ /// Display 1 Start
+ ///
[JoinName("Display1Start")]
- public JoinDataComplete Display1Start = new JoinDataComplete(new JoinData { JoinNumber = 158, JoinSpan = 1 },
+ public JoinDataComplete Display1Start = new JoinDataComplete(new JoinData { JoinNumber = 190, JoinSpan = 1 },
new JoinMetadata { Description = "Display 1 Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
-
///
/// Constructor to use when instantiating this Join Map without inheriting from it
///
diff --git a/src/PepperDash.Essentials.Core/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/src/PepperDash.Essentials.Core/Fusion/IEssentialsRoomFusionController.cs
similarity index 82%
rename from src/PepperDash.Essentials.Core/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs
rename to src/PepperDash.Essentials.Core/Fusion/IEssentialsRoomFusionController.cs
index e2638493..1f21cbe6 100644
--- a/src/PepperDash.Essentials.Core/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs
+++ b/src/PepperDash.Essentials.Core/Fusion/IEssentialsRoomFusionController.cs
@@ -1,6 +1,4 @@
-
-
-using Crestron.SimplSharp;
+using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.CrestronXml;
using Crestron.SimplSharp.CrestronXml.Serialization;
@@ -8,6 +6,7 @@ using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.Fusion;
using Newtonsoft.Json;
using PepperDash.Core;
+using PepperDash.Core.Logging;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using Serilog.Events;
@@ -21,26 +20,42 @@ namespace PepperDash.Essentials.Core.Fusion
///
/// Represents a EssentialsHuddleSpaceFusionSystemControllerBase
///
- public class EssentialsHuddleSpaceFusionSystemControllerBase : Device, IOccupancyStatusProvider
+ public class IEssentialsRoomFusionController : EssentialsDevice, IOccupancyStatusProvider, IFusionHelpRequest
{
- private readonly EssentialsHuddleSpaceRoomFusionRoomJoinMap JoinMap;
+ private IEssentialsRoomFusionControllerPropertiesConfig _config;
+
+ private EssentialsHuddleSpaceRoomFusionRoomJoinMap JoinMap;
private const string RemoteOccupancyXml = "Local{0}";
- private readonly bool _guidFileExists;
+ private bool _guidFileExists;
private readonly Dictionary _sourceToFeedbackSigs =
new Dictionary();
+ ///
+ /// Gets or sets the CurrentRoomSourceNameSig
+ ///
protected StringSigData CurrentRoomSourceNameSig;
private readonly FusionCustomPropertiesBridge CustomPropertiesBridge = new FusionCustomPropertiesBridge();
+
+ ///
+ /// Gets or sets the FusionOccSensor
+ ///
protected FusionOccupancySensorAsset FusionOccSensor;
private readonly FusionRemoteOccupancySensor FusionRemoteOccSensor;
+ ///
+ /// Gets or sets the FusionRoom
+ ///
protected FusionRoom FusionRoom;
+
+ ///
+ /// Gets or sets the FusionStaticAssets
+ ///
protected Dictionary FusionStaticAssets;
private readonly long PushNotificationTimeout = 5000;
- private readonly IEssentialsRoom Room;
+ private IEssentialsRoom Room;
private readonly long SchedulePollInterval = 300000;
private Event _currentMeeting;
@@ -48,8 +63,7 @@ namespace PepperDash.Essentials.Core.Fusion
private CTimer _dailyTimeRequestTimer;
private StatusMonitorCollection _errorMessageRollUp;
- private FusionRoomGuids _guiDs;
- private uint _ipId;
+ private FusionRoomGuids _guids;
private bool _isRegisteredForSchedulePushNotifications;
private Event _nextMeeting;
@@ -60,6 +74,20 @@ namespace PepperDash.Essentials.Core.Fusion
private string _roomOccupancyRemoteString;
+ private bool _helpRequestSent;
+
+ private eFusionHelpResponse _helpRequestStatus;
+
+ ///
+ public StringFeedback HelpRequestResponseFeedback { get; private set; }
+
+ ///
+ public BoolFeedback HelpRequestSentFeedback { get; private set; }
+
+ ///
+ public StringFeedback HelpRequestStatusFeedback { get; private set; }
+
+
#region System Info Sigs
//StringSigData SystemName;
@@ -93,71 +121,110 @@ namespace PepperDash.Essentials.Core.Fusion
#endregion
- public EssentialsHuddleSpaceFusionSystemControllerBase(IEssentialsRoom room, uint ipId, string joinMapKey)
+ ///
+ /// Constructor
+ ///
+ public IEssentialsRoomFusionController(string key, string name, IEssentialsRoomFusionControllerPropertiesConfig config)
+ : base(key, name)
+ {
+ _config = config;
+
+ AddPostActivationAction(() =>
+ {
+ var room = DeviceManager.GetDeviceForKey(_config.RoomKey);
+
+ if (room == null)
+ {
+ this.LogError("Error Creating Fusion Room Controller. No room found with key '{0}'", _config.RoomKey);
+ return;
+ }
+
+ this.LogInformation("Creating Fusion Room Controller for room '{0}' at IPID: {1:X2}", room.Key, _config.IpIdInt);
+
+ ConstructorHelper(room, _config.IpIdInt, _config.JoinMapKey);
+
+ });
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IEssentialsRoomFusionController(IEssentialsRoom room, string ipId, string joinMapKey)
: base(room.Key + "-fusion")
+ {
+ _config = new IEssentialsRoomFusionControllerPropertiesConfig()
+ {
+ IpId = ipId,
+ RoomKey = room.Key,
+ JoinMapKey = joinMapKey
+ };
+
+ ConstructorHelper(room, _config.IpIdInt, joinMapKey);
+ }
+
+ private void ConstructorHelper(IEssentialsRoom room, uint ipId, string joinMapKey)
{
try
{
+ this.LogDebug("ConstructorHelper called for Fusion Room Controller for room '{0}' with IPID {1:X2}", room.Key, ipId);
+
+ this.LogDebug("JoinMap Key: {0}", joinMapKey);
+
JoinMap = new EssentialsHuddleSpaceRoomFusionRoomJoinMap(1);
- CrestronConsole.AddNewConsoleCommand((o) => JoinMap.PrintJoinMapInfo(), string.Format("ptjnmp-{0}", Key), "Prints Attribute Join Map", ConsoleAccessLevelEnum.AccessOperator);
+ this.LogDebug("JoinMap created");
+
+ CrestronConsole.AddNewConsoleCommand((o) =>
+ {
+ if (o is string deviceKey)
+ {
+ if (string.IsNullOrEmpty(deviceKey) || deviceKey == "?")
+ {
+ CrestronConsole.ConsoleCommandResponse("Please provide a device key for a Fusion Room instance");
+ return;
+ }
+ else if (deviceKey != this.Key)
+ {
+ return;
+ }
+ }
+ else
+ {
+ CrestronConsole.ConsoleCommandResponse("Invalid parameter. Please provide a device key for a Fusion Room instance");
+ return;
+ }
+
+ JoinMap.PrintJoinMapInfo();
+ }, "printfusionjoinmap", "Prints Attribute Join Map", ConsoleAccessLevelEnum.AccessOperator);
if (!string.IsNullOrEmpty(joinMapKey))
{
+ // this.LogDebug("Attempting to get custom join map for key: {0}", joinMapKey);
var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
if (customJoins != null)
{
JoinMap.SetCustomJoinData(customJoins);
}
}
-
+
Room = room;
- _ipId = ipId;
+ this.LogDebug("Room found: {0}", Room.Key);
FusionStaticAssets = new Dictionary();
- _guiDs = new FusionRoomGuids();
+ this.LogDebug("FusionStaticAssets dictionary created");
- 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);
- }
+ _guids = new FusionRoomGuids();
+ this.LogDebug("FusionRoomGuids created");
if (Room is IRoomOccupancy occupancyRoom)
{
+ Debug.LogDebug(this, "Room '{0}' supports IRoomOccupancy", Room.Key);
if (occupancyRoom.RoomOccupancy != null)
{
if (occupancyRoom.OccupancyStatusProviderIsRemote)
@@ -171,8 +238,8 @@ namespace PepperDash.Essentials.Core.Fusion
}
}
+ this.LogDebug("Occupancy setup complete");
- AddPostActivationAction(() => PostActivate(guidFilePath));
}
catch (Exception e)
{
@@ -180,9 +247,54 @@ namespace PepperDash.Essentials.Core.Fusion
}
}
- private void PostActivate(string guidFilePath)
+ private string GetGuidFilePath(uint ipId)
{
- CreateSymbolAndBasicSigs(_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, _config.IpIdInt);
+
+ 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;
+ }
+
+ ///
+ public override void Initialize()
+ {
+
+ GenerateGuidFile(GetGuidFilePath(_config.IpIdInt));
+
+ CreateSymbolAndBasicSigs(_config.IpIdInt);
SetUpSources();
SetUpCommunitcationMonitors();
SetUpDisplay();
@@ -191,12 +303,18 @@ namespace PepperDash.Essentials.Core.Fusion
FusionRVI.GenerateFileForAllFusionDevices();
- GenerateGuidFile(guidFilePath);
+ HelpRequestResponseFeedback = new StringFeedback("HelpRequestResponse", () => FusionRoom.Help.OutputSig.StringValue);
+
+ HelpRequestSentFeedback = new BoolFeedback("HelpRequestSent", () => _helpRequestSent);
+ HelpRequestStatusFeedback = new StringFeedback("HelpRequestStatus", () => _helpRequestStatus.ToString());
}
+ ///
+ /// Gets the RoomGuid
+ ///
protected string RoomGuid
{
- get { return _guiDs.RoomGuid; }
+ get { return _guids.RoomGuid; }
}
///
@@ -204,6 +322,9 @@ namespace PepperDash.Essentials.Core.Fusion
///
public StringFeedback RoomOccupancyRemoteStringFeedback { get; private set; }
+ ///
+ /// Gets the RoomIsOccupiedFeedbackFunc
+ ///
protected Func RoomIsOccupiedFeedbackFunc
{
get { return () => FusionRemoteOccSensor.RoomOccupied.OutputSig.BoolValue; }
@@ -218,10 +339,16 @@ namespace PepperDash.Essentials.Core.Fusion
#endregion
+ ///
+ /// ScheduleChange event
+ ///
public event EventHandler ScheduleChange;
//public event EventHandler MeetingEndWarning;
//public event EventHandler NextMeetingBeginWarning;
+ ///
+ /// RoomInfoChange event
+ ///
public event EventHandler RoomInfoChange;
//ScheduleResponseEvent NextMeeting;
@@ -258,11 +385,11 @@ namespace PepperDash.Essentials.Core.Fusion
Debug.LogMessage(LogEventLevel.Debug, this, "Writing GUIDs to file");
- _guiDs = FusionOccSensor == null
- ? new FusionRoomGuids(Room.Name, _ipId, RoomGuid, FusionStaticAssets)
- : new FusionRoomGuids(Room.Name, _ipId, RoomGuid, FusionStaticAssets, FusionOccSensor);
+ _guids = FusionOccSensor == null
+ ? new FusionRoomGuids(Room.Name, _config.IpIdInt, RoomGuid, FusionStaticAssets)
+ : new FusionRoomGuids(Room.Name, _config.IpIdInt, RoomGuid, FusionStaticAssets, FusionOccSensor);
- var json = JsonConvert.SerializeObject(_guiDs, Newtonsoft.Json.Formatting.Indented);
+ var json = JsonConvert.SerializeObject(_guids, Newtonsoft.Json.Formatting.Indented);
using (var sw = new StreamWriter(filePath))
{
@@ -312,17 +439,17 @@ namespace PepperDash.Essentials.Core.Fusion
{
var json = File.ReadToEnd(filePath, Encoding.ASCII);
- _guiDs = JsonConvert.DeserializeObject(json);
+ _guids = JsonConvert.DeserializeObject(json);
- _ipId = _guiDs.IpId;
+ // _config.IpId = _guids.IpId;
- FusionStaticAssets = _guiDs.StaticAssets;
+ FusionStaticAssets = _guids.StaticAssets;
}
Debug.LogMessage(LogEventLevel.Information, this, "Fusion Guids successfully read from file: {0}",
filePath);
- Debug.LogMessage(LogEventLevel.Debug, this, "\r\n********************\r\n\tRoom Name: {0}\r\n\tIPID: {1:X}\r\n\tRoomGuid: {2}\r\n*******************", Room.Name, _ipId, RoomGuid);
+ Debug.LogMessage(LogEventLevel.Debug, this, "\r\n********************\r\n\tRoom Name: {0}\r\n\tIPID: {1:X}\r\n\tRoomGuid: {2}\r\n*******************", Room.Name, _config.IpIdInt, RoomGuid);
foreach (var item in FusionStaticAssets)
{
@@ -343,6 +470,10 @@ namespace PepperDash.Essentials.Core.Fusion
}
}
+ ///
+ /// CreateSymbolAndBasicSigs method
+ ///
+ ///
protected virtual void CreateSymbolAndBasicSigs(uint ipId)
{
Debug.LogMessage(LogEventLevel.Information, this, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId);
@@ -405,6 +536,10 @@ namespace PepperDash.Essentials.Core.Fusion
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
}
+ ///
+ /// CrestronEnvironment_EthernetEventHandler method
+ ///
+ ///
protected void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs)
{
if (ethernetEventArgs.EthernetEventType == eEthernetEventType.LinkUp)
@@ -413,6 +548,9 @@ namespace PepperDash.Essentials.Core.Fusion
}
}
+ ///
+ /// GetSystemInfo method
+ ///
protected void GetSystemInfo()
{
//SystemName.InputSig.StringValue = Room.Name;
@@ -426,6 +564,9 @@ namespace PepperDash.Essentials.Core.Fusion
() => CrestronConsole.SendControlSystemCommand("reboot", ref response));
}
+ ///
+ /// SetUpEthernetValues method
+ ///
protected void SetUpEthernetValues()
{
_ip1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp1.JoinNumber, JoinMap.ProcessorIp1.AttributeName, eSigIoMask.InputSigOnly);
@@ -441,6 +582,9 @@ namespace PepperDash.Essentials.Core.Fusion
_netMask2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask2.JoinNumber, JoinMap.ProcessorNetMask2.AttributeName, eSigIoMask.InputSigOnly);
}
+ ///
+ /// GetProcessorEthernetValues method
+ ///
protected void GetProcessorEthernetValues()
{
_ip1.InputSig.StringValue =
@@ -475,7 +619,7 @@ namespace PepperDash.Essentials.Core.Fusion
// Interface 1
if (InitialParametersClass.NumberOfEthernetInterfaces > 1)
- // Only get these values if the processor has more than 1 NIC
+ // Only get these values if the processor has more than 1 NIC
{
_ip2.InputSig.StringValue =
CrestronEthernetHelper.GetEthernetParameter(
@@ -489,6 +633,9 @@ namespace PepperDash.Essentials.Core.Fusion
}
}
+ ///
+ /// GetProcessorInfo method
+ ///
protected void GetProcessorInfo()
{
_firmware = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorFirmware.JoinNumber, JoinMap.ProcessorFirmware.AttributeName, eSigIoMask.InputSigOnly);
@@ -499,7 +646,7 @@ namespace PepperDash.Essentials.Core.Fusion
{
var join = JoinMap.ProgramNameStart.JoinNumber + i;
var progNum = i + 1;
- _program[i] = FusionRoom.CreateOffsetStringSig((uint) join,
+ _program[i] = FusionRoom.CreateOffsetStringSig((uint)join,
string.Format("{0} {1}", JoinMap.ProgramNameStart.AttributeName, progNum), eSigIoMask.InputSigOnly);
}
}
@@ -507,6 +654,9 @@ namespace PepperDash.Essentials.Core.Fusion
_firmware.InputSig.StringValue = InitialParametersClass.FirmwareVersion;
}
+ ///
+ /// GetCustomProperties method
+ ///
protected void GetCustomProperties()
{
if (FusionRoom.IsOnline)
@@ -524,11 +674,16 @@ namespace PepperDash.Essentials.Core.Fusion
// TODO: Get IP and Project Name from TP
}
+ ///
+ /// FusionRoom_OnlineStatusChange method
+ ///
+ ///
+ ///
protected void FusionRoom_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
if (args.DeviceOnLine)
{
- CrestronInvoke.BeginInvoke( (o) =>
+ CrestronInvoke.BeginInvoke((o) =>
{
CrestronEnvironment.Sleep(200);
@@ -676,7 +831,7 @@ namespace PepperDash.Essentials.Core.Fusion
var extendTime = _currentMeeting.dtEnd - DateTime.Now;
var extendMinutesRaw = extendTime.TotalMinutes;
- extendMinutes += (int) Math.Round(extendMinutesRaw);
+ extendMinutes += (int)Math.Round(extendMinutesRaw);
}
@@ -784,11 +939,11 @@ namespace PepperDash.Essentials.Core.Fusion
var parameters = actionResponse["Parameters"];
foreach (var isRegistered in from XmlElement parameter in parameters
- where parameter.HasAttributes
- select parameter.Attributes
+ where parameter.HasAttributes
+ select parameter.Attributes
into attributes
- where attributes["ID"].Value == "Registered"
- select Int32.Parse(attributes["Value"].Value))
+ where attributes["ID"].Value == "Registered"
+ select Int32.Parse(attributes["Value"].Value))
{
switch (isRegistered)
{
@@ -845,9 +1000,9 @@ namespace PepperDash.Essentials.Core.Fusion
Debug.LogMessage(LogEventLevel.Debug, this, "DateTime from Fusion Server: {0}", currentTime);
// Parse time and date from response and insert values
- CrestronEnvironment.SetTimeAndDate((ushort) currentTime.Hour, (ushort) currentTime.Minute,
- (ushort) currentTime.Second, (ushort) currentTime.Month, (ushort) currentTime.Day,
- (ushort) currentTime.Year);
+ CrestronEnvironment.SetTimeAndDate((ushort)currentTime.Hour, (ushort)currentTime.Minute,
+ (ushort)currentTime.Second, (ushort)currentTime.Month, (ushort)currentTime.Day,
+ (ushort)currentTime.Year);
Debug.LogMessage(LogEventLevel.Debug, this, "Processor time set to {0}", CrestronEnvironment.GetLocalTime());
}
@@ -1065,6 +1220,9 @@ namespace PepperDash.Essentials.Core.Fusion
}
}
+ ///
+ /// SetUpSources method
+ ///
protected virtual void SetUpSources()
{
// Sources
@@ -1074,10 +1232,10 @@ namespace PepperDash.Essentials.Core.Fusion
// NEW PROCESS:
// Make these lists and insert the fusion attributes by iterating these
var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls);
- uint i = 1;
+ uint i = 0;
foreach (var kvp in setTopBoxes)
{
- TryAddRouteActionSigs(JoinMap.Display1SetTopBoxSourceStart.AttributeName + " " + i, JoinMap.Display1SetTopBoxSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
+ TryAddRouteActionSigs(JoinMap.Display1SetTopBoxSourceStart.AttributeName + " " + (i + 1), JoinMap.Display1SetTopBoxSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots
{
@@ -1086,10 +1244,10 @@ namespace PepperDash.Essentials.Core.Fusion
}
var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls);
- i = 1;
+ i = 0;
foreach (var kvp in discPlayers)
{
- TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
+ TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + (i + 1), JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > JoinMap.Display1DiscPlayerSourceStart.JoinSpan) // We only have five spots
{
@@ -1098,10 +1256,10 @@ namespace PepperDash.Essentials.Core.Fusion
}
var laptops = dict.Where(d => d.Value.SourceDevice is IRoutingSource);
- i = 1;
+ i = 0;
foreach (var kvp in laptops)
{
- TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.AttributeName + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
+ TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.AttributeName + " " + (i + 1), JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots???
{
@@ -1111,7 +1269,7 @@ namespace PepperDash.Essentials.Core.Fusion
foreach (var usageDevice in dict.Select(kvp => kvp.Value.SourceDevice).OfType())
{
- usageDevice.UsageTracker = new UsageTracking(usageDevice as Device) {UsageIsTracked = true};
+ usageDevice.UsageTracker = new UsageTracking(usageDevice as Device) { UsageIsTracked = true };
usageDevice.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
}
}
@@ -1157,17 +1315,31 @@ namespace PepperDash.Essentials.Core.Fusion
Debug.LogMessage(LogEventLevel.Debug, this, "Device usage string: {0}", deviceUsage);
}
-
+ ///
+ /// Tries to add route action sigs for a source
+ ///
+ ///
+ ///
+ ///
+ ///
protected void TryAddRouteActionSigs(string attrName, uint attrNum, string routeKey, Device pSrc)
{
- Debug.LogMessage(LogEventLevel.Verbose, this, "Creating attribute '{0}' with join {1} for source {2}",
+ this.LogVerbose("Creating attribute '{0}' with join {1} for source {2}",
attrName, attrNum, pSrc.Key);
try
{
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);
+ if (!_sourceToFeedbackSigs.ContainsKey(pSrc))
+ {
+ _sourceToFeedbackSigs.Add(pSrc, sigD.InputSig);
+ }
+ else
+ {
+ this.LogWarning("Source '{0}' already has a feedback sig mapped. Overwriting.", pSrc.Key);
+ _sourceToFeedbackSigs[pSrc] = sigD.InputSig;
+ }
// And respond to selection in Fusion
sigD.OutputSig.SetSigFalseAction(() =>
@@ -1180,14 +1352,12 @@ namespace PepperDash.Essentials.Core.Fusion
}
catch (Exception)
{
- Debug.LogMessage(LogEventLevel.Verbose, this, "Error creating Fusion signal {0} {1} for device '{2}'. THIS NEEDS REWORKING",
+ this.LogVerbose("Error creating Fusion signal {0} {1} for device '{2}'. THIS NEEDS REWORKING",
attrNum, attrName, pSrc.Key);
}
}
- ///
- ///
- ///
+
private void SetUpCommunitcationMonitors()
{
uint displayNum = 0;
@@ -1274,6 +1444,8 @@ namespace PepperDash.Essentials.Core.Fusion
if (attrName != null)
{
+ this.LogDebug("Linking communication monitor for device '{0}' to Fusion attribute '{1}' at join {2}",
+ dev.Key, attrName, attrNum);
// Link comm status to sig and update
var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputSigOnly);
var smd = dev as ICommunicationMonitor;
@@ -1285,6 +1457,9 @@ namespace PepperDash.Essentials.Core.Fusion
}
}
+ ///
+ /// SetUpDisplay method
+ ///
protected virtual void SetUpDisplay()
{
try
@@ -1297,7 +1472,7 @@ namespace PepperDash.Essentials.Core.Fusion
foreach (var display in displays.Cast())
{
- display.UsageTracker = new UsageTracking(display as Device) {UsageIsTracked = true};
+ display.UsageTracker = new UsageTracking(display as Device) { UsageIsTracked = true };
display.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
}
@@ -1410,7 +1585,7 @@ namespace PepperDash.Essentials.Core.Fusion
// Power on
- var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint) joinOffset, displayName + "Power On",
+ var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On",
eSigIoMask.InputOutputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action(b =>
{
@@ -1421,7 +1596,7 @@ namespace PepperDash.Essentials.Core.Fusion
});
// Power Off
- var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 1, displayName + "Power Off",
+ var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off",
eSigIoMask.InputOutputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action(b =>
{
@@ -1439,7 +1614,7 @@ namespace PepperDash.Essentials.Core.Fusion
}
// Current Source
- var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 8,
+ var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8,
displayName + "Source None", eSigIoMask.InputOutputSig);
defaultDisplaySourceNone.OutputSig.UserObject = new Action(b =>
{
@@ -1507,7 +1682,7 @@ namespace PepperDash.Essentials.Core.Fusion
//if (Room.OccupancyObj != null)
//{
- var tempOccAsset = _guiDs.OccupancyAsset;
+ var tempOccAsset = _guids.OccupancyAsset;
if (tempOccAsset == null)
{
@@ -1532,7 +1707,7 @@ namespace PepperDash.Essentials.Core.Fusion
occRoom.RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
}
RoomOccupancyRemoteStringFeedback = new StringFeedback(() => _roomOccupancyRemoteString);
-
+
RoomOccupancyRemoteStringFeedback.LinkInputSig(occSensorAsset.RoomOccupancyInfo.InputSig);
//}
@@ -1588,12 +1763,74 @@ namespace PepperDash.Essentials.Core.Fusion
}
}
+ ///
+ /// Event handler for Fusion state changes
+ ///
+ ///
+ ///
protected void FusionRoom_FusionStateChange(FusionBase device, FusionStateEventArgs args)
{
+ if (args.EventId == FusionEventIds.HelpMessageReceivedEventId)
+ {
+ this.LogInformation( "Help message received from Fusion for room '{0}'",
+ Room.Name);
+
+ this.LogDebug("Help message content: {0}", FusionRoom.Help.OutputSig.StringValue);
+ // Fire help request event
+ HelpRequestResponseFeedback.FireUpdate();
+
+ if (!string.IsNullOrEmpty(FusionRoom.Help.OutputSig.StringValue))
+ {
+ switch (FusionRoom.Help.OutputSig.StringValue)
+ {
+ case "Please wait, a technician is on his / her way.":
+ // this.LogInformation("Please wait, a technician is on his / her way.",
+ // Room.Name);
+
+ _helpRequestStatus = eFusionHelpResponse.HelpOnTheWay;
+ break;
+ case "Please call the helpdesk.":
+ // this.LogInformation("Please call the helpdesk.");
+ // _helpRequestStatus = eFusionHelpResponse.CallHelpDesk;
+ break;
+ case "Please wait, I will reschedule your meeting to a different room.":
+ // this.LogInformation("Please wait, I will reschedule your meeting to a different room.",
+ // Room.Name);
+
+ _helpRequestStatus = eFusionHelpResponse.ReschedulingMeeting;
+ break;
+ case "I will be taking control of your system. Please be patient while I adjust the settings.":
+ // this.LogInformation("I will be taking control of your system. Please be patient while I adjust the settings.",
+ // Room.Name);
+
+ _helpRequestStatus = eFusionHelpResponse.TakingControl;
+ break;
+ default:
+ // this.LogInformation("Unknown help request code received from Fusion for room '{0}'",
+ // Room.Name);
+
+ _helpRequestStatus = eFusionHelpResponse.None;
+ break;
+ }
+ }
+ else
+ {
+ _helpRequestStatus = eFusionHelpResponse.None;
+ }
+
+ if(_helpRequestStatus == eFusionHelpResponse.None)
+ {
+ _helpRequestSent = false;
+ HelpRequestSentFeedback.FireUpdate();
+ }
+
+ HelpRequestStatusFeedback.FireUpdate();
+ }
+
+
// The sig/UO method: Need separate handlers for fixed and user sigs, all flavors,
// even though they all contain sigs.
-
BoolOutputSig outSig;
if (args.UserConfiguredSigDetail is BooleanSigDataFixedName sigData)
{
@@ -1632,9 +1869,69 @@ namespace PepperDash.Essentials.Core.Fusion
(outSig.UserObject as Action).Invoke(outSig.StringValue);
}
}
+
+ ///
+ public void SendHelpRequest()
+ {
+
+ var now = DateTime.Now;
+
+ var breakString = _config.UseHtmlFormatForHelpRequests ? "
" : "\r\n";
+
+ var date = now.ToString("MMMM dd, yyyy");
+ var time = now.ToString("hh:mm tt");
+ if (_config.Use24HourTimeFormat)
+ {
+ time = now.ToString("HH:mm");
+ }
+
+ var requestString = $"HR00: {breakString} Assistance has been requested from room {Room.Name}{breakString}on {date} at {time}";
+
+ FusionRoom.Help.InputSig.StringValue = requestString;
+
+ this.LogInformation("Help request sent to Fusion from room '{0}'", Room.Name);
+ this.LogDebug("Help request content: {0}", FusionRoom.Help.InputSig.StringValue);
+
+ _helpRequestSent = true;
+ HelpRequestSentFeedback.FireUpdate();
+
+ _helpRequestStatus = eFusionHelpResponse.HelpRequested;
+ HelpRequestStatusFeedback.FireUpdate();
+ }
+
+ ///
+ public void CancelHelpRequest()
+ {
+ if (_helpRequestSent)
+ {
+ FusionRoom.Help.InputSig.StringValue = "";
+ _helpRequestSent = false;
+ HelpRequestSentFeedback.FireUpdate();
+ _helpRequestStatus = eFusionHelpResponse.None;
+ HelpRequestStatusFeedback.FireUpdate();
+ Debug.LogMessage(LogEventLevel.Information, this, "Help request cancelled in Fusion for room '{0}'", Room.Name);
+ }
+ }
+
+ ///
+ public void ToggleHelpRequest()
+ {
+ if (_helpRequestSent)
+ {
+ CancelHelpRequest();
+ }
+ else
+ {
+ SendHelpRequest();
+ }
+ }
+
}
+ ///
+ /// Extensions to enhance Fusion room, asset and signal creation.
+ ///
public static class FusionRoomExtensions
{
///
@@ -1648,6 +1945,8 @@ namespace PepperDash.Essentials.Core.Fusion
///
public static BooleanSigData CreateOffsetBoolSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
{
+ Debug.LogDebug("Creating Offset Bool Sig: {0} at Join {1}", name, number);
+
if (number < 50)
{
throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
@@ -1668,6 +1967,8 @@ namespace PepperDash.Essentials.Core.Fusion
///
public static UShortSigData CreateOffsetUshortSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
{
+ Debug.LogDebug("Creating Offset UShort Sig: {0} at Join {1}", name, number);
+
if (number < 50)
{
throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
@@ -1688,6 +1989,8 @@ namespace PepperDash.Essentials.Core.Fusion
///
public static StringSigData CreateOffsetStringSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
{
+ Debug.LogDebug("Creating Offset String Sig: {0} at Join {1}", name, number);
+
if (number < 50)
{
throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
@@ -1803,6 +2106,9 @@ namespace PepperDash.Essentials.Core.Fusion
///
public class RoomInformation
{
+ ///
+ /// Constructor
+ ///
public RoomInformation()
{
FusionCustomProperties = new List();
@@ -1855,10 +2161,17 @@ namespace PepperDash.Essentials.Core.Fusion
///
public class FusionCustomProperty
{
+ ///
+ /// Constructor
+ ///
public FusionCustomProperty()
{
}
+ ///
+ /// Constructor with id
+ ///
+ ///
public FusionCustomProperty(string id)
{
ID = id;
diff --git a/src/PepperDash.Essentials.Core/Fusion/IEssentialsRoomFusionControllerFactory.cs b/src/PepperDash.Essentials.Core/Fusion/IEssentialsRoomFusionControllerFactory.cs
new file mode 100644
index 00000000..e874762c
--- /dev/null
+++ b/src/PepperDash.Essentials.Core/Fusion/IEssentialsRoomFusionControllerFactory.cs
@@ -0,0 +1,33 @@
+using System.Collections.Generic;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Fusion;
+
+///
+/// Factory for creating IEssentialsRoomFusionController devices
+///
+public class IEssentialsRoomFusionControllerFactory : EssentialsDeviceFactory
+{
+ ///
+ /// Constructor
+ ///
+ public IEssentialsRoomFusionControllerFactory()
+ {
+ TypeNames = new List() { "fusionRoom" };
+ }
+
+ ///
+ /// Builds the device
+ ///
+ ///
+ ///
+ public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc)
+ {
+ Debug.LogDebug("Factory Attempting to create new IEssentialsRoomFusionController Device");
+
+
+ var properties = dc.Properties.ToObject();
+
+ return new IEssentialsRoomFusionController(dc.Key, dc.Name, properties);
+ }
+}
\ No newline at end of file
diff --git a/src/PepperDash.Essentials.Core/Fusion/IEssentialsRoomFusionControllerPropertiesConfig.cs b/src/PepperDash.Essentials.Core/Fusion/IEssentialsRoomFusionControllerPropertiesConfig.cs
new file mode 100644
index 00000000..4dc4a834
--- /dev/null
+++ b/src/PepperDash.Essentials.Core/Fusion/IEssentialsRoomFusionControllerPropertiesConfig.cs
@@ -0,0 +1,59 @@
+using Newtonsoft.Json;
+using PepperDash.Core;
+
+///
+/// Config properties for an IEssentialsRoomFusionController device
+///
+public class IEssentialsRoomFusionControllerPropertiesConfig
+{
+ ///
+ /// Gets or sets the IP ID of the Fusion Room Controller
+ ///
+ [JsonProperty("ipId")]
+ public string IpId { get; set; }
+
+ ///
+ /// Gets the IP ID as a UInt16
+ ///
+ [JsonIgnore]
+ public uint IpIdInt
+ {
+ get
+ {
+ // Try to parse the IpId string to UInt16 as hex
+ if (ushort.TryParse(IpId, System.Globalization.NumberStyles.HexNumber, null, out ushort result))
+ {
+ return result;
+ }
+ else
+ {
+ Debug.LogWarning( "Failed to parse IpId '{0}' as UInt16", IpId);
+ return 0;
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the join map key
+ ///
+ [JsonProperty("joinMapKey")]
+ public string JoinMapKey { get; set; }
+
+ ///
+ /// Gets or sets the room key associated with this Fusion Room Controller
+ ///
+ [JsonProperty("roomKey")]
+ public string RoomKey { get; set; }
+
+ ///
+ /// Gets or sets whether to use HTML format for help requests
+ ///
+ [JsonProperty("useHtmlFormatForHelpRequests")]
+ public bool UseHtmlFormatForHelpRequests { get; set; } = false;
+
+ ///
+ /// Gets or sets whether to use 24-hour time format
+ ///
+ [JsonProperty("use24HourTimeFormat")]
+ public bool Use24HourTimeFormat { get; set; } = false;
+}
\ No newline at end of file
diff --git a/src/PepperDash.Essentials.Core/Fusion/IFusionHelpRequest.cs b/src/PepperDash.Essentials.Core/Fusion/IFusionHelpRequest.cs
new file mode 100644
index 00000000..de4cca17
--- /dev/null
+++ b/src/PepperDash.Essentials.Core/Fusion/IFusionHelpRequest.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PepperDash.Essentials.Core.Fusion
+{
+ ///
+ /// Represents Fusion Help Request functionality
+ ///
+ public interface IFusionHelpRequest
+ {
+ ///
+ /// Feedback containing the response to a help request
+ ///
+ StringFeedback HelpRequestResponseFeedback { get; }
+
+ ///
+ /// Indicates whether a help request has been sent
+ ///
+ BoolFeedback HelpRequestSentFeedback { get; }
+
+ ///
+ /// Feedback containing the current status of the help request
+ ///
+ StringFeedback HelpRequestStatusFeedback { get; }
+
+ ///
+ /// Sends a help request
+ ///
+ void SendHelpRequest();
+
+ ///
+ /// Clears the current help request status
+ ///
+ void CancelHelpRequest();
+
+ ///
+ /// Toggles between sending and cancelling a help request
+ ///
+ void ToggleHelpRequest();
+ }
+}
diff --git a/src/PepperDash.Essentials.Core/Fusion/eFusionHelpResponse.cs b/src/PepperDash.Essentials.Core/Fusion/eFusionHelpResponse.cs
new file mode 100644
index 00000000..6a5bbcd8
--- /dev/null
+++ b/src/PepperDash.Essentials.Core/Fusion/eFusionHelpResponse.cs
@@ -0,0 +1,37 @@
+
+
+namespace PepperDash.Essentials.Core.Fusion
+{
+ ///
+ /// Enumeration of possible Fusion Help Responses based on the standard responses from Fusion
+ ///
+ public enum eFusionHelpResponse
+ {
+ ///
+ /// No help response
+ ///
+ None,
+ ///
+ /// Help has been requested
+ ///
+ HelpRequested,
+ ///
+ /// Help is on the way
+ ///
+ HelpOnTheWay,
+ ///
+ /// Please call the helpdesk.
+ ///
+ CallHelpDesk,
+ ///
+ /// Rescheduling meeting.
+ ///
+ ReschedulingMeeting,
+
+ ///
+ /// Technician taking control.
+ ///
+ TakingControl,
+ }
+
+}
\ No newline at end of file
diff --git a/src/PepperDash.Essentials.Core/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs b/src/PepperDash.Essentials.Core/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs
index 49b51f67..d6f3c503 100644
--- a/src/PepperDash.Essentials.Core/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs
+++ b/src/PepperDash.Essentials.Core/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs
@@ -49,7 +49,7 @@ namespace PepperDash.Essentials.Core
///
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);
diff --git a/src/PepperDash.Essentials.Core/Room/EssentialsRoomBase.cs b/src/PepperDash.Essentials.Core/Room/EssentialsRoomBase.cs
index dfb8b5a1..38e4456e 100644
--- a/src/PepperDash.Essentials.Core/Room/EssentialsRoomBase.cs
+++ b/src/PepperDash.Essentials.Core/Room/EssentialsRoomBase.cs
@@ -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)