mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-12 19:24:53 +00:00
Mega refactor in progress
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles mapping Fusion Custom Property values to system properties
|
||||
/// </summary>
|
||||
public class FusionCustomPropertiesBridge
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates the room info and custom properties from Fusion and updates the system properties aa needed
|
||||
/// </summary>
|
||||
/// <param name="roomInfo"></param>
|
||||
public void EvaluateRoomInfo(string roomKey, RoomInformation roomInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
var reconfigurableDevices = DeviceManager.AllDevices.Where(d => d is ReconfigurableDevice);
|
||||
|
||||
foreach (var device in reconfigurableDevices)
|
||||
{
|
||||
// Get the current device config so new values can be overwritten over existing
|
||||
var deviceConfig = (device as ReconfigurableDevice).Config;
|
||||
|
||||
if (device is RoomOnToDefaultSourceWhenOccupied)
|
||||
{
|
||||
Debug.Console(1, "Mapping Room on via Occupancy values from Fusion");
|
||||
|
||||
var devProps = JsonConvert.DeserializeObject<RoomOnToDefaultSourceWhenOccupiedConfig>(deviceConfig.Properties.ToString());
|
||||
|
||||
var enableFeature = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupied"));
|
||||
if (enableFeature != null)
|
||||
devProps.EnableRoomOnWhenOccupied = bool.Parse(enableFeature.CustomFieldValue);
|
||||
|
||||
var enableTime = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("RoomOnWhenOccupiedStartTime"));
|
||||
if (enableTime != null)
|
||||
devProps.OccupancyStartTime = enableTime.CustomFieldValue;
|
||||
|
||||
var disableTime = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("RoomOnWhenOccupiedEndTime"));
|
||||
if (disableTime != null)
|
||||
devProps.OccupancyEndTime = disableTime.CustomFieldValue;
|
||||
|
||||
var enableSunday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedSun"));
|
||||
if (enableSunday != null)
|
||||
devProps.EnableSunday = bool.Parse(enableSunday.CustomFieldValue);
|
||||
|
||||
var enableMonday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedMon"));
|
||||
if (enableMonday != null)
|
||||
devProps.EnableMonday = bool.Parse(enableMonday.CustomFieldValue);
|
||||
|
||||
var enableTuesday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedTue"));
|
||||
if (enableTuesday != null)
|
||||
devProps.EnableTuesday = bool.Parse(enableTuesday.CustomFieldValue);
|
||||
|
||||
var enableWednesday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedWed"));
|
||||
if (enableWednesday != null)
|
||||
devProps.EnableWednesday = bool.Parse(enableWednesday.CustomFieldValue);
|
||||
|
||||
var enableThursday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedThu"));
|
||||
if (enableThursday != null)
|
||||
devProps.EnableThursday = bool.Parse(enableThursday.CustomFieldValue);
|
||||
|
||||
var enableFriday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedFri"));
|
||||
if (enableFriday != null)
|
||||
devProps.EnableFriday = bool.Parse(enableFriday.CustomFieldValue);
|
||||
|
||||
var enableSaturday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedSat"));
|
||||
if (enableSaturday != null)
|
||||
devProps.EnableSaturday = bool.Parse(enableSaturday.CustomFieldValue);
|
||||
|
||||
deviceConfig.Properties = JToken.FromObject(devProps);
|
||||
}
|
||||
else if (device is EssentialsRoomBase)
|
||||
{
|
||||
// Set the room name
|
||||
if (!string.IsNullOrEmpty(roomInfo.Name))
|
||||
{
|
||||
Debug.Console(1, "Current Room Name: {0}. New Room Name: {1}", deviceConfig.Name, roomInfo.Name);
|
||||
// Set the name in config
|
||||
deviceConfig.Name = roomInfo.Name;
|
||||
|
||||
Debug.Console(1, "Room Name Successfully Changed.");
|
||||
}
|
||||
|
||||
// Set the help message
|
||||
var helpMessage = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("RoomHelpMessage"));
|
||||
if (helpMessage != null)
|
||||
{
|
||||
//Debug.Console(1, "Current Help Message: {0}. New Help Message: {1}", deviceConfig.Properties["help"]["message"].Value<string>(ToString()), helpMessage.CustomFieldValue);
|
||||
deviceConfig.Properties["helpMessage"] = (string)helpMessage.CustomFieldValue;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the config on the device
|
||||
(device as ReconfigurableDevice).SetConfig(deviceConfig);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, "FusionCustomPropetiesBridge: Error mapping properties: {0}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
public class ScheduleChangeEventArgs : EventArgs
|
||||
{
|
||||
public RoomSchedule Schedule { get; set; }
|
||||
}
|
||||
|
||||
public class MeetingChangeEventArgs : EventArgs
|
||||
{
|
||||
public Event Meeting { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
/// <summary>
|
||||
/// When created, runs progcomments on every slot and stores the program names in a list
|
||||
/// </summary>
|
||||
public class ProcessorProgReg
|
||||
{
|
||||
//public static Dictionary<int, ProcessorProgramItem> Programs { get; private set; }
|
||||
|
||||
public static Dictionary<int, ProcessorProgramItem> GetProcessorProgReg()
|
||||
{
|
||||
var programs = new Dictionary<int, ProcessorProgramItem>();
|
||||
for (int i = 1; i <= Global.ControlSystem.NumProgramsSupported; i++)
|
||||
{
|
||||
string response = null;
|
||||
var success = CrestronConsole.SendControlSystemCommand("progcomments:" + i, ref response);
|
||||
var item = new ProcessorProgramItem();
|
||||
if (!success)
|
||||
item.Name = "Error: PROGCOMMENTS failed";
|
||||
else
|
||||
{
|
||||
if (response.ToLower().Contains("bad or incomplete"))
|
||||
item.Name = "";
|
||||
else
|
||||
{
|
||||
var startPos = response.IndexOf("Program File");
|
||||
var colonPos = response.IndexOf(":", startPos) + 1;
|
||||
var endPos = response.IndexOf(CrestronEnvironment.NewLine, colonPos);
|
||||
item.Name = response.Substring(colonPos, endPos - colonPos).Trim();
|
||||
item.Exists = true;
|
||||
if (item.Name.Contains(".dll"))
|
||||
{
|
||||
startPos = response.IndexOf("Compiler Revision");
|
||||
colonPos = response.IndexOf(":", startPos) + 1;
|
||||
endPos = response.IndexOf(CrestronEnvironment.NewLine, colonPos);
|
||||
item.Name = item.Name + "_v" + response.Substring(colonPos, endPos - colonPos).Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
programs[i] = item;
|
||||
Debug.Console(1, "Program {0}: {1}", i, item.Name);
|
||||
}
|
||||
return programs;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used in ProcessorProgReg
|
||||
/// </summary>
|
||||
public class ProcessorProgramItem
|
||||
{
|
||||
public bool Exists { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,499 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.Fusion;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
// Helper Classes for GUIDs
|
||||
|
||||
/// <summary>
|
||||
/// Stores GUIDs to be written to a file in NVRAM
|
||||
/// </summary>
|
||||
public class FusionRoomGuids
|
||||
{
|
||||
public string RoomName { get; set; }
|
||||
public uint IpId { get; set; }
|
||||
public string RoomGuid { get; set; }
|
||||
public FusionOccupancySensorAsset OccupancyAsset { get; set; }
|
||||
public Dictionary<int, FusionAsset> StaticAssets { get; set; }
|
||||
|
||||
public FusionRoomGuids()
|
||||
{
|
||||
StaticAssets = new Dictionary<int, FusionAsset>();
|
||||
OccupancyAsset = new FusionOccupancySensorAsset();
|
||||
}
|
||||
|
||||
public FusionRoomGuids(string roomName, uint ipId, string roomGuid, Dictionary<int, FusionAsset> staticAssets)
|
||||
{
|
||||
RoomName = roomName;
|
||||
IpId = ipId;
|
||||
RoomGuid = roomGuid;
|
||||
|
||||
StaticAssets = staticAssets;
|
||||
OccupancyAsset = new FusionOccupancySensorAsset();
|
||||
}
|
||||
|
||||
public FusionRoomGuids(string roomName, uint ipId, string roomGuid, Dictionary<int, FusionAsset> staticAssets, FusionOccupancySensorAsset occAsset)
|
||||
{
|
||||
RoomName = roomName;
|
||||
IpId = ipId;
|
||||
RoomGuid = roomGuid;
|
||||
|
||||
StaticAssets = staticAssets;
|
||||
OccupancyAsset = occAsset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a new room GUID prefixed by the program slot number and NIC MAC address
|
||||
/// </summary>
|
||||
/// <param name="progSlot"></param>
|
||||
/// <param name="mac"></param>
|
||||
public string GenerateNewRoomGuid(uint progSlot, string mac)
|
||||
{
|
||||
Guid roomGuid = Guid.NewGuid();
|
||||
|
||||
return string.Format("{0}-{1}-{2}", progSlot, mac, roomGuid.ToString());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds an asset to the StaticAssets collection and returns the new asset
|
||||
/// </summary>
|
||||
/// <param name="room"></param>
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="assetName"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="instanceId"></param>
|
||||
/// <returns></returns>
|
||||
public FusionAsset AddStaticAsset(FusionRoom room, int uid, string assetName, string type, string instanceId)
|
||||
{
|
||||
var slotNum = GetNextAvailableAssetNumber(room);
|
||||
|
||||
Debug.Console(2, "Adding Fusion Asset: {0} of Type: {1} at Slot Number: {2} with GUID: {3}", assetName, type, slotNum, instanceId);
|
||||
|
||||
var tempAsset = new FusionAsset(slotNum, assetName, type, instanceId);
|
||||
|
||||
StaticAssets.Add(uid, tempAsset);
|
||||
|
||||
return tempAsset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the next available slot number in the Fusion UserConfigurableAssetDetails collection
|
||||
/// </summary>
|
||||
/// <param name="room"></param>
|
||||
/// <returns></returns>
|
||||
public static uint GetNextAvailableAssetNumber(FusionRoom room)
|
||||
{
|
||||
uint slotNum = 0;
|
||||
|
||||
foreach (var item in room.UserConfigurableAssetDetails)
|
||||
{
|
||||
if(item.Number > slotNum)
|
||||
slotNum = item.Number;
|
||||
}
|
||||
|
||||
if (slotNum < 5)
|
||||
{
|
||||
slotNum = 5;
|
||||
}
|
||||
else
|
||||
slotNum = slotNum + 1;
|
||||
|
||||
Debug.Console(2, "#Next available fusion asset number is: {0}", slotNum);
|
||||
|
||||
return slotNum;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class FusionOccupancySensorAsset
|
||||
{
|
||||
// SlotNumber fixed at 4
|
||||
|
||||
public uint SlotNumber { get { return 4; } }
|
||||
public string Name { get { return "Occupancy Sensor"; } }
|
||||
public eAssetType Type { get; set; }
|
||||
public string InstanceId { get; set; }
|
||||
|
||||
public FusionOccupancySensorAsset()
|
||||
{
|
||||
}
|
||||
|
||||
public FusionOccupancySensorAsset(eAssetType type)
|
||||
{
|
||||
Type = type;
|
||||
|
||||
InstanceId = Guid.NewGuid().ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class FusionAsset
|
||||
{
|
||||
public uint SlotNumber { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string InstanceId { get;set; }
|
||||
|
||||
public FusionAsset()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public FusionAsset(uint slotNum, string assetName, string type, string instanceId)
|
||||
{
|
||||
SlotNumber = slotNum;
|
||||
Name = assetName;
|
||||
Type = type;
|
||||
if (string.IsNullOrEmpty(instanceId))
|
||||
{
|
||||
InstanceId = Guid.NewGuid().ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
InstanceId = instanceId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************************************
|
||||
|
||||
public class RoomSchedule
|
||||
{
|
||||
public List<Event> Meetings { get; set; }
|
||||
|
||||
public RoomSchedule()
|
||||
{
|
||||
Meetings = new List<Event>();
|
||||
}
|
||||
}
|
||||
|
||||
//****************************************************************************************************
|
||||
// Helper Classes for XML API
|
||||
|
||||
/// <summary>
|
||||
/// Data needed to request the local time from the Fusion server
|
||||
/// </summary>
|
||||
public class LocalTimeRequest
|
||||
{
|
||||
public string RequestID { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// All the data needed for a full schedule request in a room
|
||||
/// </summary>
|
||||
/// //[XmlRoot(ElementName = "RequestSchedule")]
|
||||
public class RequestSchedule
|
||||
{
|
||||
//[XmlElement(ElementName = "RequestID")]
|
||||
public string RequestID { get; set; }
|
||||
//[XmlElement(ElementName = "RoomID")]
|
||||
public string RoomID { get; set; }
|
||||
//[XmlElement(ElementName = "Start")]
|
||||
public DateTime Start { get; set; }
|
||||
//[XmlElement(ElementName = "HourSpan")]
|
||||
public double HourSpan { get; set; }
|
||||
|
||||
public RequestSchedule(string requestID, string roomID)
|
||||
{
|
||||
RequestID = requestID;
|
||||
RoomID = roomID;
|
||||
Start = DateTime.Now;
|
||||
HourSpan = 24;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//[XmlRoot(ElementName = "RequestAction")]
|
||||
public class RequestAction
|
||||
{
|
||||
//[XmlElement(ElementName = "RequestID")]
|
||||
public string RequestID { get; set; }
|
||||
//[XmlElement(ElementName = "RoomID")]
|
||||
public string RoomID { get; set; }
|
||||
//[XmlElement(ElementName = "ActionID")]
|
||||
public string ActionID { get; set; }
|
||||
//[XmlElement(ElementName = "Parameters")]
|
||||
public List<Parameter> Parameters { get; set; }
|
||||
|
||||
public RequestAction(string roomID, string actionID, List<Parameter> parameters)
|
||||
{
|
||||
RoomID = roomID;
|
||||
ActionID = actionID;
|
||||
Parameters = parameters;
|
||||
}
|
||||
}
|
||||
|
||||
//[XmlRoot(ElementName = "ActionResponse")]
|
||||
public class ActionResponse
|
||||
{
|
||||
//[XmlElement(ElementName = "RequestID")]
|
||||
public string RequestID { get; set; }
|
||||
//[XmlElement(ElementName = "ActionID")]
|
||||
public string ActionID { get; set; }
|
||||
//[XmlElement(ElementName = "Parameters")]
|
||||
public List<Parameter> Parameters { get; set; }
|
||||
}
|
||||
|
||||
//[XmlRoot(ElementName = "Parameter")]
|
||||
public class Parameter
|
||||
{
|
||||
//[XmlAttribute(AttributeName = "ID")]
|
||||
public string ID { get; set; }
|
||||
//[XmlAttribute(AttributeName = "Value")]
|
||||
public string Value { get; set; }
|
||||
}
|
||||
|
||||
////[XmlRoot(ElementName = "Parameters")]
|
||||
//public class Parameters
|
||||
//{
|
||||
// //[XmlElement(ElementName = "Parameter")]
|
||||
// public List<Parameter> Parameter { get; set; }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Data structure for a ScheduleResponse from Fusion
|
||||
/// </summary>
|
||||
/// //[XmlRoot(ElementName = "ScheduleResponse")]
|
||||
public class ScheduleResponse
|
||||
{
|
||||
//[XmlElement(ElementName = "RequestID")]
|
||||
public string RequestID { get; set; }
|
||||
//[XmlElement(ElementName = "RoomID")]
|
||||
public string RoomID { get; set; }
|
||||
//[XmlElement(ElementName = "RoomName")]
|
||||
public string RoomName { get; set; }
|
||||
//[XmlElement("Event")]
|
||||
public List<Event> Events { get; set; }
|
||||
|
||||
public ScheduleResponse()
|
||||
{
|
||||
Events = new List<Event>();
|
||||
}
|
||||
}
|
||||
|
||||
//[XmlRoot(ElementName = "Event")]
|
||||
public class Event
|
||||
{
|
||||
//[XmlElement(ElementName = "MeetingID")]
|
||||
public string MeetingID { get; set; }
|
||||
//[XmlElement(ElementName = "RVMeetingID")]
|
||||
public string RVMeetingID { get; set; }
|
||||
//[XmlElement(ElementName = "Recurring")]
|
||||
public string Recurring { get; set; }
|
||||
//[XmlElement(ElementName = "InstanceID")]
|
||||
public string InstanceID { get; set; }
|
||||
//[XmlElement(ElementName = "dtStart")]
|
||||
public DateTime dtStart { get; set; }
|
||||
//[XmlElement(ElementName = "dtEnd")]
|
||||
public DateTime dtEnd { get; set; }
|
||||
//[XmlElement(ElementName = "Organizer")]
|
||||
public string Organizer { get; set; }
|
||||
//[XmlElement(ElementName = "Attendees")]
|
||||
public Attendees Attendees { get; set; }
|
||||
//[XmlElement(ElementName = "Resources")]
|
||||
public Resources Resources { get; set; }
|
||||
//[XmlElement(ElementName = "IsEvent")]
|
||||
public string IsEvent { get; set; }
|
||||
//[XmlElement(ElementName = "IsRoomViewMeeting")]
|
||||
public string IsRoomViewMeeting { get; set; }
|
||||
//[XmlElement(ElementName = "IsPrivate")]
|
||||
public string IsPrivate { get; set; }
|
||||
//[XmlElement(ElementName = "IsExchangePrivate")]
|
||||
public string IsExchangePrivate { get; set; }
|
||||
//[XmlElement(ElementName = "MeetingTypes")]
|
||||
public MeetingTypes MeetingTypes { get; set; }
|
||||
//[XmlElement(ElementName = "ParticipantCode")]
|
||||
public string ParticipantCode { get; set; }
|
||||
//[XmlElement(ElementName = "PhoneNo")]
|
||||
public string PhoneNo { get; set; }
|
||||
//[XmlElement(ElementName = "WelcomeMsg")]
|
||||
public string WelcomeMsg { get; set; }
|
||||
//[XmlElement(ElementName = "Subject")]
|
||||
public string Subject { get; set; }
|
||||
//[XmlElement(ElementName = "LiveMeeting")]
|
||||
public LiveMeeting LiveMeeting { get; set; }
|
||||
//[XmlElement(ElementName = "ShareDocPath")]
|
||||
public string ShareDocPath { get; set; }
|
||||
//[XmlElement(ElementName = "HaveAttendees")]
|
||||
public string HaveAttendees { get; set; }
|
||||
//[XmlElement(ElementName = "HaveResources")]
|
||||
public string HaveResources { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the duration of the meeting
|
||||
/// </summary>
|
||||
public string DurationInMinutes
|
||||
{
|
||||
get
|
||||
{
|
||||
string duration;
|
||||
|
||||
var timeSpan = dtEnd.Subtract(dtStart);
|
||||
int hours = timeSpan.Hours;
|
||||
double minutes = timeSpan.Minutes;
|
||||
double roundedMinutes = Math.Round(minutes);
|
||||
if (hours > 0)
|
||||
{
|
||||
duration = string.Format("{0} hours {1} minutes", hours, roundedMinutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
duration = string.Format("{0} minutes", roundedMinutes);
|
||||
}
|
||||
|
||||
return duration;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the remaining time in the meeting. Returns null if the meeting is not currently in progress.
|
||||
/// </summary>
|
||||
public string RemainingTime
|
||||
{
|
||||
get
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
||||
string remainingTime;
|
||||
|
||||
if (GetInProgress())
|
||||
{
|
||||
var timeSpan = dtEnd.Subtract(now);
|
||||
int hours = timeSpan.Hours;
|
||||
double minutes = timeSpan.Minutes;
|
||||
double roundedMinutes = Math.Round(minutes);
|
||||
if (hours > 0)
|
||||
{
|
||||
remainingTime = string.Format("{0} hours {1} minutes", hours, roundedMinutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
remainingTime = string.Format("{0} minutes", roundedMinutes);
|
||||
}
|
||||
|
||||
return remainingTime;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the meeting is in progress
|
||||
/// </summary>
|
||||
public bool isInProgress
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetInProgress();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the meeting is in progress
|
||||
/// </summary>
|
||||
/// <returns>Returns true if in progress</returns>
|
||||
bool GetInProgress()
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
||||
if (now > dtStart && now < dtEnd)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//[XmlRoot(ElementName = "Resources")]
|
||||
public class Resources
|
||||
{
|
||||
//[XmlElement(ElementName = "Rooms")]
|
||||
public Rooms Rooms { get; set; }
|
||||
}
|
||||
|
||||
//[XmlRoot(ElementName = "Rooms")]
|
||||
public class Rooms
|
||||
{
|
||||
//[XmlElement(ElementName = "Room")]
|
||||
public List<Room> Room { get; set; }
|
||||
}
|
||||
|
||||
//[XmlRoot(ElementName = "Room")]
|
||||
public class Room
|
||||
{
|
||||
//[XmlElement(ElementName = "Name")]
|
||||
public string Name { get; set; }
|
||||
//[XmlElement(ElementName = "ID")]
|
||||
public string ID { get; set; }
|
||||
//[XmlElement(ElementName = "MPType")]
|
||||
public string MPType { get; set; }
|
||||
}
|
||||
|
||||
//[XmlRoot(ElementName = "Attendees")]
|
||||
public class Attendees
|
||||
{
|
||||
//[XmlElement(ElementName = "Required")]
|
||||
public Required Required { get; set; }
|
||||
//[XmlElement(ElementName = "Optional")]
|
||||
public Optional Optional { get; set; }
|
||||
}
|
||||
|
||||
//[XmlRoot(ElementName = "Required")]
|
||||
public class Required
|
||||
{
|
||||
//[XmlElement(ElementName = "Attendee")]
|
||||
public List<string> Attendee { get; set; }
|
||||
}
|
||||
|
||||
//[XmlRoot(ElementName = "Optional")]
|
||||
public class Optional
|
||||
{
|
||||
//[XmlElement(ElementName = "Attendee")]
|
||||
public List<string> Attendee { get; set; }
|
||||
}
|
||||
|
||||
//[XmlRoot(ElementName = "MeetingType")]
|
||||
public class MeetingType
|
||||
{
|
||||
//[XmlAttribute(AttributeName = "ID")]
|
||||
public string ID { get; set; }
|
||||
//[XmlAttribute(AttributeName = "Value")]
|
||||
public string Value { get; set; }
|
||||
}
|
||||
|
||||
//[XmlRoot(ElementName = "MeetingTypes")]
|
||||
public class MeetingTypes
|
||||
{
|
||||
//[XmlElement(ElementName = "MeetingType")]
|
||||
public List<MeetingType> MeetingType { get; set; }
|
||||
}
|
||||
|
||||
//[XmlRoot(ElementName = "LiveMeeting")]
|
||||
public class LiveMeeting
|
||||
{
|
||||
//[XmlElement(ElementName = "URL")]
|
||||
public string URL { get; set; }
|
||||
//[XmlElement(ElementName = "ID")]
|
||||
public string ID { get; set; }
|
||||
//[XmlElement(ElementName = "Key")]
|
||||
public string Key { get; set; }
|
||||
//[XmlElement(ElementName = "Subject")]
|
||||
public string Subject { get; set; }
|
||||
}
|
||||
|
||||
//[XmlRoot(ElementName = "LiveMeetingURL")]
|
||||
public class LiveMeetingURL
|
||||
{
|
||||
//[XmlElement(ElementName = "LiveMeeting")]
|
||||
public LiveMeeting LiveMeeting { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
//}
|
||||
Reference in New Issue
Block a user