diff --git a/src/PepperDash.Essentials.Core/Room/Config/EssentialsDualDisplayRoomPropertiesConfig.cs b/src/PepperDash.Essentials.Core/Room/Config/EssentialsDualDisplayRoomPropertiesConfig.cs new file mode 100644 index 00000000..3b3489bf --- /dev/null +++ b/src/PepperDash.Essentials.Core/Room/Config/EssentialsDualDisplayRoomPropertiesConfig.cs @@ -0,0 +1,8 @@ + +namespace PDT.Plugins.Essentials.Rooms.Config +{ + public class EssentialsDualDisplayRoomPropertiesConfig : EssentialsNDisplayRoomPropertiesConfig + { + + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Room/Config/EssentialsHuddleRoomPropertiesConfig.cs b/src/PepperDash.Essentials.Core/Room/Config/EssentialsHuddleRoomPropertiesConfig.cs new file mode 100644 index 00000000..76a35689 --- /dev/null +++ b/src/PepperDash.Essentials.Core/Room/Config/EssentialsHuddleRoomPropertiesConfig.cs @@ -0,0 +1,34 @@ +using Newtonsoft.Json; + +namespace PDT.Plugins.Essentials.Rooms.Config +{ + /// + /// + /// + public class EssentialsHuddleRoomPropertiesConfig : EssentialsRoomPropertiesConfig + { + /// + /// The key of the default display device + /// + [JsonProperty("defaultDisplayKey")] + public string DefaultDisplayKey { get; set; } + + /// + /// The key of the default audio device + /// + [JsonProperty("defaultAudioKey")] + public string DefaultAudioKey { get; set; } + + /// + /// The key of the source list for the room + /// + [JsonProperty("sourceListKey")] + public string SourceListKey { get; set; } + + /// + /// The key of the default source item from the source list + /// + [JsonProperty("defaultSourceItem")] + public string DefaultSourceItem { get; set; } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Room/Config/EssentialsHuddleVtc1PropertiesConfig.cs b/src/PepperDash.Essentials.Core/Room/Config/EssentialsHuddleVtc1PropertiesConfig.cs new file mode 100644 index 00000000..0071d9ee --- /dev/null +++ b/src/PepperDash.Essentials.Core/Room/Config/EssentialsHuddleVtc1PropertiesConfig.cs @@ -0,0 +1,13 @@ + +using Newtonsoft.Json; + +namespace PDT.Plugins.Essentials.Rooms.Config +{ + + public class EssentialsHuddleVtc1PropertiesConfig : EssentialsConferenceRoomPropertiesConfig + { + [JsonProperty("defaultDisplayKey")] + public string DefaultDisplayKey { get; set; } + + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Room/Config/EssentialsNDisplayRoomPropertiesConfig.cs b/src/PepperDash.Essentials.Core/Room/Config/EssentialsNDisplayRoomPropertiesConfig.cs new file mode 100644 index 00000000..7d4d2bc4 --- /dev/null +++ b/src/PepperDash.Essentials.Core/Room/Config/EssentialsNDisplayRoomPropertiesConfig.cs @@ -0,0 +1,34 @@ + +using System.Collections.Generic; +using Newtonsoft.Json; +using PepperDash.Core; +using PepperDash.Essentials.Core; + +namespace PDT.Plugins.Essentials.Rooms.Config +{ + /// + /// + /// + public class EssentialsNDisplayRoomPropertiesConfig : EssentialsConferenceRoomPropertiesConfig + { + [JsonProperty("defaultAudioBehavior")] + public string DefaultAudioBehavior { get; set; } + [JsonProperty("defaultVideoBehavior")] + public string DefaultVideoBehavior { get; set; } + [JsonProperty("displays")] + public Dictionary Displays { get; set; } + + public EssentialsNDisplayRoomPropertiesConfig() + { + Displays = new Dictionary(); + } + + } + + public class DisplayItem : IKeyName + { + public string Key { get; set; } + public string Name { get; set; } + } + +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Room/Config/EssentialsPresentationPropertiesConfig.cs b/src/PepperDash.Essentials.Core/Room/Config/EssentialsPresentationPropertiesConfig.cs new file mode 100644 index 00000000..125a818f --- /dev/null +++ b/src/PepperDash.Essentials.Core/Room/Config/EssentialsPresentationPropertiesConfig.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +namespace PDT.Plugins.Essentials.Rooms.Config +{ + /// + /// + /// + public class EssentialsPresentationRoomPropertiesConfig : EssentialsRoomPropertiesConfig + { + public string DefaultAudioBehavior { get; set; } + public string DefaultAudioKey { get; set; } + public string DefaultVideoBehavior { get; set; } + public List DisplayKeys { get; set; } + public string SourceListKey { get; set; } + public bool HasDsp { get; set; } + + public EssentialsPresentationRoomPropertiesConfig() + { + DisplayKeys = new List(); + } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Room/Config/EssentialsRoomConfig.cs b/src/PepperDash.Essentials.Core/Room/Config/EssentialsRoomConfig.cs new file mode 100644 index 00000000..ac5f7b10 --- /dev/null +++ b/src/PepperDash.Essentials.Core/Room/Config/EssentialsRoomConfig.cs @@ -0,0 +1,406 @@ +using System; +using System.Collections.Generic; +using Crestron.SimplSharp; +using Newtonsoft.Json; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.Privacy; + +namespace PDT.Plugins.Essentials.Rooms.Config +{ + public class EssentialsRoomConfigHelper + { + /// + /// Returns a room object from this config data + /// + /// + public static IKeyed GetRoomObject(DeviceConfig roomConfig) + { + var typeName = roomConfig.Type.ToLower(); + + switch (typeName) + { + case "huddle" : + { + return new EssentialsHuddleSpaceRoom(roomConfig); + } + case "huddlevtc1" : + { + return new EssentialsHuddleVtc1Room(roomConfig); + } + case "ddvc01bridge" : + { + return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing. + } + case "dualdisplay" : + { + return new EssentialsDualDisplayRoom(roomConfig); + } + case "combinedhuddlevtc1" : + { + return new EssentialsCombinedHuddleVtc1Room(roomConfig); + } + case "techroom" : + { + return new EssentialsTechRoom(roomConfig); + } + default : + { + return DeviceFactory.GetDevice(roomConfig); + } + } + } + + /// + /// Gets and operating, standalone emergegncy object that can be plugged into a room. + /// Returns null if there is no emergency defined + /// + public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, IEssentialsRoom room) + { + // This emergency + var emergency = props.Emergency; + if (emergency != null) + { + //switch on emergency type here. Right now only contact and shutdown + var e = new EssentialsRoomEmergencyContactClosure(room.Key + "-emergency", props.Emergency, room); + DeviceManager.AddDevice(e); + } + return null; + } + + /// + /// + /// + /// + /// + /// + public static MicrophonePrivacyController GetMicrophonePrivacy( + EssentialsRoomPropertiesConfig props, IPrivacy room) + { + var microphonePrivacy = props.MicrophonePrivacy; + if (microphonePrivacy == null) + { + Debug.Console(0, "Cannot create microphone privacy with null properties"); + return null; + } + // Get the MicrophonePrivacy device from the device manager + var mP = (DeviceManager.GetDeviceForKey(props.MicrophonePrivacy.DeviceKey) as MicrophonePrivacyController); + // Set this room as the IPrivacy device + if (mP == null) + { + Debug.Console(0, "ERROR: Selected device {0} is not MicrophonePrivacyController", props.MicrophonePrivacy.DeviceKey); + return null; + } + mP.SetPrivacyDevice(room); + + var behaviour = props.MicrophonePrivacy.Behaviour.ToLower(); + + if (behaviour == null) + { + Debug.Console(0, "WARNING: No behaviour defined for MicrophonePrivacyController"); + return null; + } + if (behaviour == "trackroomstate") + { + // Tie LED enable to room power state + var essRoom = room as IEssentialsRoom; + essRoom.OnFeedback.OutputChange += (o, a) => + { + if (essRoom.OnFeedback.BoolValue) + mP.EnableLeds = true; + else + mP.EnableLeds = false; + }; + + mP.EnableLeds = essRoom.OnFeedback.BoolValue; + } + else if (behaviour == "trackcallstate") + { + // Tie LED enable to room power state + var inCallRoom = room as IHasInCallFeedback; + inCallRoom.InCallFeedback.OutputChange += (o, a) => + { + if (inCallRoom.InCallFeedback.BoolValue) + mP.EnableLeds = true; + else + mP.EnableLeds = false; + }; + + mP.EnableLeds = inCallRoom.InCallFeedback.BoolValue; + } + + return mP; + } + + } + + /// + /// + /// + public class EssentialsRoomPropertiesConfig + { + [JsonProperty("addresses")] + public EssentialsRoomAddressPropertiesConfig Addresses { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + + [JsonProperty("emergency")] + public EssentialsRoomEmergencyConfig Emergency { get; set; } + + [JsonProperty("help")] + public EssentialsHelpPropertiesConfig Help { get; set; } + + [JsonProperty("helpMessage")] + public string HelpMessage { get; set; } + + /// + /// Read this value to get the help message. It checks for the old and new config format. + /// + public string HelpMessageForDisplay + { + get + { + if(Help != null && !string.IsNullOrEmpty(Help.Message)) + { + return Help.Message; + } + else + { + return HelpMessage; + } + } + } + + [JsonProperty("environment")] + public EssentialsEnvironmentPropertiesConfig Environment { get; set; } + + [JsonProperty("logo")] + public EssentialsLogoPropertiesConfig LogoLight { get; set; } + + [JsonProperty("logoDark")] + public EssentialsLogoPropertiesConfig LogoDark { get; set; } + + [JsonProperty("microphonePrivacy")] + public EssentialsRoomMicrophonePrivacyConfig MicrophonePrivacy { get; set; } + + [JsonProperty("occupancy")] + public EssentialsRoomOccSensorConfig Occupancy { get; set; } + + [JsonProperty("oneButtonMeeting")] + public EssentialsOneButtonMeetingPropertiesConfig OneButtonMeeting { get; set; } + + [JsonProperty("shutdownVacancySeconds")] + public int ShutdownVacancySeconds { get; set; } + + [JsonProperty("shutdownPromptSeconds")] + public int ShutdownPromptSeconds { get; set; } + + [JsonProperty("tech")] + public EssentialsRoomTechConfig Tech { get; set; } + + [JsonProperty("volumes")] + public EssentialsRoomVolumesConfig Volumes { get; set; } + + [JsonProperty("fusion")] + public EssentialsRoomFusionConfig Fusion { get; set; } + + [JsonProperty("essentialsRoomUiBehaviorConfig", NullValueHandling=NullValueHandling.Ignore)] + public EssentialsRoomUiBehaviorConfig UiBehavior { get; set; } + + [JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")] + public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; } + + /// + /// Indicates if this room represents a combination of other rooms + /// + [JsonProperty("isRoomCombinationScenario")] + public bool IsRoomCombinationScenario { get; set; } + + public EssentialsRoomPropertiesConfig() + { + LogoLight = new EssentialsLogoPropertiesConfig(); + LogoDark = new EssentialsLogoPropertiesConfig(); + } + } + + public class EssentialsRoomUiBehaviorConfig + { + [JsonProperty("disableActivityButtonsWhileWarmingCooling")] + public bool DisableActivityButtonsWhileWarmingCooling { get; set; } + } + + public class EssentialsAvRoomPropertiesConfig : EssentialsRoomPropertiesConfig + { + [JsonProperty("defaultAudioKey")] + public string DefaultAudioKey { get; set; } + [JsonProperty("sourceListKey")] + public string SourceListKey { get; set; } + [JsonProperty("destinationListKey")] + public string DestinationListKey { get; set; } + [JsonProperty("defaultSourceItem")] + public string DefaultSourceItem { get; set; } + /// + /// Indicates if the room supports advanced sharing + /// + [JsonProperty("supportsAdvancedSharing")] + public bool SupportsAdvancedSharing { get; set; } + /// + /// Indicates if non-tech users can change the share mode + /// + [JsonProperty("userCanChangeShareMode")] + public bool UserCanChangeShareMode { 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; } + + [JsonProperty("deviceKeys")] + public List DeviceKeys { get; set; } + + public EssentialsEnvironmentPropertiesConfig() + { + DeviceKeys = new List(); + } + + } + + public class EssentialsRoomFusionConfig + { + public uint IpIdInt + { + get + { + try + { + return Convert.ToUInt32(IpId, 16); + } + catch (Exception) + { + throw new FormatException(string.Format("ERROR:Unable to convert IP ID: {0} to hex. Error:\n{1}", IpId)); + } + + } + } + + [JsonProperty("ipId")] + public string IpId { get; set; } + + [JsonProperty("joinMapKey")] + public string JoinMapKey { get; set; } + + } + + public class EssentialsRoomMicrophonePrivacyConfig + { + [JsonProperty("deviceKey")] + public string DeviceKey { get; set; } + + [JsonProperty("behaviour")] + public string Behaviour { get; set; } + } + + /// + /// Properties for the help text box + /// + public class EssentialsHelpPropertiesConfig + { + [JsonProperty("message")] + public string Message { get; set; } + + [JsonProperty("showCallButton")] + public bool ShowCallButton { get; set; } + + /// + /// Defaults to "Call Help Desk" + /// + [JsonProperty("callButtonText")] + public string CallButtonText { get; set; } + + public EssentialsHelpPropertiesConfig() + { + CallButtonText = "Call Help Desk"; + } + } + + /// + /// + /// + public class EssentialsOneButtonMeetingPropertiesConfig + { + [JsonProperty("enable")] + public bool Enable { get; set; } + } + + public class EssentialsRoomAddressPropertiesConfig + { + [JsonProperty("phoneNumber")] + public string PhoneNumber { get; set; } + + [JsonProperty("sipAddress")] + public string SipAddress { get; set; } + } + + + /// + /// Properties for the room's logo on panels + /// + public class EssentialsLogoPropertiesConfig + { + [JsonProperty("type")] + public string Type { get; set; } + + [JsonProperty("url")] + public string Url { get; set; } + /// + /// Gets either the custom URL, a local-to-processor URL, or null if it's a default logo + /// + public string GetLogoUrlLight() + { + if (Type == "url") + return Url; + if (Type == "system") + return string.Format("http://{0}:8080/logo.png", + CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0)); + return null; + } + + public string GetLogoUrlDark() + { + if (Type == "url") + return Url; + if (Type == "system") + return string.Format("http://{0}:8080/logo-dark.png", + CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0)); + return null; + } + } + + /// + /// Represents occupancy sensor(s) setup for a room + /// + public class EssentialsRoomOccSensorConfig + { + [JsonProperty("deviceKey")] + public string DeviceKey { get; set; } + + [JsonProperty("timeoutMinutes")] + public int TimeoutMinutes { get; set; } + } + + public class EssentialsRoomTechConfig + { + [JsonProperty("password")] + public string Password { get; set; } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Room/Config/EssentialsRoomEmergencyConfig.cs b/src/PepperDash.Essentials.Core/Room/Config/EssentialsRoomEmergencyConfig.cs new file mode 100644 index 00000000..0100f006 --- /dev/null +++ b/src/PepperDash.Essentials.Core/Room/Config/EssentialsRoomEmergencyConfig.cs @@ -0,0 +1,30 @@ +namespace PDT.Plugins.Essentials.Rooms.Config +{ + /// + /// + /// + public class EssentialsRoomEmergencyConfig + { + public EssentialsRoomEmergencyTriggerConfig Trigger { get; set; } + + public string Behavior { get; set; } + } + + /// + /// + /// + public class EssentialsRoomEmergencyTriggerConfig + { + /// + /// contact, + /// + public string Type { get; set; } + /// + /// Input number if contact + /// + public int Number { get; set; } + + public bool TriggerOnClose { get; set; } + + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Room/Config/EssentialsTechRoomConfig.cs b/src/PepperDash.Essentials.Core/Room/Config/EssentialsTechRoomConfig.cs new file mode 100644 index 00000000..1de4128d --- /dev/null +++ b/src/PepperDash.Essentials.Core/Room/Config/EssentialsTechRoomConfig.cs @@ -0,0 +1,77 @@ + +using System.Collections.Generic; +using Newtonsoft.Json; +using PepperDash.Essentials.Room.Config; + +namespace PDT.Plugins.Essentials.Rooms.Config +{ + public class EssentialsTechRoomConfig + { + /// + /// The key of the dummy device used to enable routing + /// + [JsonProperty("dummySourceKey")] + public string DummySourceKey { get; set; } + + /// + /// The keys of the displays assigned to this room + /// + [JsonProperty("displays")] + public List Displays { get; set; } + + /// + /// The keys of the tuners assinged to this room + /// + [JsonProperty("tuners")] + public List Tuners { get; set; } + + /// + /// PIN to access the room as a normal user + /// + [JsonProperty("userPin")] + public string UserPin { get; set; } + + /// + /// PIN to access the room as a tech user + /// + [JsonProperty("techPin")] + public string TechPin { get; set; } + + /// + /// Name of the presets file. Path prefix is assumed to be /html/presets/lists/ + /// + [JsonProperty("presetsFileName")] + public string PresetsFileName { get; set; } + + [JsonProperty("scheduledEvents")] + public List ScheduledEvents { get; set; } + + /// + /// Indicates that the room is the primary when true + /// + [JsonProperty("isPrimary")] + public bool IsPrimary { get; set; } + + /// + /// Indicates which tuners should mirror preset recall when two rooms are configured in a primary->secondary scenario + /// + [JsonProperty("mirroredTuners")] + public Dictionary MirroredTuners { get; set; } + + [JsonProperty("helpMessage")] + public string HelpMessage { get; set; } + + /// + /// Indicates the room + /// + [JsonProperty("isTvPresetsProvider")] + public bool IsTvPresetsProvider; + + public EssentialsTechRoomConfig() + { + Displays = new List(); + Tuners = new List(); + ScheduledEvents = new List(); + } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Room/Config/SimplRoomPropertiesConfig.cs b/src/PepperDash.Essentials.Core/Room/Config/SimplRoomPropertiesConfig.cs new file mode 100644 index 00000000..52aac362 --- /dev/null +++ b/src/PepperDash.Essentials.Core/Room/Config/SimplRoomPropertiesConfig.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace PDT.Plugins.Essentials.Rooms.Config +{ + public class SimplRoomPropertiesConfig : EssentialsHuddleVtc1PropertiesConfig + { + [JsonProperty("roomPhoneNumber")] + public string RoomPhoneNumber { get; set; } + [JsonProperty("roomURI")] + public string RoomURI { get; set; } + [JsonProperty("speedDials")] + public List SpeedDials { get; set; } + [JsonProperty("volumeSliderNames")] + public List VolumeSliderNames { get; set; } + } + + public class SimplSpeedDial + { + [JsonProperty("name")] + public string Name { get; set; } + [JsonProperty("number")] + public string Number { get; set; } + } +} \ No newline at end of file