mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-03-29 09:04:56 +00:00
Compare commits
2 Commits
v3.0.0-dev
...
dev/v3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4d53dbe0e | ||
|
|
43a9661e08 |
@@ -131,12 +131,6 @@ public class GenericTcpIpClient : Device, ISocketStatusWithStreamDebugging, IAut
|
||||
/// </summary>
|
||||
public string ClientStatusText { get { return ClientStatus.ToString(); } }
|
||||
|
||||
/// <summary>
|
||||
/// Ushort representation of client status
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
public ushort UClientStatus { get { return (ushort)ClientStatus; } }
|
||||
|
||||
/// <summary>
|
||||
/// Connection failure reason
|
||||
/// </summary>
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Core.WebApi.Presets;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a preset
|
||||
/// </summary>
|
||||
public class Preset
|
||||
{
|
||||
/// <summary>
|
||||
/// ID of preset
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User ID
|
||||
/// </summary>
|
||||
public int UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Room Type ID
|
||||
/// </summary>
|
||||
public int RoomTypeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Preset Name
|
||||
/// </summary>
|
||||
public string PresetName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Preset Number
|
||||
/// </summary>
|
||||
public int PresetNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Preset Data
|
||||
/// </summary>
|
||||
public string Data { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public Preset()
|
||||
{
|
||||
PresetName = "";
|
||||
PresetNumber = 1;
|
||||
Data = "{}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a PresetReceivedEventArgs
|
||||
/// </summary>
|
||||
public class PresetReceivedEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// True when the preset is found
|
||||
/// </summary>
|
||||
public bool LookupSuccess { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// S+ helper
|
||||
/// </summary>
|
||||
public ushort ULookupSuccess { get { return (ushort)(LookupSuccess ? 1 : 0); } }
|
||||
|
||||
/// <summary>
|
||||
/// The preset
|
||||
/// </summary>
|
||||
public Preset Preset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// For Simpl+
|
||||
/// </summary>
|
||||
public PresetReceivedEventArgs() { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="preset"></param>
|
||||
/// <param name="success"></param>
|
||||
public PresetReceivedEventArgs(Preset preset, bool success)
|
||||
{
|
||||
LookupSuccess = success;
|
||||
Preset = preset;
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Core.WebApi.Presets;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class User
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string ExternalId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string FirstName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string LastName { get; set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UserReceivedEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// True when user is found
|
||||
/// </summary>
|
||||
public bool LookupSuccess { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// For stupid S+
|
||||
/// </summary>
|
||||
public ushort ULookupSuccess { get { return (ushort)(LookupSuccess ? 1 : 0); } }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public User User { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// For Simpl+
|
||||
/// </summary>
|
||||
public UserReceivedEventArgs() { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="success"></param>
|
||||
public UserReceivedEventArgs(User user, bool success)
|
||||
{
|
||||
LookupSuccess = success;
|
||||
User = user;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a UserAndRoomMessage
|
||||
/// </summary>
|
||||
public class UserAndRoomMessage
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int RoomTypeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int PresetNumber { get; set; }
|
||||
}
|
||||
@@ -1,280 +0,0 @@
|
||||
extern alias NewtonsoftJson;
|
||||
|
||||
using System;
|
||||
using Crestron.SimplSharp; // For Basic SIMPL# Classes
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharp.Net.Http;
|
||||
using Crestron.SimplSharp.Net.Https;
|
||||
using JsonConvert = NewtonsoftJson::Newtonsoft.Json.JsonConvert;
|
||||
using JObject = NewtonsoftJson::Newtonsoft.Json.Linq.JObject;
|
||||
using PepperDash.Core.JsonToSimpl;
|
||||
|
||||
|
||||
namespace PepperDash.Core.WebApi.Presets;
|
||||
|
||||
/// <summary>
|
||||
/// Passcode client for the WebApi
|
||||
/// </summary>
|
||||
public class WebApiPasscodeClient : IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// Notifies when user received
|
||||
/// </summary>
|
||||
public event EventHandler<UserReceivedEventArgs> UserReceived;
|
||||
|
||||
/// <summary>
|
||||
/// Notifies when Preset received
|
||||
/// </summary>
|
||||
public event EventHandler<PresetReceivedEventArgs> PresetReceived;
|
||||
|
||||
/// <summary>
|
||||
/// Unique identifier for this instance
|
||||
/// </summary>
|
||||
public string Key { get; private set; }
|
||||
|
||||
//string JsonMasterKey;
|
||||
|
||||
/// <summary>
|
||||
/// An embedded JsonToSimpl master object.
|
||||
/// </summary>
|
||||
JsonToSimplGenericMaster J2SMaster;
|
||||
|
||||
string UrlBase;
|
||||
|
||||
string DefaultPresetJsonFilePath;
|
||||
|
||||
User CurrentUser;
|
||||
|
||||
Preset CurrentPreset;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// SIMPL+ can only execute the default constructor. If you have variables that require initialization, please
|
||||
/// use an Initialize method
|
||||
/// </summary>
|
||||
public WebApiPasscodeClient()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the instance
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="jsonMasterKey"></param>
|
||||
/// <param name="urlBase"></param>
|
||||
/// <param name="defaultPresetJsonFilePath"></param>
|
||||
public void Initialize(string key, string jsonMasterKey, string urlBase, string defaultPresetJsonFilePath)
|
||||
{
|
||||
Key = key;
|
||||
//JsonMasterKey = jsonMasterKey;
|
||||
UrlBase = urlBase;
|
||||
DefaultPresetJsonFilePath = defaultPresetJsonFilePath;
|
||||
|
||||
J2SMaster = new JsonToSimplGenericMaster();
|
||||
J2SMaster.SaveCallback = this.SaveCallback;
|
||||
J2SMaster.Initialize(jsonMasterKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user for a passcode
|
||||
/// </summary>
|
||||
/// <param name="passcode"></param>
|
||||
public void GetUserForPasscode(string passcode)
|
||||
{
|
||||
// Bullshit duplicate code here... These two cases should be the same
|
||||
// except for https/http and the certificate ignores
|
||||
if (!UrlBase.StartsWith("https"))
|
||||
return;
|
||||
var req = new HttpsClientRequest();
|
||||
req.Url = new UrlParser(UrlBase + "/api/users/dopin");
|
||||
req.RequestType = Crestron.SimplSharp.Net.Https.RequestType.Post;
|
||||
req.Header.AddHeader(new HttpsHeader("Content-Type", "application/json"));
|
||||
req.Header.AddHeader(new HttpsHeader("Accept", "application/json"));
|
||||
var jo = new JObject();
|
||||
jo.Add("pin", passcode);
|
||||
req.ContentString = jo.ToString();
|
||||
|
||||
var client = new HttpsClient();
|
||||
client.HostVerification = false;
|
||||
client.PeerVerification = false;
|
||||
var resp = client.Dispatch(req);
|
||||
var handler = UserReceived;
|
||||
if (resp.Code == 200)
|
||||
{
|
||||
//CrestronConsole.PrintLine("Received: {0}", resp.ContentString);
|
||||
var user = JsonConvert.DeserializeObject<User>(resp.ContentString);
|
||||
CurrentUser = user;
|
||||
if (handler != null)
|
||||
UserReceived(this, new UserReceivedEventArgs(user, true));
|
||||
}
|
||||
else
|
||||
if (handler != null)
|
||||
UserReceived(this, new UserReceivedEventArgs(null, false));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="roomTypeId"></param>
|
||||
/// <param name="presetNumber"></param>
|
||||
/// <summary>
|
||||
/// GetPresetForThisUser method
|
||||
/// </summary>
|
||||
public void GetPresetForThisUser(int roomTypeId, int presetNumber)
|
||||
{
|
||||
if (CurrentUser == null)
|
||||
{
|
||||
CrestronConsole.PrintLine("GetPresetForThisUser no user loaded");
|
||||
return;
|
||||
}
|
||||
|
||||
var msg = new UserAndRoomMessage
|
||||
{
|
||||
UserId = CurrentUser.Id,
|
||||
RoomTypeId = roomTypeId,
|
||||
PresetNumber = presetNumber
|
||||
};
|
||||
|
||||
var handler = PresetReceived;
|
||||
try
|
||||
{
|
||||
if (!UrlBase.StartsWith("https"))
|
||||
return;
|
||||
var req = new HttpsClientRequest();
|
||||
req.Url = new UrlParser(UrlBase + "/api/presets/userandroom");
|
||||
req.RequestType = Crestron.SimplSharp.Net.Https.RequestType.Post;
|
||||
req.Header.AddHeader(new HttpsHeader("Content-Type", "application/json"));
|
||||
req.Header.AddHeader(new HttpsHeader("Accept", "application/json"));
|
||||
req.ContentString = JsonConvert.SerializeObject(msg);
|
||||
|
||||
var client = new HttpsClient();
|
||||
client.HostVerification = false;
|
||||
client.PeerVerification = false;
|
||||
|
||||
// ask for the preset
|
||||
var resp = client.Dispatch(req);
|
||||
if (resp.Code == 200) // got it
|
||||
{
|
||||
//Debug.Console(1, this, "Received: {0}", resp.ContentString);
|
||||
var preset = JsonConvert.DeserializeObject<Preset>(resp.ContentString);
|
||||
CurrentPreset = preset;
|
||||
|
||||
//if there's no preset data, load the template
|
||||
if (preset.Data == null || preset.Data.Trim() == string.Empty || JObject.Parse(preset.Data).Count == 0)
|
||||
{
|
||||
//Debug.Console(1, this, "Loaded preset has no data. Loading default template.");
|
||||
LoadDefaultPresetData();
|
||||
return;
|
||||
}
|
||||
|
||||
J2SMaster.LoadWithJson(preset.Data);
|
||||
if (handler != null)
|
||||
PresetReceived(this, new PresetReceivedEventArgs(preset, true));
|
||||
}
|
||||
else // no existing preset
|
||||
{
|
||||
CurrentPreset = new Preset();
|
||||
LoadDefaultPresetData();
|
||||
if (handler != null)
|
||||
PresetReceived(this, new PresetReceivedEventArgs(null, false));
|
||||
}
|
||||
}
|
||||
catch (HttpException e)
|
||||
{
|
||||
var resp = e.Response;
|
||||
Debug.Console(1, this, "No preset received (code {0}). Loading default template", resp.Code);
|
||||
LoadDefaultPresetData();
|
||||
if (handler != null)
|
||||
PresetReceived(this, new PresetReceivedEventArgs(null, false));
|
||||
}
|
||||
}
|
||||
|
||||
void LoadDefaultPresetData()
|
||||
{
|
||||
CurrentPreset = null;
|
||||
if (!File.Exists(DefaultPresetJsonFilePath))
|
||||
{
|
||||
Debug.Console(0, this, "Cannot load default preset file. Saving will not work");
|
||||
return;
|
||||
}
|
||||
using (StreamReader sr = new StreamReader(DefaultPresetJsonFilePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = sr.ReadToEnd();
|
||||
J2SMaster.SetJsonWithoutEvaluating(data);
|
||||
CurrentPreset = new Preset() { Data = data, UserId = CurrentUser.Id };
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, this, "Error reading default preset JSON: \r{0}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="roomTypeId"></param>
|
||||
/// <param name="presetNumber"></param>
|
||||
/// <summary>
|
||||
/// SavePresetForThisUser method
|
||||
/// </summary>
|
||||
public void SavePresetForThisUser(int roomTypeId, int presetNumber)
|
||||
{
|
||||
if (CurrentPreset == null)
|
||||
LoadDefaultPresetData();
|
||||
//return;
|
||||
|
||||
//// A new preset needs to have its numbers set
|
||||
//if (CurrentPreset.IsNewPreset)
|
||||
//{
|
||||
CurrentPreset.UserId = CurrentUser.Id;
|
||||
CurrentPreset.RoomTypeId = roomTypeId;
|
||||
CurrentPreset.PresetNumber = presetNumber;
|
||||
//}
|
||||
J2SMaster.Save(); // Will trigger callback when ready
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// After save operation on JSON master happens, send it to server
|
||||
/// </summary>
|
||||
/// <param name="json"></param>
|
||||
void SaveCallback(string json)
|
||||
{
|
||||
CurrentPreset.Data = json;
|
||||
|
||||
if (!UrlBase.StartsWith("https"))
|
||||
return;
|
||||
var req = new HttpsClientRequest();
|
||||
req.RequestType = Crestron.SimplSharp.Net.Https.RequestType.Post;
|
||||
req.Url = new UrlParser(string.Format("{0}/api/presets/addorchange", UrlBase));
|
||||
req.Header.AddHeader(new HttpsHeader("Content-Type", "application/json"));
|
||||
req.Header.AddHeader(new HttpsHeader("Accept", "application/json"));
|
||||
req.ContentString = JsonConvert.SerializeObject(CurrentPreset);
|
||||
|
||||
var client = new HttpsClient();
|
||||
client.HostVerification = false;
|
||||
client.PeerVerification = false;
|
||||
try
|
||||
{
|
||||
var resp = client.Dispatch(req);
|
||||
|
||||
// 201=created
|
||||
// 204=empty content
|
||||
if (resp.Code == 201)
|
||||
CrestronConsole.PrintLine("Preset added");
|
||||
else if (resp.Code == 204)
|
||||
CrestronConsole.PrintLine("Preset updated");
|
||||
else if (resp.Code == 209)
|
||||
CrestronConsole.PrintLine("Preset already exists. Cannot save as new.");
|
||||
else
|
||||
CrestronConsole.PrintLine("Preset save failed: {0}\r", resp.Code, resp.ContentString);
|
||||
}
|
||||
catch (HttpException e)
|
||||
{
|
||||
|
||||
CrestronConsole.PrintLine("Preset save exception {0}", e.Response.Code);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,259 +0,0 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Crestron.SimplSharp.Net.Http;
|
||||
using Crestron.SimplSharpPro.Diagnostics;
|
||||
|
||||
using PepperDash.Core;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Config;
|
||||
|
||||
public static class ConfigUpdater
|
||||
{
|
||||
public static event EventHandler<ConfigStatusEventArgs> ConfigStatusChanged;
|
||||
|
||||
public static void GetConfigFromServer(string url)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Attempting to get new config from '{0}'", url);
|
||||
|
||||
// HTTP GET
|
||||
var req = new HttpClientRequest();
|
||||
|
||||
try
|
||||
{
|
||||
req.RequestType = RequestType.Get;
|
||||
req.Url.Parse(url);
|
||||
|
||||
new HttpClient().DispatchAsync(req, (r, e) =>
|
||||
{
|
||||
if (e == HTTP_CALLBACK_ERROR.COMPLETED)
|
||||
{
|
||||
if (r.Code == 200)
|
||||
{
|
||||
var newConfig = r.ContentString;
|
||||
|
||||
OnStatusUpdate(eUpdateStatus.ConfigFileReceived);
|
||||
|
||||
ArchiveExistingPortalConfigs();
|
||||
|
||||
CheckForLocalConfigAndDelete();
|
||||
|
||||
WriteConfigToFile(newConfig);
|
||||
|
||||
RestartProgram();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Config Update Process Stopped. Failed to get config file from server: {0}", r.Code);
|
||||
OnStatusUpdate(eUpdateStatus.UpdateFailed);
|
||||
}
|
||||
}
|
||||
else
|
||||
Debug.LogMessage(LogEventLevel.Information, "Request for config from Server Failed: {0}", e);
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Error Getting Config from Server: {0}", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void OnStatusUpdate(eUpdateStatus status)
|
||||
{
|
||||
var handler = ConfigStatusChanged;
|
||||
|
||||
if(handler != null)
|
||||
{
|
||||
handler(typeof(ConfigUpdater), new ConfigStatusEventArgs(status));
|
||||
}
|
||||
}
|
||||
|
||||
static void WriteConfigToFile(string configData)
|
||||
{
|
||||
var filePath = Global.FilePathPrefix+ "configurationFile-updated.json";
|
||||
|
||||
try
|
||||
{
|
||||
var config = JObject.Parse(configData).ToObject<EssentialsConfig>();
|
||||
|
||||
ConfigWriter.WriteFile(filePath, configData);
|
||||
|
||||
OnStatusUpdate(eUpdateStatus.WritingConfigFile);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Error parsing new config: {0}", e);
|
||||
|
||||
OnStatusUpdate(eUpdateStatus.UpdateFailed);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for any existing portal config files and archives them
|
||||
/// </summary>
|
||||
static void ArchiveExistingPortalConfigs()
|
||||
{
|
||||
var filePath = Global.FilePathPrefix + Global.ConfigFileName;
|
||||
|
||||
var configFiles = ConfigReader.GetConfigFiles(filePath);
|
||||
|
||||
if (configFiles != null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Existing config files found. Moving to Archive folder.");
|
||||
|
||||
OnStatusUpdate(eUpdateStatus.ArchivingConfigs);
|
||||
|
||||
MoveFilesToArchiveFolder(configFiles);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "No Existing config files found in '{0}'. Nothing to archive", filePath);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for presence of archive folder and if found deletes contents.
|
||||
/// Moves any config files to the archive folder and adds a .bak suffix
|
||||
/// </summary>
|
||||
/// <param name="files"></param>
|
||||
static void MoveFilesToArchiveFolder(FileInfo[] files)
|
||||
{
|
||||
string archiveDirectoryPath = Global.FilePathPrefix + "archive";
|
||||
|
||||
if (!Directory.Exists(archiveDirectoryPath))
|
||||
{
|
||||
// Directory does not exist, create it
|
||||
Directory.Create(archiveDirectoryPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Directory exists, first clear any contents
|
||||
var archivedConfigFiles = ConfigReader.GetConfigFiles(archiveDirectoryPath + Global.DirectorySeparator + Global.ConfigFileName + ".bak");
|
||||
|
||||
if(archivedConfigFiles != null || archivedConfigFiles.Length > 0)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "{0} Existing files found in archive folder. Deleting.", archivedConfigFiles.Length);
|
||||
|
||||
for (int i = 0; i < archivedConfigFiles.Length; i++ )
|
||||
{
|
||||
var file = archivedConfigFiles[i];
|
||||
Debug.LogMessage(LogEventLevel.Information, "Deleting archived file: '{0}'", file.FullName);
|
||||
file.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Move any files from the program folder to the archive folder
|
||||
foreach (var file in files)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Moving config file '{0}' to archive folder", file.FullName);
|
||||
|
||||
// Moves the file and appends the .bak extension
|
||||
var fileDest = archiveDirectoryPath + "/" + file.Name + ".bak";
|
||||
if(!File.Exists(fileDest))
|
||||
{
|
||||
file.MoveTo(fileDest);
|
||||
}
|
||||
else
|
||||
Debug.LogMessage(LogEventLevel.Information, "Cannot move file to archive folder. Existing file already exists with same name: '{0}'", fileDest);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for LocalConfig folder in file system and deletes if found
|
||||
/// </summary>
|
||||
static void CheckForLocalConfigAndDelete()
|
||||
{
|
||||
var folderPath = Global.FilePathPrefix + ConfigWriter.LocalConfigFolder;
|
||||
|
||||
if (Directory.Exists(folderPath))
|
||||
{
|
||||
OnStatusUpdate(eUpdateStatus.DeletingLocalConfig);
|
||||
Directory.Delete(folderPath);
|
||||
Debug.LogMessage(LogEventLevel.Information, "Local Config Found in '{0}'. Deleting.", folderPath);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Connects to the processor via SSH and restarts the program
|
||||
/// </summary>
|
||||
static void RestartProgram()
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Attempting to Reset Program");
|
||||
|
||||
OnStatusUpdate(eUpdateStatus.RestartingProgram);
|
||||
|
||||
string response = string.Empty;
|
||||
|
||||
CrestronConsole.SendControlSystemCommand(string.Format("progreset -p:{0}", InitialParametersClass.ApplicationNumber), ref response);
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Console Response: {0}", response);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumeration of eUpdateStatus values
|
||||
/// </summary>
|
||||
public enum eUpdateStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// UpdateStarted status
|
||||
/// </summary>
|
||||
UpdateStarted,
|
||||
|
||||
/// <summary>
|
||||
/// ConfigFileReceived status
|
||||
/// </summary>
|
||||
ConfigFileReceived,
|
||||
|
||||
/// <summary>
|
||||
/// ArchivingConfigs status
|
||||
/// </summary>
|
||||
ArchivingConfigs,
|
||||
|
||||
/// <summary>
|
||||
/// DeletingLocalConfig status
|
||||
/// </summary>
|
||||
DeletingLocalConfig,
|
||||
|
||||
/// <summary>
|
||||
/// WritingConfigFile status
|
||||
/// </summary>
|
||||
WritingConfigFile,
|
||||
|
||||
/// <summary>
|
||||
/// RestartingProgram status
|
||||
/// </summary>
|
||||
RestartingProgram,
|
||||
|
||||
/// <summary>
|
||||
/// UpdateSucceeded status
|
||||
/// </summary>
|
||||
UpdateSucceeded,
|
||||
|
||||
/// <summary>
|
||||
/// UpdateFailed status
|
||||
/// </summary>
|
||||
UpdateFailed
|
||||
}
|
||||
|
||||
public class ConfigStatusEventArgs : EventArgs
|
||||
{
|
||||
public eUpdateStatus UpdateStatus { get; private set; }
|
||||
|
||||
public ConfigStatusEventArgs(eUpdateStatus status)
|
||||
{
|
||||
UpdateStatus = status;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
|
||||
namespace PepperDash.Essentials.Core;
|
||||
|
||||
@@ -11,23 +12,22 @@ namespace PepperDash.Essentials.Core;
|
||||
/// </summary>
|
||||
public class DestinationListItem
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the key identifier for the sink device that this destination represents.
|
||||
/// </summary>
|
||||
[JsonProperty("sinkKey")]
|
||||
public string SinkKey { get; set; }
|
||||
|
||||
private EssentialsDevice _sinkDevice;
|
||||
private IRoutingSink _sinkDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the actual device instance for this destination.
|
||||
/// Lazily loads the device from the DeviceManager using the SinkKey.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public EssentialsDevice SinkDevice
|
||||
public IRoutingSink SinkDevice
|
||||
{
|
||||
get { return _sinkDevice ?? (_sinkDevice = DeviceManager.GetDeviceForKey(SinkKey) as EssentialsDevice); }
|
||||
get { return _sinkDevice ?? (_sinkDevice = DeviceManager.GetDeviceForKey(SinkKey) as IRoutingSink); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -43,17 +43,17 @@ public class SourceListItem
|
||||
/// Returns the source Device for this, if it exists in DeviceManager
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public Device SourceDevice
|
||||
public IRoutingSource SourceDevice
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_SourceDevice == null)
|
||||
_SourceDevice = DeviceManager.GetDeviceForKey(SourceKey) as Device;
|
||||
_SourceDevice = DeviceManager.GetDeviceForKey<IRoutingSource>(SourceKey);
|
||||
return _SourceDevice;
|
||||
}
|
||||
}
|
||||
|
||||
private Device _SourceDevice;
|
||||
private IRoutingSource _SourceDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Gets either the source's Name or this AlternateName property, if
|
||||
|
||||
@@ -1236,11 +1236,14 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
uint i = 0;
|
||||
foreach (var kvp in setTopBoxes)
|
||||
{
|
||||
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
|
||||
if (kvp.Value.SourceDevice is Device device)
|
||||
{
|
||||
break;
|
||||
TryAddRouteActionSigs(JoinMap.Display1SetTopBoxSourceStart.AttributeName + " " + (i + 1), JoinMap.Display1SetTopBoxSourceStart.JoinNumber + i, kvp.Key, device);
|
||||
i++;
|
||||
if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1248,11 +1251,14 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
i = 0;
|
||||
foreach (var kvp in discPlayers)
|
||||
{
|
||||
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
|
||||
if (kvp.Value.SourceDevice is Device device)
|
||||
{
|
||||
break;
|
||||
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + (i + 1), JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, device);
|
||||
i++;
|
||||
if (i > JoinMap.Display1DiscPlayerSourceStart.JoinSpan) // We only have five spots
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1260,11 +1266,14 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
i = 0;
|
||||
foreach (var kvp in laptops)
|
||||
{
|
||||
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???
|
||||
if (kvp.Value.SourceDevice is Device device)
|
||||
{
|
||||
break;
|
||||
TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.AttributeName + " " + (i + 1), JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, device);
|
||||
i++;
|
||||
if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots???
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1745,22 +1754,24 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
return;
|
||||
}
|
||||
|
||||
var dev = info.SourceDevice;
|
||||
if (type == ChangeType.WillChange)
|
||||
if (info.SourceDevice is Device dev)
|
||||
{
|
||||
if (_sourceToFeedbackSigs.ContainsKey(dev))
|
||||
if (type == ChangeType.WillChange)
|
||||
{
|
||||
_sourceToFeedbackSigs[dev].BoolValue = false;
|
||||
if (_sourceToFeedbackSigs.ContainsKey(dev))
|
||||
{
|
||||
_sourceToFeedbackSigs[dev].BoolValue = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_sourceToFeedbackSigs.ContainsKey(dev))
|
||||
else
|
||||
{
|
||||
_sourceToFeedbackSigs[dev].BoolValue = true;
|
||||
if (_sourceToFeedbackSigs.ContainsKey(dev))
|
||||
{
|
||||
_sourceToFeedbackSigs[dev].BoolValue = true;
|
||||
}
|
||||
//var name = (room == null ? "" : room.Name);
|
||||
CurrentRoomSourceNameSig.InputSig.StringValue = dev.Name;
|
||||
}
|
||||
//var name = (room == null ? "" : room.Name);
|
||||
CurrentRoomSourceNameSig.InputSig.StringValue = info.SourceDevice.Name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,18 +28,6 @@ public interface IHasDefaultDisplay
|
||||
IRoutingSink DefaultDisplay { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For rooms with multiple displays
|
||||
/// </summary>
|
||||
[Obsolete("This interface is being deprecated in favor of using destination lists for routing to multiple displays.")]
|
||||
public interface IHasMultipleDisplays
|
||||
{
|
||||
/// <summary>
|
||||
/// A dictionary of displays in the room with the key being the type of display (presentation, calling, etc.) and the value being the display device
|
||||
/// </summary>
|
||||
Dictionary<eSourceListItemDestinationTypes, IRoutingSink> Displays { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For rooms with routing
|
||||
/// </summary>
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace PepperDash.Essentials.Core.Routing
|
||||
/// <summary>
|
||||
/// The current sources for the room, keyed by eRoutingSignalType.
|
||||
/// This allows for multiple sources to be tracked, such as audio and video.
|
||||
/// Intended to be implemented on a DestinationListItem to provide access to the current sources for the room in its context.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This interface is used to provide access to the current sources in a room,
|
||||
@@ -17,7 +18,7 @@ namespace PepperDash.Essentials.Core.Routing
|
||||
/// Gets the current sources for the room, keyed by eRoutingSignalType.
|
||||
/// This dictionary contains the current source for each signal type, such as audio, video, and control signals.
|
||||
/// </summary>
|
||||
Dictionary<eRoutingSignalType, SourceListItem> CurrentSources { get; }
|
||||
Dictionary<eRoutingSignalType, IRoutingSource> CurrentSources { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current source keys for the room, keyed by eRoutingSignalType.
|
||||
@@ -28,16 +29,51 @@ namespace PepperDash.Essentials.Core.Routing
|
||||
/// <summary>
|
||||
/// Event raised when the current sources change.
|
||||
/// </summary>
|
||||
event EventHandler CurrentSourcesChanged;
|
||||
event EventHandler<CurrentSourcesChangedEventArgs> CurrentSourcesChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current source for a specific signal type.
|
||||
/// This method updates the current source for the specified signal type and notifies any subscribers of the change.
|
||||
/// </summary>
|
||||
/// <param name="signalType">The signal type to update.</param>
|
||||
/// <param name="sourceListKey">The key for the source list.</param>
|
||||
/// <param name="sourceListItem">The source list item to set as the current source.</param>
|
||||
void SetCurrentSource(eRoutingSignalType signalType, string sourceListKey, SourceListItem sourceListItem);
|
||||
/// <param name="sourceDevice">The source device to set as the current source.</param>
|
||||
void SetCurrentSource(eRoutingSignalType signalType, IRoutingSource sourceDevice);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Event arguments for the CurrentSourcesChanged event, providing details about the signal type and the previous and new sources.
|
||||
/// </summary>
|
||||
public class CurrentSourcesChangedEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the signal type for which the current source has changed.
|
||||
/// </summary>
|
||||
public eRoutingSignalType SignalType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the previous source for the signal type before the change occurred.
|
||||
/// </summary>
|
||||
public IRoutingSource PreviousSource { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the new source for the signal type after the change occurred.
|
||||
/// </summary>
|
||||
public IRoutingSource NewSource { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CurrentSourcesChangedEventArgs class with the specified signal type, previous source, and new source.
|
||||
/// </summary>
|
||||
/// <param name="signalType">The signal type for which the current source has changed.</param>
|
||||
/// <param name="previousSource">The previous source for the signal type before the change occurred.</param>
|
||||
/// <param name="newSource">The new source for the signal type after the change occurred.</param>
|
||||
public CurrentSourcesChangedEventArgs(eRoutingSignalType signalType, IRoutingSource previousSource, IRoutingSource newSource)
|
||||
{
|
||||
SignalType = signalType;
|
||||
PreviousSource = previousSource;
|
||||
NewSource = newSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using PepperDash.Core;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core;
|
||||
@@ -11,6 +12,7 @@ public interface IRoutingOutputs : IKeyed
|
||||
/// <summary>
|
||||
/// Collection of Output Ports
|
||||
/// </summary>
|
||||
[JsonProperty("outputPorts")]
|
||||
RoutingPortCollection<RoutingOutputPort> OutputPorts { get; }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
|
||||
namespace PepperDash.Essentials.Core;
|
||||
@@ -5,7 +6,7 @@ namespace PepperDash.Essentials.Core;
|
||||
/// <summary>
|
||||
/// Defines the contract for IRoutingSink
|
||||
/// </summary>
|
||||
public interface IRoutingSink : IRoutingInputs, IHasCurrentSourceInfoChange
|
||||
public interface IRoutingSink : IRoutingInputs, IKeyName, ICurrentSources
|
||||
{
|
||||
}
|
||||
|
||||
@@ -20,10 +21,4 @@ public interface IRoutingSinkWithInputPort : IRoutingSink
|
||||
RoutingInputPort CurrentInputPort { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interface for routing sinks that have access to the current source information.
|
||||
/// </summary>
|
||||
public interface IRoutingSinkWithCurrentSources : IRoutingSink, ICurrentSources
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
/// <summary>
|
||||
/// Defines the contract for IRoutingSinkWithFeedback
|
||||
/// </summary>
|
||||
public interface IRoutingSinkWithFeedback : IRoutingSinkWithSwitching
|
||||
public interface IRoutingSinkWithFeedback : IRoutingSink
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
namespace PepperDash.Essentials.Core;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Marker interface to identify a device that acts as the origin of a signal path (<see cref="IRoutingOutputs"/>).
|
||||
/// </summary>
|
||||
public interface IRoutingSource : IRoutingOutputs
|
||||
public interface IRoutingSource : IRoutingOutputs, IKeyName
|
||||
{
|
||||
}
|
||||
@@ -9,15 +9,15 @@ namespace PepperDash.Essentials.Core.Routing;
|
||||
/// Manages routing feedback by subscribing to route changes on midpoint and sink devices,
|
||||
/// tracing the route back to the original source, and updating the CurrentSourceInfo on sink devices.
|
||||
/// </summary>
|
||||
public class RoutingFeedbackManager: EssentialsDevice
|
||||
public class RoutingFeedbackManager : EssentialsDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RoutingFeedbackManager"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key for this manager device.</param>
|
||||
/// <param name="name">The name of this manager device.</param>
|
||||
public RoutingFeedbackManager(string key, string name): base(key, name)
|
||||
{
|
||||
public RoutingFeedbackManager(string key, string name) : base(key, name)
|
||||
{
|
||||
AddPreActivationAction(SubscribeForMidpointFeedback);
|
||||
AddPreActivationAction(SubscribeForSinkFeedback);
|
||||
}
|
||||
@@ -41,12 +41,12 @@ public class RoutingFeedbackManager: EssentialsDevice
|
||||
/// </summary>
|
||||
private void SubscribeForSinkFeedback()
|
||||
{
|
||||
var sinkDevices = DeviceManager.AllDevices.OfType<IRoutingSinkWithSwitchingWithInputPort>();
|
||||
var sinkDevices = DeviceManager.AllDevices.OfType<IRoutingSinkWithSwitchingWithInputPort>();
|
||||
|
||||
foreach (var device in sinkDevices)
|
||||
{
|
||||
device.InputChanged += HandleSinkUpdate;
|
||||
}
|
||||
foreach (var device in sinkDevices)
|
||||
{
|
||||
device.InputChanged += HandleSinkUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -59,7 +59,7 @@ public class RoutingFeedbackManager: EssentialsDevice
|
||||
{
|
||||
try
|
||||
{
|
||||
var devices = DeviceManager.AllDevices.OfType<IRoutingSinkWithSwitchingWithInputPort>();
|
||||
var devices = DeviceManager.AllDevices.OfType<IRoutingSinkWithInputPort>();
|
||||
|
||||
foreach (var device in devices)
|
||||
{
|
||||
@@ -96,13 +96,13 @@ public class RoutingFeedbackManager: EssentialsDevice
|
||||
/// </summary>
|
||||
/// <param name="destination">The destination sink device to update.</param>
|
||||
/// <param name="inputPort">The currently selected input port on the destination device.</param>
|
||||
private void UpdateDestination(IRoutingSinkWithSwitching destination, RoutingInputPort inputPort)
|
||||
{
|
||||
private void UpdateDestination(IRoutingSink destination, RoutingInputPort inputPort)
|
||||
{
|
||||
// Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Updating destination {destination} with inputPort {inputPort}", this,destination?.Key, inputPort?.Key);
|
||||
|
||||
if(inputPort == null)
|
||||
if (inputPort == null)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Warning, "Destination {destination} has not reported an input port yet", this,destination.Key);
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Warning, "Destination {destination} has not reported an input port yet", this, destination.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -116,19 +116,10 @@ public class RoutingFeedbackManager: EssentialsDevice
|
||||
if (firstTieLine == null)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "No tieline found for inputPort {inputPort}. Clearing current source", this, inputPort);
|
||||
|
||||
var tempSourceListItem = new SourceListItem
|
||||
{
|
||||
SourceKey = "$transient",
|
||||
Name = inputPort.Key,
|
||||
};
|
||||
|
||||
|
||||
destination.CurrentSourceInfo = tempSourceListItem; ;
|
||||
destination.CurrentSourceInfoKey = "$transient";
|
||||
return;
|
||||
}
|
||||
} catch (Exception ex)
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Error getting first tieline: {Exception}", this, ex);
|
||||
return;
|
||||
@@ -136,6 +127,7 @@ public class RoutingFeedbackManager: EssentialsDevice
|
||||
|
||||
// Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Getting source for first TieLine {tieLine}", this, firstTieLine);
|
||||
|
||||
|
||||
TieLine sourceTieLine;
|
||||
try
|
||||
{
|
||||
@@ -145,91 +137,34 @@ public class RoutingFeedbackManager: EssentialsDevice
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "No route found to source for inputPort {inputPort}. Clearing current source", this, inputPort);
|
||||
|
||||
var tempSourceListItem = new SourceListItem
|
||||
{
|
||||
SourceKey = "$transient",
|
||||
Name = "None",
|
||||
};
|
||||
|
||||
destination.CurrentSourceInfo = tempSourceListItem;
|
||||
destination.CurrentSourceInfoKey = string.Empty;
|
||||
destination.SetCurrentSource(sourceTieLine.Type, null);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
} catch(Exception ex)
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Error getting sourceTieLine: {Exception}", this, ex);
|
||||
return;
|
||||
}
|
||||
|
||||
// Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Found root TieLine {tieLine}", this, sourceTieLine);
|
||||
|
||||
// Does not handle combinable scenarios or other scenarios where a display might be part of multiple rooms yet.
|
||||
var room = DeviceManager.AllDevices.OfType<IEssentialsRoom>().FirstOrDefault((r) => {
|
||||
if(r is IHasMultipleDisplays roomMultipleDisplays)
|
||||
{
|
||||
return roomMultipleDisplays.Displays.Any(d => d.Value.Key == destination.Key);
|
||||
}
|
||||
|
||||
if(r is IHasDefaultDisplay roomDefaultDisplay)
|
||||
{
|
||||
return roomDefaultDisplay.DefaultDisplay.Key == destination.Key;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if(room == null)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Warning, "No room found for display {destination}", this, destination.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
// Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Found room {room} for destination {destination}", this, room.Key, destination.Key);
|
||||
|
||||
var sourceList = ConfigReader.ConfigObject.GetSourceListForKey(room.SourceListKey);
|
||||
|
||||
if (sourceList == null)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Warning, "No source list found for source list key {key}. Unable to find source for tieLine {sourceTieLine}", this, room.SourceListKey, sourceTieLine);
|
||||
return;
|
||||
}
|
||||
|
||||
// Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Found sourceList for room {room}", this, room.Key);
|
||||
|
||||
var sourceListItem = sourceList.FirstOrDefault(sli => {
|
||||
//// Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose,
|
||||
// "SourceListItem {sourceListItem}:{sourceKey} tieLine sourceport device key {sourcePortDeviceKey}",
|
||||
// this,
|
||||
// sli.Key,
|
||||
// sli.Value.SourceKey,
|
||||
// sourceTieLine.SourcePort.ParentDevice.Key);
|
||||
|
||||
return sli.Value.SourceKey.Equals(sourceTieLine.SourcePort.ParentDevice.Key,StringComparison.InvariantCultureIgnoreCase);
|
||||
});
|
||||
|
||||
var source = sourceListItem.Value;
|
||||
var sourceKey = sourceListItem.Key;
|
||||
|
||||
if (source == null)
|
||||
if (sourceTieLine.SourcePort.ParentDevice == null)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "No source found for device {key}. Creating transient source for {destination}", this, sourceTieLine.SourcePort.ParentDevice.Key, destination);
|
||||
|
||||
var tempSourceListItem = new SourceListItem
|
||||
{
|
||||
SourceKey = "$transient",
|
||||
Name = sourceTieLine.SourcePort.Key,
|
||||
};
|
||||
destination.SetCurrentSource(sourceTieLine.Type, null);
|
||||
|
||||
destination.CurrentSourceInfoKey = "$transient";
|
||||
destination.CurrentSourceInfo = tempSourceListItem;
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Got Source {@source} with key {sourceKey}", this, source, sourceKey);
|
||||
|
||||
destination.CurrentSourceInfoKey = sourceKey;
|
||||
destination.CurrentSourceInfo = source;
|
||||
|
||||
if (sourceTieLine.SourcePort.ParentDevice is IRoutingSource sourceDevice)
|
||||
{
|
||||
destination.SetCurrentSource(sourceTieLine.Type, sourceDevice);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -249,13 +184,14 @@ public class RoutingFeedbackManager: EssentialsDevice
|
||||
{
|
||||
// Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "TieLine Source device {sourceDevice} is midpoint", this, midpoint);
|
||||
|
||||
if(midpoint.CurrentRoutes == null || midpoint.CurrentRoutes.Count == 0)
|
||||
if (midpoint.CurrentRoutes == null || midpoint.CurrentRoutes.Count == 0)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "Midpoint {midpointKey} has no routes",this, midpoint.Key);
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "Midpoint {midpointKey} has no routes", this, midpoint.Key);
|
||||
return null;
|
||||
}
|
||||
|
||||
var currentRoute = midpoint.CurrentRoutes.FirstOrDefault(route => {
|
||||
var currentRoute = midpoint.CurrentRoutes.FirstOrDefault(route =>
|
||||
{
|
||||
//Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Checking {route} against {tieLine}", this, route, tieLine);
|
||||
|
||||
return route.OutputPort != null && route.InputPort != null && route.OutputPort?.Key == tieLine.SourcePort.Key && route.OutputPort?.ParentDevice.Key == tieLine.SourcePort.ParentDevice.Key;
|
||||
@@ -269,9 +205,11 @@ public class RoutingFeedbackManager: EssentialsDevice
|
||||
|
||||
//Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Found currentRoute {currentRoute} through {midpoint}", this, currentRoute, midpoint);
|
||||
|
||||
nextTieLine = TieLineCollection.Default.FirstOrDefault(tl => {
|
||||
nextTieLine = TieLineCollection.Default.FirstOrDefault(tl =>
|
||||
{
|
||||
//Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Checking {route} against {tieLine}", tl.DestinationPort.Key, currentRoute.InputPort.Key);
|
||||
return tl.DestinationPort.Key == currentRoute.InputPort.Key && tl.DestinationPort.ParentDevice.Key == currentRoute.InputPort.ParentDevice.Key; });
|
||||
return tl.DestinationPort.Key == currentRoute.InputPort.Key && tl.DestinationPort.ParentDevice.Key == currentRoute.InputPort.ParentDevice.Key;
|
||||
});
|
||||
|
||||
if (nextTieLine != null)
|
||||
{
|
||||
@@ -292,13 +230,14 @@ public class RoutingFeedbackManager: EssentialsDevice
|
||||
return tieLine;
|
||||
}
|
||||
|
||||
nextTieLine = TieLineCollection.Default.FirstOrDefault(tl => tl.DestinationPort.Key == tieLine.SourcePort.Key && tl.DestinationPort.ParentDevice.Key == tieLine.SourcePort.ParentDevice.Key );
|
||||
nextTieLine = TieLineCollection.Default.FirstOrDefault(tl => tl.DestinationPort.Key == tieLine.SourcePort.Key && tl.DestinationPort.ParentDevice.Key == tieLine.SourcePort.ParentDevice.Key);
|
||||
|
||||
if (nextTieLine != null)
|
||||
{
|
||||
return GetRootTieLine(nextTieLine);
|
||||
}
|
||||
} catch (Exception ex)
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Error walking tieLines: {Exception}", this, ex);
|
||||
return null;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common;
|
||||
@@ -13,33 +14,19 @@ namespace PepperDash.Essentials.Devices.Common;
|
||||
/// </summary>
|
||||
public class GenericAudioOut : EssentialsDevice, IRoutingSink
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public RoutingInputPort CurrentInputPort => AnyAudioIn;
|
||||
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CurrentSourceInfo;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
/// <inheritdoc/>
|
||||
public Dictionary<eRoutingSignalType, IRoutingSource> CurrentSources { get; private set; }
|
||||
|
||||
var handler = CurrentSourceChange;
|
||||
/// <inheritdoc/>
|
||||
public Dictionary<eRoutingSignalType, string> CurrentSourceKeys { get; private set; }
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
/// <inheritdoc />
|
||||
public event System.EventHandler<CurrentSourcesChangedEventArgs> CurrentSourcesChanged;
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the AnyAudioIn
|
||||
@@ -56,6 +43,66 @@ public class GenericAudioOut : EssentialsDevice, IRoutingSink
|
||||
{
|
||||
AnyAudioIn = new RoutingInputPort(RoutingPortNames.AnyAudioIn, eRoutingSignalType.Audio,
|
||||
eRoutingPortConnectionType.LineAudio, null, this);
|
||||
|
||||
CurrentSources = new Dictionary<eRoutingSignalType, IRoutingSource>
|
||||
{
|
||||
{ eRoutingSignalType.Audio, null },
|
||||
};
|
||||
|
||||
CurrentSourceKeys = new Dictionary<eRoutingSignalType, string>
|
||||
{
|
||||
{ eRoutingSignalType.Audio, string.Empty },
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void SetCurrentSource(eRoutingSignalType signalType, IRoutingSource sourceDevice)
|
||||
{
|
||||
foreach (eRoutingSignalType type in System.Enum.GetValues(typeof(eRoutingSignalType)))
|
||||
{
|
||||
var flagValue = System.Convert.ToInt32(type);
|
||||
// Skip if flagValue is 0 or not a power of two (i.e., not a single-bit flag).
|
||||
// (flagValue & (flagValue - 1)) != 0 checks if more than one bit is set.
|
||||
if (flagValue == 0 || (flagValue & (flagValue - 1)) != 0)
|
||||
{
|
||||
this.LogDebug("Skipping {type}", type);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.LogDebug("setting {type}", type);
|
||||
|
||||
var previousSource = CurrentSources[type];
|
||||
|
||||
if (signalType.HasFlag(type))
|
||||
{
|
||||
UpdateCurrentSources(type, previousSource, sourceDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateCurrentSources(eRoutingSignalType signalType, IRoutingSource previousSource, IRoutingSource sourceDevice)
|
||||
{
|
||||
if (CurrentSources.ContainsKey(signalType))
|
||||
{
|
||||
CurrentSources[signalType] = sourceDevice;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSources.Add(signalType, sourceDevice);
|
||||
}
|
||||
|
||||
// Update the current source key for the specified signal type
|
||||
if (CurrentSourceKeys.ContainsKey(signalType))
|
||||
{
|
||||
CurrentSourceKeys[signalType] = sourceDevice.Key;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSourceKeys.Add(signalType, sourceDevice.Key);
|
||||
}
|
||||
|
||||
// Raise the CurrentSourcesChanged event
|
||||
CurrentSourcesChanged?.Invoke(this, new CurrentSourcesChangedEventArgs(signalType, previousSource, sourceDevice));
|
||||
}
|
||||
|
||||
#region IRoutingInputs Members
|
||||
@@ -116,13 +163,20 @@ public class GenericAudioOutWithVolume : GenericAudioOut, IHasVolumeDevice
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory for creating GenericAudioOutWithVolume devices
|
||||
/// </summary>
|
||||
public class GenericAudioOutWithVolumeFactory : EssentialsDeviceFactory<GenericAudioOutWithVolume>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor for GenericAudioOutWithVolumeFactory
|
||||
/// </summary>
|
||||
public GenericAudioOutWithVolumeFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "genericaudiooutwithvolume" };
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new GenericAudioOutWithVolumeFactory Device");
|
||||
|
||||
@@ -48,48 +48,20 @@ public abstract class DisplayBase : EssentialsDevice, IDisplay, ICurrentSources,
|
||||
/// </summary>
|
||||
public event InputChangedEventHandler InputChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Event that is raised when the current source information changes.
|
||||
/// </summary>
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CurrentSourceInfoKey
|
||||
/// </summary>
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current source information for the display.
|
||||
/// </summary>
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CurrentSourceInfo;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSourceChange;
|
||||
|
||||
handler?.Invoke(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
|
||||
handler?.Invoke(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Dictionary<eRoutingSignalType, SourceListItem> CurrentSources { get; private set; }
|
||||
public Dictionary<eRoutingSignalType, IRoutingSource> CurrentSources { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Dictionary<eRoutingSignalType, string> CurrentSourceKeys { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler CurrentSourcesChanged;
|
||||
public event EventHandler<CurrentSourcesChangedEventArgs> CurrentSourcesChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets feedback indicating whether the display is currently cooling down after being powered off.
|
||||
@@ -163,7 +135,7 @@ public abstract class DisplayBase : EssentialsDevice, IDisplay, ICurrentSources,
|
||||
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
|
||||
CurrentSources = new Dictionary<eRoutingSignalType, SourceListItem>
|
||||
CurrentSources = new Dictionary<eRoutingSignalType, IRoutingSource>
|
||||
{
|
||||
{ eRoutingSignalType.Audio, null },
|
||||
{ eRoutingSignalType.Video, null },
|
||||
@@ -388,7 +360,7 @@ public abstract class DisplayBase : EssentialsDevice, IDisplay, ICurrentSources,
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void SetCurrentSource(eRoutingSignalType signalType, string sourceListKey, SourceListItem sourceListItem)
|
||||
public virtual void SetCurrentSource(eRoutingSignalType signalType, IRoutingSource sourceDevice)
|
||||
{
|
||||
foreach (eRoutingSignalType type in Enum.GetValues(typeof(eRoutingSignalType)))
|
||||
{
|
||||
@@ -403,35 +375,38 @@ public abstract class DisplayBase : EssentialsDevice, IDisplay, ICurrentSources,
|
||||
|
||||
this.LogDebug("setting {type}", type);
|
||||
|
||||
var previousSource = CurrentSources[type];
|
||||
|
||||
if (signalType.HasFlag(type))
|
||||
{
|
||||
UpdateCurrentSources(type, sourceListKey, sourceListItem);
|
||||
UpdateCurrentSources(type, previousSource, sourceDevice);
|
||||
}
|
||||
}
|
||||
// Raise the CurrentSourcesChanged event
|
||||
CurrentSourcesChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void UpdateCurrentSources(eRoutingSignalType signalType, string sourceListKey, SourceListItem sourceListItem)
|
||||
private void UpdateCurrentSources(eRoutingSignalType signalType, IRoutingSource previousSource, IRoutingSource sourceDevice)
|
||||
{
|
||||
if (CurrentSources.ContainsKey(signalType))
|
||||
{
|
||||
CurrentSources[signalType] = sourceListItem;
|
||||
CurrentSources[signalType] = sourceDevice;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSources.Add(signalType, sourceListItem);
|
||||
CurrentSources.Add(signalType, sourceDevice);
|
||||
}
|
||||
|
||||
// Update the current source key for the specified signal type
|
||||
if (CurrentSourceKeys.ContainsKey(signalType))
|
||||
{
|
||||
CurrentSourceKeys[signalType] = sourceListKey;
|
||||
CurrentSourceKeys[signalType] = sourceDevice.Key;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSourceKeys.Add(signalType, sourceListKey);
|
||||
CurrentSourceKeys.Add(signalType, sourceDevice.Key);
|
||||
}
|
||||
|
||||
// Raise the CurrentSourcesChanged event
|
||||
CurrentSourcesChanged?.Invoke(this, new CurrentSourcesChangedEventArgs(signalType, previousSource, sourceDevice));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,14 +14,14 @@ namespace PepperDash.Essentials.Devices.Common.Generic;
|
||||
/// </summary>
|
||||
public class GenericSink : EssentialsDevice, IRoutingSinkWithSwitchingWithInputPort, ICurrentSources
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public Dictionary<eRoutingSignalType, SourceListItem> CurrentSources { get; private set; }
|
||||
/// <inheritdoc/>
|
||||
public Dictionary<eRoutingSignalType, IRoutingSource> CurrentSources { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Dictionary<eRoutingSignalType, string> CurrentSourceKeys { get; private set; }
|
||||
/// <inheritdoc/>
|
||||
public Dictionary<eRoutingSignalType, string> CurrentSourceKeys { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler CurrentSourcesChanged;
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<CurrentSourcesChangedEventArgs> CurrentSourcesChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the GenericSink class
|
||||
@@ -36,7 +36,7 @@ public class GenericSink : EssentialsDevice, IRoutingSinkWithSwitchingWithInputP
|
||||
|
||||
InputPorts.Add(inputPort);
|
||||
|
||||
CurrentSources = new Dictionary<eRoutingSignalType, SourceListItem>
|
||||
CurrentSources = new Dictionary<eRoutingSignalType, IRoutingSource>
|
||||
{
|
||||
{ eRoutingSignalType.Audio, null },
|
||||
{ eRoutingSignalType.Video, null },
|
||||
@@ -49,36 +49,55 @@ public class GenericSink : EssentialsDevice, IRoutingSinkWithSwitchingWithInputP
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetCurrentSource(eRoutingSignalType signalType, string sourceListKey, SourceListItem sourceListItem)
|
||||
{
|
||||
foreach (eRoutingSignalType type in Enum.GetValues(typeof(eRoutingSignalType)))
|
||||
{
|
||||
var flagValue = Convert.ToInt32(type);
|
||||
// Skip if flagValue is 0 or not a power of two (i.e., not a single-bit flag).
|
||||
// (flagValue & (flagValue - 1)) != 0 checks if more than one bit is set.
|
||||
if (flagValue == 0 || (flagValue & (flagValue - 1)) != 0)
|
||||
{
|
||||
this.LogDebug("Skipping {type}", type);
|
||||
continue;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public virtual void SetCurrentSource(eRoutingSignalType signalType, IRoutingSource sourceDevice)
|
||||
{
|
||||
foreach (eRoutingSignalType type in Enum.GetValues(typeof(eRoutingSignalType)))
|
||||
{
|
||||
var flagValue = Convert.ToInt32(type);
|
||||
// Skip if flagValue is 0 or not a power of two (i.e., not a single-bit flag).
|
||||
// (flagValue & (flagValue - 1)) != 0 checks if more than one bit is set.
|
||||
if (flagValue == 0 || (flagValue & (flagValue - 1)) != 0)
|
||||
{
|
||||
this.LogDebug("Skipping {type}", type);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.LogDebug("setting {type}", type);
|
||||
this.LogDebug("setting {type}", type);
|
||||
|
||||
if (signalType.HasFlag(type))
|
||||
{
|
||||
UpdateCurrentSources(type, sourceListKey, sourceListItem);
|
||||
}
|
||||
}
|
||||
// Raise the CurrentSourcesChanged event
|
||||
CurrentSourcesChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
var previousSource = CurrentSources[type];
|
||||
|
||||
private void UpdateCurrentSources(eRoutingSignalType signalType, string sourceListKey, SourceListItem sourceListItem)
|
||||
{
|
||||
CurrentSources[signalType] = sourceListItem;
|
||||
CurrentSourceKeys[signalType] = sourceListKey;
|
||||
}
|
||||
if (signalType.HasFlag(type))
|
||||
{
|
||||
UpdateCurrentSources(type, previousSource, sourceDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateCurrentSources(eRoutingSignalType signalType, IRoutingSource previousSource, IRoutingSource sourceDevice)
|
||||
{
|
||||
if (CurrentSources.ContainsKey(signalType))
|
||||
{
|
||||
CurrentSources[signalType] = sourceDevice;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSources.Add(signalType, sourceDevice);
|
||||
}
|
||||
|
||||
// Update the current source key for the specified signal type
|
||||
if (CurrentSourceKeys.ContainsKey(signalType))
|
||||
{
|
||||
CurrentSourceKeys[signalType] = sourceDevice.Key;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSourceKeys.Add(signalType, sourceDevice.Key);
|
||||
}
|
||||
|
||||
// Raise the CurrentSourcesChanged event
|
||||
CurrentSourcesChanged?.Invoke(this, new CurrentSourcesChangedEventArgs(signalType, previousSource, sourceDevice));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the InputPorts
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using PepperDash.Essentials.Devices.Common.Sources;
|
||||
using Serilog.Events;
|
||||
|
||||
@@ -22,10 +25,19 @@ public class BlueJeansPc : InRoomPc, IRunRouteAction, IRoutingSink
|
||||
|
||||
/// <summary>
|
||||
/// The currently active input port, which for this device is always AnyVideoIn
|
||||
/// This is used by the routing system to determine where to route video sources when this device is a destination
|
||||
/// This is used by the routing system to determine where to route video sources when this device is a destination
|
||||
/// </summary>
|
||||
public RoutingInputPort CurrentInputPort => AnyVideoIn;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Dictionary<eRoutingSignalType, IRoutingSource> CurrentSources { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Dictionary<eRoutingSignalType, string> CurrentSourceKeys { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<CurrentSourcesChangedEventArgs> CurrentSourcesChanged;
|
||||
|
||||
#region IRoutingInputs Members
|
||||
|
||||
/// <summary>
|
||||
@@ -47,15 +59,77 @@ public class BlueJeansPc : InRoomPc, IRunRouteAction, IRoutingSink
|
||||
{
|
||||
(AnyVideoIn = new RoutingInputPort(RoutingPortNames.AnyVideoIn, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.None, 0, this))
|
||||
};
|
||||
|
||||
CurrentSources = new Dictionary<eRoutingSignalType, IRoutingSource>
|
||||
{
|
||||
{ eRoutingSignalType.Audio, null },
|
||||
{ eRoutingSignalType.Video, null },
|
||||
};
|
||||
|
||||
CurrentSourceKeys = new Dictionary<eRoutingSignalType, string>
|
||||
{
|
||||
{ eRoutingSignalType.Audio, string.Empty },
|
||||
{ eRoutingSignalType.Video, string.Empty },
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void SetCurrentSource(eRoutingSignalType signalType, IRoutingSource sourceDevice)
|
||||
{
|
||||
foreach (eRoutingSignalType type in Enum.GetValues(typeof(eRoutingSignalType)))
|
||||
{
|
||||
var flagValue = Convert.ToInt32(type);
|
||||
// Skip if flagValue is 0 or not a power of two (i.e., not a single-bit flag).
|
||||
// (flagValue & (flagValue - 1)) != 0 checks if more than one bit is set.
|
||||
if (flagValue == 0 || (flagValue & (flagValue - 1)) != 0)
|
||||
{
|
||||
this.LogDebug("Skipping {type}", type);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.LogDebug("setting {type}", type);
|
||||
|
||||
var previousSource = CurrentSources[type];
|
||||
|
||||
if (signalType.HasFlag(type))
|
||||
{
|
||||
UpdateCurrentSources(type, previousSource, sourceDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateCurrentSources(eRoutingSignalType signalType, IRoutingSource previousSource, IRoutingSource sourceDevice)
|
||||
{
|
||||
if (CurrentSources.ContainsKey(signalType))
|
||||
{
|
||||
CurrentSources[signalType] = sourceDevice;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSources.Add(signalType, sourceDevice);
|
||||
}
|
||||
|
||||
// Update the current source key for the specified signal type
|
||||
if (CurrentSourceKeys.ContainsKey(signalType))
|
||||
{
|
||||
CurrentSourceKeys[signalType] = sourceDevice.Key;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSourceKeys.Add(signalType, sourceDevice.Key);
|
||||
}
|
||||
|
||||
// Raise the CurrentSourcesChanged event
|
||||
CurrentSourcesChanged?.Invoke(this, new CurrentSourcesChangedEventArgs(signalType, previousSource, sourceDevice));
|
||||
}
|
||||
|
||||
#region IRunRouteAction Members
|
||||
|
||||
/// <summary>
|
||||
/// Runs a route action for the specified route key and source list key. Optionally, a callback can be provided to be executed upon successful completion.
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
/// <param name="sourceListKey"></param>
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
/// <param name="sourceListKey"></param>
|
||||
public void RunRouteAction(string routeKey, string sourceListKey)
|
||||
{
|
||||
RunRouteAction(routeKey, sourceListKey, null);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.SoftCodec;
|
||||
@@ -27,6 +30,15 @@ public class GenericSoftCodec : EssentialsDevice, IRoutingSource, IRoutingSinkWi
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Dictionary<eRoutingSignalType, IRoutingSource> CurrentSources { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Dictionary<eRoutingSignalType, string> CurrentSourceKeys { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public event System.EventHandler<CurrentSourcesChangedEventArgs> CurrentSourcesChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GenericSoftCodec"/> class
|
||||
/// </summary>
|
||||
@@ -49,6 +61,18 @@ public class GenericSoftCodec : EssentialsDevice, IRoutingSource, IRoutingSinkWi
|
||||
InputPorts.Add(inputPort);
|
||||
}
|
||||
|
||||
CurrentSources = new Dictionary<eRoutingSignalType, IRoutingSource>
|
||||
{
|
||||
{ eRoutingSignalType.Audio, null },
|
||||
{ eRoutingSignalType.Video, null },
|
||||
};
|
||||
|
||||
CurrentSourceKeys = new Dictionary<eRoutingSignalType, string>
|
||||
{
|
||||
{ eRoutingSignalType.Audio, string.Empty },
|
||||
{ eRoutingSignalType.Video, string.Empty },
|
||||
};
|
||||
|
||||
if (!props.HasCameraInputs)
|
||||
{
|
||||
return;
|
||||
@@ -62,6 +86,56 @@ public class GenericSoftCodec : EssentialsDevice, IRoutingSource, IRoutingSinkWi
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void SetCurrentSource(eRoutingSignalType signalType, IRoutingSource sourceDevice)
|
||||
{
|
||||
foreach (eRoutingSignalType type in System.Enum.GetValues(typeof(eRoutingSignalType)))
|
||||
{
|
||||
var flagValue = System.Convert.ToInt32(type);
|
||||
// Skip if flagValue is 0 or not a power of two (i.e., not a single-bit flag).
|
||||
// (flagValue & (flagValue - 1)) != 0 checks if more than one bit is set.
|
||||
if (flagValue == 0 || (flagValue & (flagValue - 1)) != 0)
|
||||
{
|
||||
this.LogDebug("Skipping {type}", type);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.LogDebug("setting {type}", type);
|
||||
|
||||
var previousSource = CurrentSources[type];
|
||||
|
||||
if (signalType.HasFlag(type))
|
||||
{
|
||||
UpdateCurrentSources(type, previousSource, sourceDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateCurrentSources(eRoutingSignalType signalType, IRoutingSource previousSource, IRoutingSource sourceDevice)
|
||||
{
|
||||
if (CurrentSources.ContainsKey(signalType))
|
||||
{
|
||||
CurrentSources[signalType] = sourceDevice;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSources.Add(signalType, sourceDevice);
|
||||
}
|
||||
|
||||
// Update the current source key for the specified signal type
|
||||
if (CurrentSourceKeys.ContainsKey(signalType))
|
||||
{
|
||||
CurrentSourceKeys[signalType] = sourceDevice.Key;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSourceKeys.Add(signalType, sourceDevice.Key);
|
||||
}
|
||||
|
||||
// Raise the CurrentSourcesChanged event
|
||||
CurrentSourcesChanged?.Invoke(this, new CurrentSourcesChangedEventArgs(signalType, previousSource, sourceDevice));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the InputPorts
|
||||
/// </summary>
|
||||
|
||||
@@ -69,7 +69,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// </summary>
|
||||
public class CurrentSourcesStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CurrentSourceKey
|
||||
/// </summary>
|
||||
@@ -81,6 +80,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// Gets or sets the CurrentSource
|
||||
/// </summary>
|
||||
[JsonProperty("currentSources")]
|
||||
public Dictionary<eRoutingSignalType, SourceListItem> CurrentSources { get; set; }
|
||||
public Dictionary<eRoutingSignalType, IRoutingSource> CurrentSources { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
|
||||
@@ -17,29 +15,22 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// </summary>
|
||||
public IRunRouteAction RoutingDevice { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the RunRouteActionMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="routingDevice">The routing device.</param>
|
||||
/// <param name="messagePath">The message path.</param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public RunRouteActionMessenger(string key, IRunRouteAction routingDevice, string messagePath)
|
||||
: base(key, messagePath, routingDevice as IKeyName)
|
||||
{
|
||||
RoutingDevice = routingDevice ?? throw new ArgumentNullException("routingDevice");
|
||||
|
||||
|
||||
if (RoutingDevice is IRoutingSink routingSink)
|
||||
{
|
||||
routingSink.CurrentSourceChange += RoutingSink_CurrentSourceChange;
|
||||
}
|
||||
}
|
||||
|
||||
private void RoutingSink_CurrentSourceChange(SourceListItem info, ChangeType type)
|
||||
{
|
||||
SendRoutingFullMessageObject();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/fullStatus", (id, content) => SendRoutingFullMessageObject(id));
|
||||
|
||||
AddAction("/routingStatus", (id, content) => SendRoutingFullMessageObject(id));
|
||||
|
||||
AddAction("/source", (id, content) =>
|
||||
{
|
||||
var c = content.ToObject<SourceSelectMessageContent>();
|
||||
@@ -55,41 +46,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
RoutingDevice.RunRouteAction(c.SourceListItemKey, sourceListKey);
|
||||
});
|
||||
|
||||
if (RoutingDevice is IRoutingSink sinkDevice)
|
||||
{
|
||||
sinkDevice.CurrentSourceChange += (o, a) => SendRoutingFullMessageObject();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to update full status of the routing device
|
||||
/// </summary>
|
||||
private void SendRoutingFullMessageObject(string id = null)
|
||||
{
|
||||
if (RoutingDevice is IRoutingSink sinkDevice)
|
||||
{
|
||||
var sourceKey = sinkDevice.CurrentSourceInfoKey;
|
||||
|
||||
if (string.IsNullOrEmpty(sourceKey))
|
||||
sourceKey = "none";
|
||||
|
||||
PostStatusMessage(new RoutingStateMessage
|
||||
{
|
||||
SelectedSourceKey = sourceKey
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a RoutingStateMessage
|
||||
/// </summary>
|
||||
public class RoutingStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the SelectedSourceKey
|
||||
/// </summary>
|
||||
[JsonProperty("selectedSourceKey")]
|
||||
public string SelectedSourceKey { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -719,29 +719,6 @@ namespace PepperDash.Essentials.RoomBridges
|
||||
}
|
||||
}
|
||||
|
||||
if (room is IHasDefaultDisplay defDisplayRoom)
|
||||
{
|
||||
this.LogVerbose("Getting default display config");
|
||||
configuration.DefaultDisplayKey = defDisplayRoom.DefaultDisplay.Key;
|
||||
configuration.Destinations.Add(eSourceListItemDestinationTypes.defaultDisplay, defDisplayRoom.DefaultDisplay.Key);
|
||||
}
|
||||
|
||||
if (room is IHasMultipleDisplays multiDisplayRoom)
|
||||
{
|
||||
this.LogVerbose("Getting multiple display config");
|
||||
|
||||
if (multiDisplayRoom.Displays == null)
|
||||
{
|
||||
this.LogVerbose("Displays collection is null");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.LogVerbose("Displays collection exists");
|
||||
|
||||
configuration.Destinations = multiDisplayRoom.Displays.ToDictionary(kv => kv.Key, kv => kv.Value.Key);
|
||||
}
|
||||
}
|
||||
|
||||
if (room is IHasAccessoryDevices accRoom)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "Getting accessory devices config", this);
|
||||
@@ -1015,13 +992,6 @@ namespace PepperDash.Essentials.RoomBridges
|
||||
[JsonProperty("defaultDisplayKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string DefaultDisplayKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the destinations dictionary keyed by destination type
|
||||
/// </summary>
|
||||
[JsonProperty("destinations", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Dictionary<eSourceListItemDestinationTypes, string> Destinations { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the EnvironmentalDevices
|
||||
/// </summary>
|
||||
@@ -1106,7 +1076,6 @@ namespace PepperDash.Essentials.RoomBridges
|
||||
/// </summary>
|
||||
public RoomConfiguration()
|
||||
{
|
||||
Destinations = new Dictionary<eSourceListItemDestinationTypes, string>();
|
||||
EnvironmentalDevices = new List<EnvironmentalDeviceConfiguration>();
|
||||
SourceList = new Dictionary<string, SourceListItem>();
|
||||
TouchpanelKeys = new List<string>();
|
||||
|
||||
@@ -1,881 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||
<Class Name="PepperDash.Essentials.EssentialsRoomVolumesConfig" Collapsed="true">
|
||||
<Position X="19.25" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAQAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAIAgA=</HashCode>
|
||||
<FileName>Audio\EssentialsVolumeLevelConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.EssentialsVolumeLevelConfig" Collapsed="true">
|
||||
<Position X="22.75" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAEAAAAAAAAAAAAAAAAIAAAAgBAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Audio\EssentialsVolumeLevelConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.ConfigReader" Collapsed="true">
|
||||
<Position X="26.25" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAIAAAAAAAABAAAACAAIAAAAQAAAAAAAAAAEAA=</HashCode>
|
||||
<FileName>Config\ConfigReader.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.DeviceFactory" Collapsed="true">
|
||||
<Position X="29.75" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Config\DeviceFactory.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.EssentialsConfig" Collapsed="true">
|
||||
<Position X="33.25" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAEAAAAAQAIAAAAAAAACAAAAAAAAAAAAAAEAAAA=</HashCode>
|
||||
<FileName>Config\EssentialsConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.SystemTemplateConfigs" Collapsed="true">
|
||||
<Position X="33.25" Y="7.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Config\EssentialsConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.ConfigTieLine" Collapsed="true">
|
||||
<Position X="31.5" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAgEAAAAAAEAAAAAAAAAAAAAAAAAAAAAEAIAIA=</HashCode>
|
||||
<FileName>Configuration ORIGINAL\ConfigTieLine.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Configuration" Collapsed="true">
|
||||
<Position X="33.25" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AEAAAAAAAAAAgQAAAAAAgAAAAAAAAAAAAAAgEDAADAQ=</HashCode>
|
||||
<FileName>Configuration ORIGINAL\Configuration.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.ConfigSourceList" Collapsed="true">
|
||||
<Position X="29.75" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAQAAAAAAAQAAACAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Configuration ORIGINAL\Configuration.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.ConfigSourceItem" Collapsed="true">
|
||||
<Position X="28" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAgAAAAAAAEAAAAAAAAAAAAAAAAAgAAAAAAA=</HashCode>
|
||||
<FileName>Configuration ORIGINAL\Configuration.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.ConfigInfo" Collapsed="true">
|
||||
<Position X="24.5" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>IQAAAAAEAAAAAAADAAACABQAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Configuration ORIGINAL\Configuration.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.SourceListConfigProperties" Collapsed="true">
|
||||
<Position X="24.5" Y="7.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAEAAAAAAAAAAAIAAAAAgAAAIAAA=</HashCode>
|
||||
<FileName>Configuration ORIGINAL\ConfigurationHelpers.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.DmFactory" Collapsed="true">
|
||||
<Position X="31.5" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAQAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Configuration ORIGINAL\Factories\DmFactory.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.FactoryHelper" Collapsed="true">
|
||||
<Position X="26.25" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAEDAAKAA=</HashCode>
|
||||
<FileName>Configuration ORIGINAL\Factories\FactoryHelper.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.IrOutPortConfig" Collapsed="true">
|
||||
<Position X="31.5" Y="4.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAABAAAA=</HashCode>
|
||||
<FileName>Configuration ORIGINAL\Factories\FactoryHelper.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.ControlSystem" Collapsed="true">
|
||||
<Position X="35" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAoAgAAIAEAACAAEAIEIBICAAAAAAABAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>ControlSystem.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Amplifier" Collapsed="true" BaseTypeListCollapsed="true">
|
||||
<Position X="21" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAA=</HashCode>
|
||||
<FileName>Devices\Amplifier.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" Collapsed="true" />
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.CotijaConfig" Collapsed="true">
|
||||
<Position X="19.25" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\CotijaConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.CotijaDdvc01RoomBridgePropertiesConfig" Collapsed="true">
|
||||
<Position X="22.75" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\CotijaConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.CotijaSystemController" Collapsed="true">
|
||||
<Position X="24.5" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>CAAABAABAgACCAKGBIAAEyBAFAAACYSAgIAAAAJkAAA=</HashCode>
|
||||
<FileName>Room\Cotija\CotijaSystemController.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.CotijaBridgeBase" Collapsed="true">
|
||||
<Position X="9.5" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAQIQAAAAAAAAgAAAAAAQAAAAAAAAAAAAAAAABAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\RoomBridges\CotijaBridgeBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.CotijaEssentialsHuddleSpaceRoomBridge" Collapsed="true">
|
||||
<Position X="8.25" Y="5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAIAAAAIABAAkgAABgIAAAAAAAAAEAAAAAAgBAAACA=</HashCode>
|
||||
<FileName>Room\Cotija\RoomBridges\CotijaEssentialsHuddleSpaceRoomBridge.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.SourceSelectMessageContent" Collapsed="true">
|
||||
<Position X="26.25" Y="7.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\RoomBridges\CotijaEssentialsHuddleSpaceRoomBridge.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.EssentialsHuddleSpaceRoom" Collapsed="true">
|
||||
<Position X="0.5" Y="9" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>iQFBQAIAAgAAgQAEQACAMABAAABAACAQUAAQAAgCgBA=</HashCode>
|
||||
<FileName>Room\Types\EssentialsHuddleSpaceRoom.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" />
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.EssentialsHuddleVtc1Room" Collapsed="true">
|
||||
<Position X="2.75" Y="9" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>iQFBQAIAIgQMgQAEQAigMABAAABAADIwUACQAAgCgTE=</HashCode>
|
||||
<FileName>Room\Types\EssentialsHuddleVtc1Room.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" />
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.EssentialsPresentationRoom" Collapsed="true">
|
||||
<Position X="5" Y="9" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>iQAEAAIACkAAAQAOQASgMAAJAABgAAAQQAAQAAgCgBA=</HashCode>
|
||||
<FileName>Room\Types\EssentialsPresentationRoom.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" />
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.EssentialsRoomBase" Collapsed="true">
|
||||
<Position X="2.75" Y="7.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>gQAAEAICECgCAQAEAAAUIwIyAAAAgACiAgAAAQECAgA=</HashCode>
|
||||
<FileName>Room\Types\EssentialsRoomBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.CrestronTouchpanelPropertiesConfig" Collapsed="true">
|
||||
<Position X="26.25" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AICCIAAIGIAAAAAgCAAIAEAAAAAAAAAAAAEAIAAAAAA=</HashCode>
|
||||
<FileName>UI\CrestronTouchpanelPropertiesConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.UiSetupPropertiesConfig" Collapsed="true">
|
||||
<Position X="19.25" Y="8.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>UI\CrestronTouchpanelPropertiesConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.EssentialsTouchpanelController" Collapsed="true">
|
||||
<Position X="21" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAIAEAAAAAAAAAAAAAAAAEAAAAACKIBAAgACAAAAAA=</HashCode>
|
||||
<FileName>UI\EssentialsTouchpanelController.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.HttpLogoServer" Collapsed="true">
|
||||
<Position X="19.25" Y="4.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAQAAAACAAAAABAAAAAAAAAABAAAAAAAAAAkAAAAA=</HashCode>
|
||||
<FileName>UI\HttpLogoServer.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.UIBoolJoin" Collapsed="true">
|
||||
<Position X="35" Y="7.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>j+jWCNqEIGzi4UTaTgyn37kpncQJK7L42VMLmMgTE5A=</HashCode>
|
||||
<FileName>UI\JoinConstants\UIBoolJoin.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.UISmartObjectJoin" Collapsed="true">
|
||||
<Position X="21" Y="8.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>BAggBIABCQAAGAAQAAAACAACAAAAAAAAAAIAAAAAAAA=</HashCode>
|
||||
<FileName>UI\JoinConstants\UISmartObjectJoin.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.UIStringJoin" Collapsed="true">
|
||||
<Position X="22.75" Y="8.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>BkBgIAgAAggOQAFGAYQIABACgCEBjkSQAUEAASIABCE=</HashCode>
|
||||
<FileName>UI\JoinConstants\UIStringlJoin.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.UIUshortJoin" Collapsed="true">
|
||||
<Position X="24.5" Y="8.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAQAAAACAAAACAEAAIAAAAAAIABAIAAAABAAAEAAAAA=</HashCode>
|
||||
<FileName>UI\JoinConstants\UIUshortJoin.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.SubpageReferenceListActivityItem" Collapsed="true">
|
||||
<Position X="28" Y="7.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA=</HashCode>
|
||||
<FileName>UI\SubpageReferenceListActivityItem.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.SubpageReferenceListButtonAndModeItem" Collapsed="true">
|
||||
<Position X="29.75" Y="7.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA=</HashCode>
|
||||
<FileName>UI\SubpageReferenceListCallStagingItem.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.SubpageReferenceListSourceItem" Collapsed="true">
|
||||
<Position X="31.5" Y="7.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAABAAAAAAAAAAAAAAAAAAAAgAAAAACAAAAAABgAAA=</HashCode>
|
||||
<FileName>UI\SubpageReferenceListSourceItem.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.PanelDriverBase" Collapsed="true">
|
||||
<Position X="8.75" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>CAAIkAAAAAAQEAAAEAACAAAAAIAEABAAAgAACAAAAAA=</HashCode>
|
||||
<FileName>UIDrivers\enums and base.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.EssentialsPanelMainInterfaceDriver" Collapsed="true">
|
||||
<Position X="1" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>ABAAAAAAAhgAAAAAEAAAAAAAAIAEAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>UIDrivers\Essentials\EssentialsPanelMainInterfaceDriver.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.EssentialsPresentationPanelAvFunctionsDriver" Collapsed="true">
|
||||
<Position X="3.25" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>gTEAIIAiCggFNCQ4EA4AWBkAKJCEqAAOS4CKMAQQJQA=</HashCode>
|
||||
<FileName>UIDrivers\Essentials\EssentialsPresentationPanelAvFunctionsDriver.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.EssentialsHuddlePanelAvFunctionsDriver" Collapsed="true">
|
||||
<Position X="7.75" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>gRQAIICuAghENHQpEA4IWCkBMJDEsEAEC4CAMARQIBA=</HashCode>
|
||||
<FileName>UIDrivers\EssentialsHuddle\EssentialsHuddlePanelAvFunctionsDriver.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.EssentialsHuddleVtc1PanelAvFunctionsDriver" Collapsed="true">
|
||||
<Position X="12.25" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>GRwAIYC+oghAeHStEDAIWCdBMADEsBAcDwCAMARYIBg=</HashCode>
|
||||
<FileName>UIDrivers\EssentialsHuddleVTC\EssentialsHuddleVtc1PanelAvFunctionsDriver.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" />
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.JoinedSigInterlock" Collapsed="true">
|
||||
<Position X="19.25" Y="5.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAQgAIAAAAAAAAAEAAAAAQAAAAEAAAAAAAAEAAAgAA=</HashCode>
|
||||
<FileName>UIDrivers\JoinedSigInterlock.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.SingleSubpageModalAndBackDriver" Collapsed="true">
|
||||
<Position X="14.5" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAEAAAQAAABIAEAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>UIDrivers\Page Drivers\SingleSubpageModalAndBackDriver.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.SingleSubpageModalDriver" Collapsed="true">
|
||||
<Position X="16.75" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAEAAAAAAABAAEAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>UIDrivers\Page Drivers\SingleSubpageModalDriver.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.SigInterlock" Collapsed="true">
|
||||
<Position X="19.25" Y="7.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAQAAIAAAAAAAAIEAAAAAAAAAAEAAAAAAAAEAAAgAA=</HashCode>
|
||||
<FileName>UIDrivers\SigInterlock.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.SmartObjectRoomsList" Collapsed="true">
|
||||
<Position X="21" Y="7.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAACAAACBAAAAAAAAAAAAAAAAAAAAIAAAAAAQA=</HashCode>
|
||||
<FileName>UIDrivers\SmartObjectRoomsList.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.SmartObjectRoomsListItem" Collapsed="true">
|
||||
<Position X="22.75" Y="7.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAQAAAAAAAAAAAABAAQAAAAAAAAAACAAEAAAAAAAA=</HashCode>
|
||||
<FileName>UIDrivers\SmartObjectRoomsList.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.VolumeDeviceChangeEventArgs" Collapsed="true">
|
||||
<Position X="26.25" Y="8.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAABAAAAAEAAAAAAAAAAAAAAAAAAAQAAAAAAAAA=</HashCode>
|
||||
<FileName>UIDrivers\VolumeAndSourceChangeArgs.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase" Collapsed="true">
|
||||
<Position X="8.25" Y="9.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>IAGigRBpCgZwAIMSBBIbIgAAImAPtEBiAAgECpJgKQo=</HashCode>
|
||||
<FileName>OTHER\Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" />
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.FusionRoomExtensions" Collapsed="true">
|
||||
<Position X="31.5" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAACgAIQAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.FusionStaticAssetExtensions" Collapsed="true">
|
||||
<Position X="35" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAQAAACAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.EssentialsHuddleVtc1FusionController" Collapsed="true">
|
||||
<Position X="8.25" Y="11" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AACAAAAAAgAAAIAAAAAAAAAgIBAQAAAAAAAAAAAAAQA=</HashCode>
|
||||
<FileName>OTHER\Fusion\EssentialsHuddleVtc1FusionController.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.ScheduleChangeEventArgs" Collapsed="true">
|
||||
<Position X="33.25" Y="6.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionEventHandlers.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.MeetingChangeEventArgs" Collapsed="true">
|
||||
<Position X="26.25" Y="5.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionEventHandlers.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.ProcessorProgReg" Collapsed="true">
|
||||
<Position X="19.25" Y="6.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionProcessorQueries.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.ProcessorProgramItem" Collapsed="true">
|
||||
<Position X="35" Y="5.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAEAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionProcessorQueries.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.FusionRoomGuids" Collapsed="true">
|
||||
<Position X="33.25" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAICAAAAAAAAAAAAAAAAAACAAAATQAAAAAAAABAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.FusionOccupancySensorAsset" Collapsed="true">
|
||||
<Position X="29.75" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAQAQAAAAAAAAQAAAAAAQAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.FusionAsset" Collapsed="true">
|
||||
<Position X="28" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAQAQAAAAAAAAQAAAAAAQAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.RoomSchedule" Collapsed="true">
|
||||
<Position X="31.5" Y="6.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.LocalTimeRequest" Collapsed="true">
|
||||
<Position X="24.5" Y="5.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.RequestSchedule" Collapsed="true">
|
||||
<Position X="22.75" Y="6.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAACACAAAAQAAAAAAAAAAAAAAAAAAAACAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.RequestAction" Collapsed="true">
|
||||
<Position X="21" Y="6.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAACAAAgAAQAAAAAAAAAAAAAAAAAAIAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.ActionResponse" Collapsed="true">
|
||||
<Position X="19.25" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAgAAQAAAAAAAAAAAAAAAAAAIAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.Parameter" Collapsed="true">
|
||||
<Position X="33.25" Y="5.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAgAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.ScheduleResponse" Collapsed="true">
|
||||
<Position X="35" Y="6.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAACAAAAAAQAAAAAAAAAAgAAAAAAAAAAABAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.Event" Collapsed="true">
|
||||
<Position X="24.5" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AABCAAAAYEAAEBIBAIAAJAQAQKAYAAAIEAAAEAACCgg=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.Resources" Collapsed="true">
|
||||
<Position X="26.25" Y="6.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.Rooms" Collapsed="true">
|
||||
<Position X="29.75" Y="6.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.Room" Collapsed="true">
|
||||
<Position X="28" Y="6.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAgAAAAAAAAAQAAAAAAAAAAAAAAAAEAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.Attendees" Collapsed="true">
|
||||
<Position X="22.75" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAABAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.Required" Collapsed="true">
|
||||
<Position X="24.5" Y="6.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.Optional" Collapsed="true">
|
||||
<Position X="31.5" Y="5.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.MeetingType" Collapsed="true">
|
||||
<Position X="28" Y="5.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAgAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.MeetingTypes" Collapsed="true">
|
||||
<Position X="29.75" Y="5.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.LiveMeeting" Collapsed="true">
|
||||
<Position X="21" Y="5.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAgAQAAIAAAAAAACAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Fusion.LiveMeetingURL" Collapsed="true">
|
||||
<Position X="22.75" Y="5.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>OTHER\Fusion\FusionRviDataClasses.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.DDVC01RoomPropertiesConfig" Collapsed="true">
|
||||
<Position X="5" Y="6.25" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAIAgAAQAAAAAAAAEAAAAAAA=</HashCode>
|
||||
<FileName>Room\Config\DDVC01RoomPropertiesConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.DDVC01SpeedDial" Collapsed="true">
|
||||
<Position X="28" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAEAAAAQAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Config\DDVC01RoomPropertiesConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsHuddleRoomPropertiesConfig" Collapsed="true">
|
||||
<Position X="2.75" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAgAAAAAAAAAAACAAAAAABAAAAAAAAABA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsHuddleRoomPropertiesConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsHuddleVtc1PropertiesConfig" Collapsed="true">
|
||||
<Position X="5" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAgAAAAAAAAAAACIAAAAABAAAAAAAAABA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsHuddleVtc1PropertiesConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsPresentationRoomPropertiesConfig" Collapsed="true">
|
||||
<Position X="0.5" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAACAIAAAAAAAAAAABAACAAAAAABAAAAAAAAABA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsPresentationPropertiesConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsRoomConfig" Collapsed="true">
|
||||
<Position X="26.25" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAEAAAAAA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsRoomConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsRoomPropertiesConfig" Collapsed="true">
|
||||
<Position X="2.75" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AABAEQAAAAEoAAEEAAQAAAACAAAAAAgggAAAAQAAAgA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsRoomConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsLightingPropertiesConfig" Collapsed="true">
|
||||
<Position X="19.25" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsRoomConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsRoomMicrophonePrivacyConfig" Collapsed="true">
|
||||
<Position X="31.5" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAEAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsRoomConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsHelpPropertiesConfig" Collapsed="true">
|
||||
<Position X="35" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAgABAAAAAIAAAAAA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsRoomConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsOneButtonMeetingPropertiesConfig" Collapsed="true">
|
||||
<Position X="22.75" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsRoomConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsRoomAddressPropertiesConfig" Collapsed="true">
|
||||
<Position X="24.5" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAQAAAgAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsRoomConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsLogoPropertiesConfig" Collapsed="true">
|
||||
<Position X="21" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIACQAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsRoomConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsRoomOccSensorConfig" Collapsed="true">
|
||||
<Position X="33.25" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AACAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsRoomConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsRoomTechConfig" Collapsed="true">
|
||||
<Position X="35" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsRoomConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsRoomEmergencyConfig" Collapsed="true">
|
||||
<Position X="28" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAABAACAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsRoomEmergencyConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Config.EssentialsRoomEmergencyTriggerConfig" Collapsed="true">
|
||||
<Position X="29.75" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAABQAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Config\EssentialsRoomEmergencyConfig.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Cotija.CotijaDdvc01DeviceBridge" Collapsed="true" BaseTypeListCollapsed="true">
|
||||
<Position X="21" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AUAAAAgAAAACwAYAAAAAAAEAAAAAAAAAIcAAAEAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\CotijaDdvc01DeviceBridge.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" Collapsed="true" />
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Cotija.IChannelExtensions" Collapsed="true">
|
||||
<Position X="21" Y="4.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAACAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\DeviceTypeInterfaces\IChannelExtensions.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Cotija.IColorExtensions" Collapsed="true">
|
||||
<Position X="22.75" Y="4.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAACAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\DeviceTypeInterfaces\IColorExtensions.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Cotija.IDPadExtensions" Collapsed="true">
|
||||
<Position X="24.5" Y="4.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAACAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\DeviceTypeInterfaces\IDPadExtensions.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Cotija.IDvrExtensions" Collapsed="true">
|
||||
<Position X="26.25" Y="4.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAACAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\DeviceTypeInterfaces\IDvrExtensions.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Cotija.INumericExtensions" Collapsed="true">
|
||||
<Position X="28" Y="4.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAACAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\DeviceTypeInterfaces\INumericExtensions.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Cotija.IPowerExtensions" Collapsed="true">
|
||||
<Position X="29.75" Y="4.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAACAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\DeviceTypeInterfaces\IPowerExtensions.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Cotija.ISetTopBoxControlsExtensions" Collapsed="true">
|
||||
<Position X="33.25" Y="4.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAACAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\DeviceTypeInterfaces\ISetTopBoxControlsExtensions.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Cotija.ITransportExtensions" Collapsed="true">
|
||||
<Position X="35" Y="4.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAACAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\DeviceTypeInterfaces\ITransportExtensions.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.Cotija.CotijaDdvc01RoomBridge" Collapsed="true">
|
||||
<Position X="10.5" Y="5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>gACIAAAAAAICAFAAAACAAAEIIAAAAAQAQAAAABAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\RoomBridges\CotijaDdvc01RoomBridge.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" />
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.EssentialsRoomEmergencyBase" Collapsed="true">
|
||||
<Position X="8.25" Y="6.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Emergency\EsentialsRoomEmergencyContactClosure.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" />
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.Room.EssentialsRoomEmergencyContactClosure" Collapsed="true">
|
||||
<Position X="8.25" Y="7.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAASBAAAAAAAAAAAAAABAAAAAAAEAA=</HashCode>
|
||||
<FileName>Room\Emergency\EsentialsRoomEmergencyContactClosure.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver" Collapsed="true">
|
||||
<Position X="5.5" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAQAAAAAiACDAAAGCAACgAIAABECBAgQAAAAQAAAAA=</HashCode>
|
||||
<FileName>UIDrivers\EssentialsHuddle\EssentialsHuddleTechPageDriver.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver" Collapsed="true">
|
||||
<Position X="10" Y="1.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>XAASAoAiAagwAcBAGAUURWQEOHQFAKCmAABCNSSEDPA=</HashCode>
|
||||
<FileName>UIDrivers\VC\EssentialsVideoCodecUiDriver.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Interface Name="PepperDash.Essentials.IHasCurrentSourceInfoChange" Collapsed="true">
|
||||
<Position X="22.75" Y="9.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Types\EssentialsRoomBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Interface>
|
||||
<Interface Name="PepperDash.Essentials.IAVDriver" Collapsed="true">
|
||||
<Position X="19.25" Y="9.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAgAAAAAAAAACBAAACAAAAIBAAAEAAAEAgAAAAAAIAA=</HashCode>
|
||||
<FileName>UIDrivers\EssentialsHuddleVTC\EssentialsHuddleVtc1PanelAvFunctionsDriver.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Interface>
|
||||
<Interface Name="PepperDash.Essentials.Room.Cotija.IDelayedConfiguration" Collapsed="true">
|
||||
<Position X="21" Y="9.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\Interfaces.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Interface>
|
||||
<Enum Name="PepperDash.Essentials.eShutdownType" Collapsed="true">
|
||||
<Position X="29.75" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAQAAAAAAACAAAAAAAAAAAAAAAAAAAAAEACAA=</HashCode>
|
||||
<FileName>Room\Types\EssentialsRoomBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="PepperDash.Essentials.eVacancyMode" Collapsed="true">
|
||||
<Position X="31.5" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAACAAAAAAAAAAAAAAAAACAAAAAAAAAAEAAAA=</HashCode>
|
||||
<FileName>Room\Types\EssentialsRoomBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="PepperDash.Essentials.eWarmingCoolingMode" Collapsed="true">
|
||||
<Position X="33.25" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAIEAAAA=</HashCode>
|
||||
<FileName>Room\Types\EssentialsRoomBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="PepperDash.Essentials.eAvSubpageType" Collapsed="true">
|
||||
<Position X="24.5" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AIAAAAAAAAAAAAAAAhBAAAAAAAAAAACYAAAAAAAAAAA=</HashCode>
|
||||
<FileName>UIDrivers\enums and base.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="PepperDash.Essentials.eAvSourceSubpageType" Collapsed="true">
|
||||
<Position X="22.75" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAABAAAAAAAAAAAAAAACAAAEAAAAAAAAA=</HashCode>
|
||||
<FileName>UIDrivers\enums and base.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="PepperDash.Essentials.eCommonSubpageType" Collapsed="true">
|
||||
<Position X="28" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAEAAAAAAAAAIAAAAAAAAQAAAAQAAAAAAAAAAA=</HashCode>
|
||||
<FileName>UIDrivers\enums and base.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="PepperDash.Essentials.eAvSmartObjects" Collapsed="true">
|
||||
<Position X="21" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAABAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>UIDrivers\enums and base.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="PepperDash.Essentials.eCommonSmartObjects" Collapsed="true">
|
||||
<Position X="26.25" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>UIDrivers\enums and base.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Enum Name="PepperDash.Essentials.ChangeType" Collapsed="true">
|
||||
<Position X="19.25" Y="10.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAgCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>UIDrivers\VolumeAndSourceChangeArgs.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Enum>
|
||||
<Delegate Name="PepperDash.Essentials.PressAndHoldAction" Collapsed="true">
|
||||
<Position X="19.25" Y="11.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>Room\Cotija\RoomBridges\CotijaEssentialsHuddleSpaceRoomBridge.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Delegate>
|
||||
<Delegate Name="PepperDash.Essentials.SourceInfoChangeHandler" Collapsed="true">
|
||||
<Position X="21" Y="11.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAACAAACAAAAAAAAAAAAAAAAAAACAAAAA=</HashCode>
|
||||
<FileName>UIDrivers\VolumeAndSourceChangeArgs.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Delegate>
|
||||
<Font Name="Segoe UI" Size="9" />
|
||||
</ClassDiagram>
|
||||
@@ -5,7 +5,6 @@ using System.Reflection;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.CrestronThread;
|
||||
using Crestron.SimplSharpPro.Diagnostics;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
@@ -28,10 +27,8 @@ namespace PepperDash.Essentials;
|
||||
/// provides methods for platform determination, configuration loading, and system teardown.</remarks>
|
||||
public class ControlSystem : CrestronControlSystem, ILoadConfig
|
||||
{
|
||||
private HttpLogoServer LogoServer;
|
||||
|
||||
private Timer _startTimer;
|
||||
private ManualResetEventSlim _initializeEvent;
|
||||
private Timer startTimer;
|
||||
private ManualResetEventSlim initializeEvent;
|
||||
private const long StartupTime = 500;
|
||||
|
||||
/// <summary>
|
||||
@@ -79,16 +76,16 @@ public class ControlSystem : CrestronControlSystem, ILoadConfig
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "******************* Initializing System **********************");
|
||||
|
||||
_startTimer = new Timer(StartSystem, preventInitializationComplete, StartupTime, Timeout.Infinite);
|
||||
startTimer = new Timer(StartSystem, preventInitializationComplete, StartupTime, Timeout.Infinite);
|
||||
|
||||
_initializeEvent = new ManualResetEventSlim(false);
|
||||
initializeEvent = new ManualResetEventSlim(false);
|
||||
|
||||
DeviceManager.AllDevicesRegistered += (o, a) =>
|
||||
{
|
||||
_initializeEvent.Set();
|
||||
initializeEvent.Set();
|
||||
};
|
||||
|
||||
_initializeEvent.Wait(30000);
|
||||
initializeEvent.Wait(30000);
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Debug, "******************* System Initialization Complete **********************");
|
||||
|
||||
@@ -96,7 +93,7 @@ public class ControlSystem : CrestronControlSystem, ILoadConfig
|
||||
}
|
||||
else
|
||||
{
|
||||
_startTimer = new Timer(StartSystem, preventInitializationComplete, StartupTime, Timeout.Infinite);
|
||||
startTimer = new Timer(StartSystem, preventInitializationComplete, StartupTime, Timeout.Infinite);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,7 +354,6 @@ public class ControlSystem : CrestronControlSystem, ILoadConfig
|
||||
{
|
||||
LoadDevices();
|
||||
LoadRooms();
|
||||
LoadLogoServer();
|
||||
|
||||
DeviceManager.ActivateAll();
|
||||
|
||||
@@ -495,67 +491,6 @@ public class ControlSystem : CrestronControlSystem, ILoadConfig
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires up a logo server if not already running
|
||||
/// </summary>
|
||||
void LoadLogoServer()
|
||||
{
|
||||
if (ConfigReader.ConfigObject.Rooms == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "No rooms configured. Bypassing Logo server startup.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!ConfigReader.ConfigObject.Rooms.Any(
|
||||
CheckRoomConfig))
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "No rooms configured to use system Logo server. Bypassing Logo server startup");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
LogoServer = new HttpLogoServer(8080, Global.DirectorySeparator + "html" + Global.DirectorySeparator + "logo");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "NOTICE: Logo server cannot be started. Likely already running in another program");
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckRoomConfig(DeviceConfig c)
|
||||
{
|
||||
string logoDark = null;
|
||||
string logoLight = null;
|
||||
string logo = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (c.Properties["logoDark"] != null)
|
||||
{
|
||||
logoDark = c.Properties["logoDark"].Value<string>("type");
|
||||
}
|
||||
|
||||
if (c.Properties["logoLight"] != null)
|
||||
{
|
||||
logoLight = c.Properties["logoLight"].Value<string>("type");
|
||||
}
|
||||
|
||||
if (c.Properties["logo"] != null)
|
||||
{
|
||||
logo = c.Properties["logo"].Value<string>("type");
|
||||
}
|
||||
|
||||
return ((logoDark != null && logoDark == "system") ||
|
||||
(logoLight != null && logoLight == "system") || (logo != null && logo == "system"));
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Unable to find logo information in any room config");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void LoadAssets()
|
||||
{
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharp.Net.Http;
|
||||
|
||||
using PepperDash.Core;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials;
|
||||
|
||||
public class HttpLogoServer
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
readonly HttpServer _server;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
readonly string _fileDirectory;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static Dictionary<string, string> ExtensionContentTypes;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="port"></param>
|
||||
/// <param name="directory"></param>
|
||||
public HttpLogoServer(int port, string directory)
|
||||
{
|
||||
ExtensionContentTypes = new Dictionary<string, string>
|
||||
{
|
||||
//{ ".css", "text/css" },
|
||||
//{ ".htm", "text/html" },
|
||||
//{ ".html", "text/html" },
|
||||
{ ".jpg", "image/jpeg" },
|
||||
{ ".jpeg", "image/jpeg" },
|
||||
//{ ".js", "application/javascript" },
|
||||
//{ ".json", "application/json" },
|
||||
//{ ".map", "application/x-navimap" },
|
||||
{ ".pdf", "application/pdf" },
|
||||
{ ".png", "image/png" },
|
||||
//{ ".txt", "text/plain" },
|
||||
};
|
||||
|
||||
_server = new HttpServer {Port = port};
|
||||
_fileDirectory = directory;
|
||||
_server.OnHttpRequest += Server_OnHttpRequest;
|
||||
_server.Open();
|
||||
|
||||
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void Server_OnHttpRequest(object sender, OnHttpRequestArgs args)
|
||||
{
|
||||
var path = args.Request.Path;
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "HTTP Request with path: '{requestPath:l}'", args.Request.Path);
|
||||
|
||||
try
|
||||
{
|
||||
if (File.Exists(_fileDirectory + path))
|
||||
{
|
||||
var filePath = path.Replace('/', '\\');
|
||||
var localPath = string.Format(@"{0}{1}", _fileDirectory, filePath);
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "HTTP Logo Server attempting to find file: '{localPath:l}'", localPath);
|
||||
if (File.Exists(localPath))
|
||||
{
|
||||
args.Response.Header.ContentType = GetContentType(new FileInfo(localPath).Extension);
|
||||
args.Response.ContentStream = new FileStream(localPath, FileMode.Open, FileAccess.Read);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "HTTP Logo Server Cannot find file '{localPath:l}'", localPath);
|
||||
args.Response.ContentString = string.Format("Not found: '{0}'", filePath);
|
||||
args.Response.Code = 404;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "HTTP Logo Server: '{file:l}' does not exist", _fileDirectory + path);
|
||||
args.Response.ContentString = string.Format("Not found: '{0}'", _fileDirectory + path);
|
||||
args.Response.Code = 404;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Error, "Exception getting file: {exception}", ex.Message, ex.StackTrace);
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "Stack Trace: {stackTrace}", ex.StackTrace);
|
||||
|
||||
args.Response.Code = 400;
|
||||
args.Response.ContentString = string.Format("invalid request");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
|
||||
{
|
||||
if (programEventType == eProgramStatusEventType.Stopping)
|
||||
_server.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="extension"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetContentType(string extension)
|
||||
{
|
||||
var type = ExtensionContentTypes.ContainsKey(extension) ? ExtensionContentTypes[extension] : "text/plain";
|
||||
return type;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user