Merge remote-tracking branch 'origin/feature/ecs-407' into feature/cisco-spark-2

This commit is contained in:
Neil Dorin
2017-09-28 15:26:28 -06:00
18 changed files with 486 additions and 139 deletions

View File

@@ -15,6 +15,7 @@ namespace PepperDash.Essentials
public class ControlSystem : CrestronControlSystem
{
PepperDashPortalSyncClient PortalSync;
HttpLogoServer LogoServer;
public ControlSystem()
: base()
@@ -63,6 +64,8 @@ namespace PepperDash.Essentials
LoadTieLines();
LoadRooms();
LogoServer = new HttpLogoServer(8080, @"\html\logo");
DeviceManager.ActivateAll();
Debug.Console(0, "Essentials load complete\r" +
"-------------------------------------------------------------");
@@ -206,6 +209,5 @@ namespace PepperDash.Essentials
Debug.Console(0, "WARNING: Cannot create room from config, key '{0}'", roomConfig.Key);
}
}
}
}

View File

@@ -164,11 +164,14 @@
<Compile Include="FOR REFERENCE UI\PageControllers\PageControllerLargeSetTopBoxGeneric.cs" />
<Compile Include="FOR REFERENCE UI\PageControllers\LargeTouchpanelControllerBase.cs" />
<Compile Include="FOR REFERENCE UI\Panels\SmartGraphicsTouchpanelControllerBase.cs" />
<Compile Include="UIDrivers\SigInterlock.cs" />
<Compile Include="UIDrivers\EssentialsHuddleVTC\EssentialsHuddlePresentationUiDriver.cs" />
<Compile Include="UIDrivers\EssentialsHuddleVTC\EssentialsHuddleTechPageDriver.cs" />
<Compile Include="UI\HttpLogoServer.cs" />
<Compile Include="UI\SubpageReferenceListCallStagingItem.cs" />
<Compile Include="UIDrivers\VC\EssentialsVideoCodecUiDriver.cs" />
<Compile Include="UIDrivers\JoinedSigInterlock.cs" />
<Compile Include="UIDrivers\EssentialsHuddleVTC\HuddleVTCPanelAvFunctionsDriver.cs" />
<Compile Include="UIDrivers\EssentialsHuddleVTC\EssentialsHuddleVtc1PanelAvFunctionsDriver.cs" />
<Compile Include="UIDrivers\VolumeAndSourceChangeArgs.cs" />
<Compile Include="UI\JoinConstants\UISmartObjectJoin.cs" />
<Compile Include="UI\JoinConstants\UIStringlJoin.cs" />

View File

@@ -141,7 +141,7 @@ namespace PepperDash.Essentials.Room.Config
if (Type == "url")
return Url;
if (Type == "system")
return string.Format("http://{0}:5646/logo",
return string.Format("http://{0}:8080/logo.png",
CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0));
return null;
}

View File

@@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.Net.Http;
using PepperDash.Core;
namespace PepperDash.Essentials
{
public class HttpLogoServer
{
/// <summary>
///
/// </summary>
HttpServer Server;
/// <summary>
///
/// </summary>
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();
Server.Port = port;
FileDirectory = directory;
Server.OnHttpRequest += new OnHttpRequestHandler(Server_OnHttpRequest);
Server.Open();
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
}
/// <summary>
///
/// </summary>
void Server_OnHttpRequest(object sender, OnHttpRequestArgs args)
{
var path = args.Request.Path;
if (File.Exists(FileDirectory + @"\" + path))
{
string filePath = path.Replace('/', '\\');
string localPath = string.Format(@"{0}{1}", FileDirectory, filePath);
if (File.Exists(localPath))
{
args.Response.Header.ContentType = GetContentType(new FileInfo(localPath).Extension);
args.Response.ContentStream = new FileStream(localPath, FileMode.Open, FileAccess.Read);
}
else
{
args.Response.ContentString = string.Format("Not found: '{0}'", filePath);
args.Response.Code = 404;
}
}
}
/// <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)
{
string type;
if (ExtensionContentTypes.ContainsKey(extension))
type = ExtensionContentTypes[extension];
else
type = "text/plain";
return type;
}
}
}

View File

@@ -206,6 +206,43 @@ namespace PepperDash.Essentials
// Letter joins start at 2921;
/// <summary>
/// 3101
/// </summary>
public const uint TechExitButton = 3101;
/// <summary>
/// 3106
/// </summary>
public const uint TechCommonItemsVisbible = 3106;
/// <summary>
/// 3107
/// </summary>
public const uint TechSystemStatusVisible = 3107;
/// <summary>
/// 3108
/// </summary>
public const uint TechDisplayControlsVisible = 3108;
/// <summary>
/// 3109
/// </summary>
public const uint TechPanelSetupVisible = 3109;
/// <summary>
/// 3110
/// </summary>
public const uint TechAdvancedVolumeVisible = 3110;
/// <summary>
/// 3111
/// </summary>
public const uint TechAboutVisible = 3111;
/// <summary>
/// 3112
/// </summary>
public const uint TechSchedulerVisible = 3112;
//******************************************************
/// <summary>
/// 3811
@@ -300,14 +337,8 @@ namespace PepperDash.Essentials
/// 3891
/// </summary>
public const uint VolumeDefaultPress = 3891;
/// <summary>
/// 3901
/// </summary>
public const uint TechPagesExitButton = 3901;
/// <summary>
/// 3902
/// </summary>
public const uint TechPanelSetupVisible = 3902;
/// <summary>
/// 3999
/// </summary>

View File

@@ -29,6 +29,14 @@
/// 15022 The main activity footer
/// </summary>
public const uint ActivityFooterSRL = 15022;
/// <summary>
/// 3901 The Tech page menu list
/// </summary>
public const uint TechMenuList = 3901;
/// <summary>
/// 3902 Tech page statuses
/// </summary>
public const uint TechStatusList = 3902;
}
}

View File

@@ -28,6 +28,14 @@ namespace PepperDash.Essentials
/// </summary>
//public const uint KeypadText = 2901;
/// <summary>
/// 3101 - This is the start of the range 3101 - 3120
/// </summary>
public const uint TechMenuButtonTextStart = 3101;
//----- through 3120
/// <summary>
/// 3812
/// </summary>

View File

@@ -220,7 +220,7 @@ namespace PepperDash.Essentials
// Setup button
TriList.SetSigHeldAction(UIBoolJoin.GearHeaderButtonPress, 2000,
() => PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.TechPanelSetupVisible));// ShowInterlockedModal(UIBoolJoin.TechPanelSetupVisible));
TriList.SetSigFalseAction(UIBoolJoin.TechPagesExitButton, () =>
TriList.SetSigFalseAction(UIBoolJoin.TechExitButton, () =>
PopupInterlock.HideAndClear()); // HideCurrentInterlockedModal());
#warning This gets overridden by config after NYU demo
if(TriList is CrestronApp)

View File

@@ -0,0 +1,147 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects;
using PepperDash.Essentials.Core.Touchpanels.Keyboards;
namespace PepperDash.Essentials.UIDrivers
{
public class EssentialsHuddleTechPageDriver : PanelDriverBase
{
/// <summary>
///
/// </summary>
SmartObjectDynamicList MenuList;
/// <summary>
///
/// </summary>
SubpageReferenceList StatusList;
/// <summary>
/// References lines in the list against device instances
/// </summary>
Dictionary<ICommunicationMonitor, uint> StatusListDeviceIndexes;
/// <summary>
///
/// </summary>
IAVDriver Parent;
/// <summary>
///
/// </summary>
JoinedSigInterlock PagesInterlock;
/// <summary>
/// 1
/// </summary>
public const uint JoinText = 1;
/// <summary>
///
/// </summary>
/// <param name="trilist"></param>
/// <param name="parent"></param>
public EssentialsHuddleTechPageDriver(BasicTriListWithSmartObject trilist, IAVDriver parent)
: base(trilist)
{
Parent = parent;
PagesInterlock = new JoinedSigInterlock(trilist);
PagesInterlock.SetButDontShow(UIBoolJoin.TechSystemStatusVisible);
trilist.SetSigFalseAction(UIBoolJoin.TechExitButton, Hide);
MenuList = new SmartObjectDynamicList(trilist.SmartObjects[UISmartObjectJoin.TechMenuList],
true, 3100);
MenuList.SetFeedback(1, true); // initial fb
MenuList.SetItemMainText(1, "System Status");
MenuList.SetItemButtonAction(1, b => {
if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechSystemStatusVisible);
MenuList.SetFeedback(1, true);
});
MenuList.SetItemMainText(2, "Display Controls");
MenuList.SetItemButtonAction(2, b => {
if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechDisplayControlsVisible);
MenuList.SetFeedback(2, true);
});
MenuList.SetItemMainText(3, "Panel Setup");
MenuList.SetItemButtonAction(3, b => {
if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechPanelSetupVisible);
MenuList.SetFeedback(3, true);
});
MenuList.Count = 3;
BuildStatusList();
}
/// <summary>
///
/// </summary>
public override void Show()
{
TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, true);
PagesInterlock.Show();
base.Show();
}
/// <summary>
///
/// </summary>
public override void Hide()
{
TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, false);
PagesInterlock.Hide();
base.Hide();
}
/// <summary>
///
/// </summary>
void BuildStatusList()
{
StatusList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechStatusList, 3, 3, 3);
StatusListDeviceIndexes = new Dictionary<ICommunicationMonitor, uint>();
uint i = 0;
foreach (var d in DeviceManager.AllDevices)
{
// make sure it is both ICommunicationMonitor and a Device
var sd = d as ICommunicationMonitor;
if (sd == null)
continue;
var dd = sd as Device;
if(dd == null)
continue;
i++;
StatusList.StringInputSig(i, 1).StringValue = dd.Name;
StatusList.UShortInputSig(i, 1).UShortValue = (ushort)sd.CommunicationMonitor.Status;
StatusListDeviceIndexes.Add(sd, i);
sd.CommunicationMonitor.StatusChange += CommunicationMonitor_StatusChange ;
}
StatusList.Count = (ushort)i;
}
/// <summary>
///
/// </summary>
void CommunicationMonitor_StatusChange(object sender, MonitorStatusChangeEventArgs e)
{
var c = sender as ICommunicationMonitor;
if (StatusListDeviceIndexes.ContainsKey(c))
{
var i = StatusListDeviceIndexes[c];
StatusList.UShortInputSig(i, 1).UShortValue = (ushort)e.Status;
}
}
}
}

View File

@@ -121,16 +121,47 @@ namespace PepperDash.Essentials
/// </summary>
JoinedSigInterlock StagingBarInterlock;
/// <summary>
/// Interlocks the various call-related subpages
/// </summary>
JoinedSigInterlock CallPagesInterlock;
/// <summary>
/// The Video codec driver
/// </summary>
PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver VCDriver;
/// <summary>
/// The driver for the tech page. Lazy getter for memory usage
/// </summary>
PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver TechDriver
{
get
{
if (_TechDriver == null)
_TechDriver = new PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver(TriList, this);
return _TechDriver;
}
}
PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver _TechDriver;
/// <summary>
/// Controls timeout of notification ribbon timer
/// </summary>
CTimer RibbonTimer;
/// <summary>
/// The keyboard
/// </summary>
public PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController Keyboard { get; private set; }
/// <summary>
/// The mode showing. Presentation or call.
/// </summary>
UiDisplayMode CurrentMode = UiDisplayMode.Start;
/// <summary>
/// Constructor
/// </summary>
@@ -277,14 +308,14 @@ namespace PepperDash.Essentials
// Setup button - shows volumes with default button OR hold for tech page
TriList.SetSigHeldAction(UIBoolJoin.GearHeaderButtonPress, 2000,
() => PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.TechPanelSetupVisible),
ShowTech,
() => PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.VolumesPageVisible));
TriList.SetSigFalseAction(UIBoolJoin.TechPagesExitButton, () =>
TriList.SetSigFalseAction(UIBoolJoin.TechExitButton, () =>
PopupInterlock.HideAndClear());
// Default Volume button
// Volume related things
TriList.SetSigFalseAction(UIBoolJoin.VolumeDefaultPress, () => CurrentRoom.SetDefaultLevels());
TriList.SetString(UIStringJoin.AdvancedVolumeSlider1Text, "Room");
if (TriList is CrestronApp)
TriList.BooleanInput[UIBoolJoin.GearButtonVisible].BoolValue = false;
@@ -379,6 +410,15 @@ namespace PepperDash.Essentials
}
}
/// <summary>
/// Reveals the tech page and puts away anything that's in the way.
/// </summary>
void ShowTech()
{
PopupInterlock.HideAndClear();
TechDriver.Show();
}
/// <summary>
/// When the room is off, set the footer SRL
/// </summary>
@@ -710,13 +750,13 @@ namespace PepperDash.Essentials
if (!srcConfig.IncludeInSourceList) // Skip sources marked this way
continue;
var actualSource = DeviceManager.GetDeviceForKey(srcConfig.SourceKey) as Device;
if (actualSource == null)
{
Debug.Console(1, "Cannot assign missing source '{0}' to source UI list",
srcConfig.SourceKey);
continue;
}
//var actualSource = DeviceManager.GetDeviceForKey(srcConfig.SourceKey) as Device;
//if (actualSource == null)
//{
// Debug.Console(1, "Cannot assign missing source '{0}' to source UI list",
// srcConfig.SourceKey);
// continue;
//}
var routeKey = kvp.Key;
var item = new SubpageReferenceListSourceItem(i++, SourceStagingSrl, srcConfig,
b => { if (!b) UiSelectSource(routeKey); });

View File

@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials
{
/// <summary>
/// Used for interlocking sigs, using a set-clears-last-set model.
/// </summary>
public class SigInterlock
{
/// <summary>
///
/// </summary>
public BoolInputSig CurrentSig { get; private set; }
/// <summary>
///
/// </summary>
public SigInterlock()
{
}
/// <summary>
/// Hides CurrentJoin and shows join. Does nothing when resending CurrentJoin
/// </summary>
public void ShowInterlocked(BoolInputSig sig)
{
if (CurrentSig == sig)
return;
SetButDontShow(sig);
sig.BoolValue = true;
}
/// <summary>
///
/// </summary>
/// <param name="join"></param>
public void ShowInterlockedWithToggle(BoolInputSig sig)
{
if(CurrentSig == sig)
HideAndClear();
else
{
if(CurrentSig != null)
CurrentSig.BoolValue = false;
CurrentSig = sig;
CurrentSig.BoolValue = true;
}
}
/// <summary>
/// Hides current Sig and clears CurrentSig
/// </summary>
public void HideAndClear()
{
Hide();
CurrentSig = null;
}
/// <summary>
/// Hides the current Sig but does not clear the selected Sig in case
/// it needs to be reshown
/// </summary>
public void Hide()
{
if(CurrentSig != null)
CurrentSig.BoolValue = false;
}
/// <summary>
/// If CurrentSig is set, it restores that Sig
/// </summary>
public void Show()
{
if(CurrentSig != null)
CurrentSig.BoolValue = true;
}
/// <summary>
/// Useful for pre-setting the interlock but not enabling it. Sets CurrentSig
/// </summary>
/// <param name="join"></param>
public void SetButDontShow(BoolInputSig sig)
{
if (CurrentSig != null)
CurrentSig.BoolValue = false;
CurrentSig = sig;
}
}
}