Pulling in 670 branch changes

This commit is contained in:
Heath Volmer
2018-02-08 12:35:08 -07:00
54 changed files with 58842 additions and 9907 deletions

View File

@@ -18,7 +18,7 @@ namespace PepperDash.Essentials
public static bool LoadConfig2()
{
Debug.Console(0, "Using unmerged system/template configs.");
Debug.Console(0, "Loading unmerged system/template portal configuration file.");
try
{
var filePath = string.Format(@"\NVRAM\program{0}\ConfigurationFile.json",
@@ -35,7 +35,7 @@ namespace PepperDash.Essentials
var doubleObj = JObject.Parse(fs.ReadToEnd());
ConfigObject = MergeConfigs(doubleObj).ToObject<EssentialsConfig>();
// Extract SystemUrl and TemplateUrl
// Extract SystemUrl and TemplateUrl into final config output
if (doubleObj["system_url"] != null)
{
@@ -83,7 +83,7 @@ namespace PepperDash.Essentials
else
merged.Add("sourceLists", Merge(template["sourceLists"], system["sourceLists"]));
// Template tie lines take precdence. Config tool probably can't do them at system
// Template tie lines take precdence. Config tool doesn't do them at system
// level anyway...
if (template["tieLines"] != null)
merged.Add("tieLines", template["tieLines"]);
@@ -92,7 +92,7 @@ namespace PepperDash.Essentials
else
merged.Add("tieLines", new JArray());
//Debug.Console(0, "MERGED RESULT: \x0d\x0a{0}", merged);
Debug.Console(2, "MERGED CONFIG RESULT: \x0d\x0a{0}", merged);
return merged;
}
@@ -141,7 +141,6 @@ namespace PepperDash.Essentials
/// <param name="b"></param>
static JObject Merge(JObject o1, JObject o2)
{
//Console.WriteLine("Merging {0}\ronto {1}", o2, o1);
foreach (var o2Prop in o2)
{
var o1Value = o1[o2Prop.Key];
@@ -160,6 +159,11 @@ namespace PepperDash.Essentials
return o1;
}
/// <summary>
/// Returns the group for a given device key in config
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string GetGroupForDeviceKey(string key)
{
var dev = ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));

View File

@@ -69,10 +69,24 @@ namespace PepperDash.Essentials
return new CotijaSystemController(key, name, props);
}
else if (typeName == "cotijaddvc01room")
else if (typeName == "cotijaddvc01roombridge")
{
var comm = CommFactory.GetControlPropertiesConfig(dc);
return new PepperDash.Essentials.Room.Cotija.CotijaDdvc01RoomBridge(key, name, comm.IpIdInt);
var bridge = new PepperDash.Essentials.Room.Cotija.CotijaDdvc01RoomBridge(key, name, comm.IpIdInt);
bridge.AddPreActivationAction(() =>
{
var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "cotijaServer") as CotijaSystemController;
if (parent == null)
{
Debug.Console(0, bridge, "ERROR: Cannot connect bridge. System controller not present");
}
Debug.Console(0, bridge, "Linking to parent controller");
bridge.AddParent(parent);
parent.CotijaRooms.Add(bridge);
});
return bridge;
}
return null;

View File

@@ -22,7 +22,7 @@ namespace PepperDash.Essentials
[JsonProperty("template_url")]
public string TemplateUrl { get; set; }
public CotijaConfig Cotija { get; private set; }
//public CotijaConfig Cotija { get; private set; }
public string SystemUuid
{
@@ -49,7 +49,7 @@ namespace PepperDash.Essentials
}
[JsonProperty("rooms")]
public List<EssentialsRoomConfig> Rooms { get; private set; }
public List<EssentialsRoomConfig> Rooms { get; set; }
}
/// <summary>
@@ -60,7 +60,5 @@ namespace PepperDash.Essentials
public EssentialsConfig System { get; set; }
public EssentialsConfig Template { get; set; }
//public CotijaConfig Cotija { get; set; }
}
}

View File

@@ -10,6 +10,7 @@ using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.DM;
using PepperDash.Essentials.Fusion;
using PepperDash.Essentials.Room.Cotija;
namespace PepperDash.Essentials
{
@@ -42,6 +43,21 @@ namespace PepperDash.Essentials
},
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
CrestronConsole.ConsoleCommandResponse
("Current running configuration. This is the merged system and template configuration");
CrestronConsole.ConsoleCommandResponse(Newtonsoft.Json.JsonConvert.SerializeObject
(ConfigReader.ConfigObject, Newtonsoft.Json.Formatting.Indented));
}, "showconfig", "Shows the current running merged config", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" +
"System URL: {0}\r" +
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
GoWithLoad();
}
@@ -67,8 +83,6 @@ namespace PepperDash.Essentials
return;
Load();
DeviceManager.ActivateAll();
Debug.Console(0, "Essentials load complete\r" +
"-------------------------------------------------------------");
}
@@ -147,6 +161,8 @@ namespace PepperDash.Essentials
LoadTieLines();
LoadRooms();
LoadLogoServer();
DeviceManager.ActivateAll();
}
@@ -157,28 +173,35 @@ namespace PepperDash.Essentials
{
foreach (var devConf in ConfigReader.ConfigObject.Devices)
{
Debug.Console(0, "Creating device '{0}'", devConf.Key);
// Skip this to prevent unnecessary warnings
if (devConf.Key == "processor")
continue;
// Try local factory first
var newDev = DeviceFactory.GetDevice(devConf);
// Then associated library factories
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf);
try
{
Debug.Console(0, "Creating device '{0}'", devConf.Key);
// Skip this to prevent unnecessary warnings
if (devConf.Key == "processor")
continue;
if (newDev != null)
DeviceManager.AddDevice(newDev);
else
Debug.Console(0, "WARNING: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
// Try local factory first
var newDev = DeviceFactory.GetDevice(devConf);
// Then associated library factories
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf);
if (newDev != null)
DeviceManager.AddDevice(newDev);
else
Debug.Console(0, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
}
catch (Exception e)
{
Debug.Console(0, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e);
}
}
}
/// <summary>
@@ -204,6 +227,12 @@ namespace PepperDash.Essentials
/// </summary>
public void LoadRooms()
{
if (ConfigReader.ConfigObject.Rooms == null)
{
Debug.Console(0, "WARNING: Configuration contains no rooms");
return;
}
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
{
var room = roomConfig.GetRoomObject();
@@ -216,12 +245,9 @@ namespace PepperDash.Essentials
Debug.Console(1, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1));
var cotija = DeviceManager.GetDeviceForKey("cotijaServer") as CotijaSystemController;
if (cotija != null)
{
cotija.CotijaRooms.Add(new CotijaEssentialsHuddleSpaceRoomBridge(cotija, room as EssentialsHuddleSpaceRoom));
}
Debug.Console(0, "******* RE-ENABLE COTIJA PROPERLY *******");
//var bridge = new CotijaEssentialsHuddleSpaceRoomBridge(room as EssentialsHuddleSpaceRoom);
//AddBridgePostActivationHelper(bridge);
}
else if (room is EssentialsHuddleVtc1Room)
{
@@ -229,7 +255,7 @@ namespace PepperDash.Essentials
Debug.Console(1, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1));
}
}
else
{
Debug.Console(1, "Room is NOT EssentialsHuddleSpaceRoom, attempting to add to DeviceManager w/o Fusion");
@@ -242,12 +268,30 @@ namespace PepperDash.Essentials
}
}
/// <summary>
/// Helps add the post activation steps that link bridges to main controller
/// </summary>
/// <param name="bridge"></param>
void AddBridgePostActivationHelper(CotijaBridgeBase bridge)
{
bridge.AddPostActivationAction(() =>
{
var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "cotijaServer") as CotijaSystemController;
if (parent == null)
{
Debug.Console(0, bridge, "ERROR: Cannot connect bridge. System controller not present");
}
Debug.Console(0, bridge, "Linking to parent controller");
bridge.AddParent(parent);
parent.CotijaRooms.Add(bridge);
});
}
/// <summary>
/// Fires up a logo server if not already running
/// </summary>
void LoadLogoServer()
{
try
{
LogoServer = new HttpLogoServer(8080, @"\html\logo");

View File

@@ -0,0 +1,276 @@
using System;
using System.Linq;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.CrestronThread;
using PepperDash.Core;
using PepperDash.Core.PortalSync;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.DM;
using PepperDash.Essentials.Fusion;
namespace PepperDash.Essentials
{
public class ControlSystem : CrestronControlSystem
{
PepperDashPortalSyncClient PortalSync;
HttpLogoServer LogoServer;
public ControlSystem()
: base()
{
Thread.MaxNumberOfUserThreads = 400;
Global.ControlSystem = this;
DeviceManager.Initialize(this);
}
/// <summary>
/// Git 'er goin'
/// </summary>
public override void InitializeSystem()
{
//CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Reloads configuration file",
//ConsoleAccessLevelEnum.AccessOperator);
//CrestronConsole.AddNewConsoleCommand(s => TearDown(), "ungo", "Unloads configuration file",
// ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
foreach (var tl in TieLineCollection.Default)
CrestronConsole.ConsoleCommandResponse(" {0}\r", tl);
},
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
GoWithLoad();
}
/// <summary>
/// Do it, yo
/// </summary>
public void GoWithLoad()
{
try
{
CrestronConsole.AddNewConsoleCommand(EnablePortalSync, "portalsync", "Loads Portal Sync",
ConsoleAccessLevelEnum.AccessOperator);
//PortalSync = new PepperDashPortalSyncClient();
Debug.Console(0, "Starting Essentials load from configuration");
var filesReady = SetupFilesystem();
if (filesReady)
{
Debug.Console(0, "Folder structure verified. Loading config...");
if (!ConfigReader.LoadConfig2())
return;
Load();
<<<<<<< HEAD
=======
>>>>>>> origin/feature/ecs-342-neil
Debug.Console(0, "Essentials load complete\r" +
"-------------------------------------------------------------");
}
else
{
Debug.Console(0,
"------------------------------------------------\r" +
"------------------------------------------------\r" +
"------------------------------------------------\r" +
"Essentials file structure setup completed.\r" +
"Please load config, sgd and ir files and\r" +
"restart program.\r" +
"------------------------------------------------\r" +
"------------------------------------------------\r" +
"------------------------------------------------");
}
}
catch (Exception e)
{
Debug.Console(0, "FATAL INITIALIZE ERROR. System is in an inconsistent state:\r{0}", e);
}
}
/// <summary>
/// Verifies filesystem is set up. IR, SGD, and program1 folders
/// </summary>
bool SetupFilesystem()
{
Debug.Console(0, "Verifying and/or creating folder structure");
var appNum = InitialParametersClass.ApplicationNumber;
var configDir = @"\NVRAM\Program" + appNum;
var configExists = Directory.Exists(configDir);
if (!configExists)
Directory.Create(configDir);
var irDir = string.Format(@"\NVRAM\Program{0}\ir", appNum);
if (!Directory.Exists(irDir))
Directory.Create(irDir);
var sgdDir = string.Format(@"\NVRAM\Program{0}\sgd", appNum);
if (!Directory.Exists(sgdDir))
Directory.Create(sgdDir);
return configExists;
}
public void EnablePortalSync(string s)
{
if (s.ToLower() == "enable")
{
CrestronConsole.ConsoleCommandResponse("Portal Sync features enabled");
PortalSync = new PepperDashPortalSyncClient();
}
}
public void TearDown()
{
Debug.Console(0, "Tearing down existing system");
DeviceManager.DeactivateAll();
TieLineCollection.Default.Clear();
foreach (var key in DeviceManager.GetDevices())
DeviceManager.RemoveDevice(key);
Debug.Console(0, "Tear down COMPLETE");
}
/// <summary>
///
/// </summary>
void Load()
{
LoadDevices();
LoadTieLines();
LoadRooms();
LoadLogoServer();
<<<<<<< HEAD
DeviceManager.ActivateAll();
=======
DeviceManager.ActivateAll();
>>>>>>> origin/feature/ecs-342-neil
}
/// <summary>
/// Reads all devices from config and adds them to DeviceManager
/// </summary>
public void LoadDevices()
{
foreach (var devConf in ConfigReader.ConfigObject.Devices)
{
try
{
Debug.Console(0, "Creating device '{0}'", devConf.Key);
// Skip this to prevent unnecessary warnings
if (devConf.Key == "processor")
continue;
// Try local factory first
var newDev = DeviceFactory.GetDevice(devConf);
// Then associated library factories
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf);
if (newDev != null)
DeviceManager.AddDevice(newDev);
else
Debug.Console(0, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
}
catch (Exception e)
{
Debug.Console(0, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e);
}
}
}
/// <summary>
/// Helper method to load tie lines. This should run after devices have loaded
/// </summary>
public void LoadTieLines()
{
// In the future, we can't necessarily just clear here because devices
// might be making their own internal sources/tie lines
var tlc = TieLineCollection.Default;
//tlc.Clear();
foreach (var tieLineConfig in ConfigReader.ConfigObject.TieLines)
{
var newTL = tieLineConfig.GetTieLine();
if (newTL != null)
tlc.Add(newTL);
}
}
/// <summary>
/// Reads all rooms from config and adds them to DeviceManager
/// </summary>
public void LoadRooms()
{
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
{
var room = roomConfig.GetRoomObject();
if (room != null)
{
if (room is EssentialsHuddleSpaceRoom)
{
DeviceManager.AddDevice(room);
Debug.Console(1, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1));
var cotija = DeviceManager.GetDeviceForKey("cotijaServer") as CotijaSystemController;
if (cotija != null)
{
cotija.CotijaRooms.Add(new CotijaEssentialsHuddleSpaceRoomBridge(cotija, room as EssentialsHuddleSpaceRoom));
}
}
else if (room is EssentialsHuddleVtc1Room)
{
DeviceManager.AddDevice(room);
Debug.Console(1, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1));
}
else
{
Debug.Console(1, "Room is NOT EssentialsHuddleSpaceRoom, attempting to add to DeviceManager w/o Fusion");
DeviceManager.AddDevice(room);
}
}
else
Debug.Console(0, "WARNING: Cannot create room from config, key '{0}'", roomConfig.Key);
}
}
/// <summary>
/// Fires up a logo server if not already running
/// </summary>
void LoadLogoServer()
{
try
{
LogoServer = new HttpLogoServer(8080, @"\html\logo");
}
catch (Exception)
{
Debug.Console(0, "NOTICE: Logo server cannot be started. Likely already running in another program");
}
}
}
}

View File

@@ -1208,14 +1208,23 @@ namespace PepperDash.Essentials.Fusion
{
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
FusionRoom.FusionAssetStateChange += new FusionAssetStateEventHandler(FusionRoom_FusionAssetStateChange);
// Build Occupancy Asset?
// Link sigs?
Room.SetRoomOccupancy(this);
//Room.SetRoomOccupancy(this as IOccupancyStatusProvider, 0);
}
void FusionRoom_FusionAssetStateChange(FusionBase device, FusionAssetStateEventArgs args)
{
if (args.EventId == FusionAssetEventId.RoomOccupiedReceivedEventId || args.EventId == FusionAssetEventId.RoomUnoccupiedReceivedEventId)
RoomIsOccupiedFeedback.FireUpdate();
}
/// <summary>
/// Sets up remote occupancy that will relay the occupancy status determined by local system devices to Fusion
/// </summary>

View File

@@ -75,9 +75,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\pepperdash-portal-sync\SspPortalSync\SspPortalSync\bin\PepperDashCorePortalSync.dll</HintPath>
</Reference>
<Reference Include="PepperDash_Core, Version=1.0.1.20241, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="PepperDash_Core, Version=1.0.3.27452, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\pepperdash-simplsharp-core\Pepperdash Core\CLZ Builds\PepperDash_Core.dll</HintPath>
<HintPath>..\..\Release Package\PepperDash_Core.dll</HintPath>
</Reference>
<Reference Include="PepperDash_Essentials_DM, Version=1.0.0.19343, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -134,11 +134,14 @@
<Compile Include="OTHER\Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs" />
<Compile Include="HttpApiHandler.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Room\Config\DDVC01RoomPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsPresentationPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsHuddleRoomPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsHuddleVtc1PropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsRoomEmergencyConfig.cs" />
<Compile Include="Room\Cotija\CotijaConfig.cs" />
<Compile Include="Room\Cotija\Interfaces.cs" />
<Compile Include="Room\Cotija\RoomBridges\CotijaBridgeBase.cs" />
<Compile Include="Room\Cotija\RoomBridges\CotijaDdvc01RoomBridge.cs" />
<Compile Include="Room\Cotija\RoomBridges\CotijaEssentialsHuddleSpaceRoomBridge.cs" />
<Compile Include="Room\Cotija\DeviceTypeInterfaces\IChannelExtensions.cs" />
@@ -193,6 +196,9 @@
<Compile Include="UI\SubpageReferenceListSourceItem.cs" />
<None Include="app.config" />
<None Include="Properties\ControlSystem.cfg" />
<EmbeddedResource Include="SGD\PepperDash Essentials iPad.sgd" />
<EmbeddedResource Include="SGD\PepperDash Essentials TSW-560.sgd" />
<EmbeddedResource Include="SGD\PepperDash Essentials TSW-760.sgd" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Essentials Core\PepperDashEssentialsBase\PepperDash_Essentials_Core.csproj">

View File

@@ -4,5 +4,5 @@
[assembly: AssemblyCompany("PepperDash Technology Corp")]
[assembly: AssemblyProduct("PepperDashEssentials")]
[assembly: AssemblyCopyright("Copyright © PepperDash Technology Corp 2017")]
[assembly: AssemblyVersion("1.0.17.*")]
[assembly: AssemblyVersion("1.0.36.*")]

View File

@@ -5,8 +5,8 @@
[assembly: AssemblyProduct("PepperDashEssentials")]
[assembly: AssemblyCopyright("Copyright © PepperDash Technology Corp 2017")]
<<<<<<< HEAD
[assembly: AssemblyVersion("1.0.8.*")]
[assembly: AssemblyVersion("1.0.31.*")]
=======
[assembly: AssemblyVersion("1.0.10.*")]
>>>>>>> development
[assembly: AssemblyVersion("1.0.33.*")]
>>>>>>> origin/feature/ecs-342-neil

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Room.Config
{
public class DDVC01RoomPropertiesConfig : EssentialsHuddleVtc1PropertiesConfig
{
public string RoomPhoneNumber { get; set; }
public string RoomURI { get; set; }
public List<DDVC01SpeedDial> SpeedDials { get; set; }
public List<string> VolumeSliderNames { get; set; }
}
public class DDVC01SpeedDial
{
public string Name { get; set; }
public string Number { get; set; }
}
}

View File

@@ -29,6 +29,10 @@ namespace PepperDash.Essentials.Room.Config
var disp = DeviceManager.GetDeviceForKey(props.DefaultDisplayKey) as IRoutingSinkWithSwitching;
var audio = DeviceManager.GetDeviceForKey(props.DefaultAudioKey) as IRoutingSinkNoSwitching;
var huddle = new EssentialsHuddleSpaceRoom(Key, Name, disp, audio, props);
if (props.Occupancy != null)
huddle.SetRoomOccupancy(DeviceManager.GetDeviceForKey(props.Occupancy.DeviceKey) as
PepperDash.Essentials.Devices.Common.Occupancy.IOccupancyStatusProvider, props.Occupancy.TimoutMinutes);
huddle.LogoUrl = props.Logo.GetUrl();
huddle.SourceListKey = props.SourceListKey;
huddle.DefaultSourceItem = props.DefaultSourceItem;
@@ -67,7 +71,8 @@ namespace PepperDash.Essentials.Room.Config
// Add Occupancy object from config
if (props.Occupancy != null)
rm.SetRoomOccupancy(DeviceManager.GetDeviceForKey(props.Occupancy.DeviceKey) as PepperDash.Essentials.Devices.Common.Occupancy.IOccupancyStatusProvider);
rm.SetRoomOccupancy(DeviceManager.GetDeviceForKey(props.Occupancy.DeviceKey) as
PepperDash.Essentials.Devices.Common.Occupancy.IOccupancyStatusProvider, props.Occupancy.TimoutMinutes);
rm.LogoUrl = props.Logo.GetUrl();
rm.SourceListKey = props.SourceListKey;
rm.DefaultSourceItem = props.DefaultSourceItem;
@@ -79,6 +84,10 @@ namespace PepperDash.Essentials.Room.Config
return rm;
}
else if (typeName == "ddvc01Bridge")
{
return new Device(Key, Name); // placeholder device that does nothing.
}
return null;
}
@@ -100,57 +109,69 @@ namespace PepperDash.Essentials.Room.Config
return null;
}
PepperDash.Essentials.Devices.Common.Microphones.MicrophonePrivacyController GetMicrophonePrivacy(EssentialsRoomPropertiesConfig props, EssentialsHuddleVtc1Room room)
{
var microphonePrivacy = props.MicrophonePrivacy;
if (microphonePrivacy != null)
{
// Get the MicrophonePrivacy device from the device manager
var mP = (DeviceManager.GetDeviceForKey(props.MicrophonePrivacy.DeviceKey) as PepperDash.Essentials.Devices.Common.Microphones.MicrophonePrivacyController);
// Set this room as the IPrivacy device
if (mP != null)
{
mP.SetPrivacyDevice(room);
/// <summary>
///
/// </summary>
/// <param name="props"></param>
/// <param name="room"></param>
/// <returns></returns>
PepperDash.Essentials.Devices.Common.Microphones.MicrophonePrivacyController GetMicrophonePrivacy(
EssentialsRoomPropertiesConfig props, EssentialsHuddleVtc1Room room)
{
var microphonePrivacy = props.MicrophonePrivacy;
if (microphonePrivacy == null)
{
Debug.Console(0, "ERROR: Cannot create microphone privacy with null properties");
return null;
}
// Get the MicrophonePrivacy device from the device manager
var mP = (DeviceManager.GetDeviceForKey(props.MicrophonePrivacy.DeviceKey) as
PepperDash.Essentials.Devices.Common.Microphones.MicrophonePrivacyController);
// Set this room as the IPrivacy device
if (mP == null)
{
Debug.Console(0, "ERROR: Selected device {0} is not MicrophonePrivacyController", props.MicrophonePrivacy.DeviceKey);
return null;
}
mP.SetPrivacyDevice(room);
var behaviour = props.MicrophonePrivacy.Behaviour.ToLower();
var behaviour = props.MicrophonePrivacy.Behaviour.ToLower();
if (behaviour != null)
{
if (behaviour == "trackroomstate")
{
// Tie LED enable to room power state
room.OnFeedback.OutputChange += (o, a) =>
{
if (room.OnFeedback.BoolValue)
mP.EnableLeds = true;
else
mP.EnableLeds = false;
};
if (behaviour == null)
{
Debug.Console(0, "WARNING: No behaviour defined for MicrophonePrivacyController");
return null;
}
if (behaviour == "trackroomstate")
{
// Tie LED enable to room power state
room.OnFeedback.OutputChange += (o, a) =>
{
if (room.OnFeedback.BoolValue)
mP.EnableLeds = true;
else
mP.EnableLeds = false;
};
mP.EnableLeds = room.OnFeedback.BoolValue;
}
else if (behaviour == "trackcallstate")
{
// Tie LED enable to room power state
room.InCallFeedback.OutputChange += (o, a) =>
{
if (room.InCallFeedback.BoolValue)
mP.EnableLeds = true;
else
mP.EnableLeds = false;
};
mP.EnableLeds = room.OnFeedback.BoolValue;
}
else if (behaviour == "trackcallstate")
{
// Tie LED enable to room power state
room.InCallFeedback.OutputChange += (o, a) =>
{
if (room.InCallFeedback.BoolValue)
mP.EnableLeds = true;
else
mP.EnableLeds = false;
};
mP.EnableLeds = room.InCallFeedback.BoolValue;
}
}
else
Debug.Console(0, "No behaviour defined for MicrophonePrivacyController");
mP.EnableLeds = room.InCallFeedback.BoolValue;
}
return mP;
}
}
return null;
}
return mP;
}
}
/// <summary>
@@ -171,6 +192,7 @@ namespace PepperDash.Essentials.Room.Config
public EssentialsLogoPropertiesConfig Logo { get; set; }
public EssentialsRoomTechConfig Tech { get; set; }
public EssentialsRoomVolumesConfig Volumes { get; set; }
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
}
public class EssentialsRoomMicrophonePrivacyConfig
@@ -239,6 +261,7 @@ namespace PepperDash.Essentials.Room.Config
public class EssentialsRoomOccSensorConfig
{
public string DeviceKey { get; set; }
public int TimoutMinutes { get; set; }
}
public class EssentialsRoomTechConfig

View File

@@ -19,7 +19,7 @@ namespace PepperDash.Essentials
{
GenericHttpSseClient SseClient;
CCriticalSection FileLock;
//CCriticalSection FileLock;
/// <summary>
/// Prevents post operations from stomping on each other and getting lost
@@ -44,7 +44,7 @@ namespace PepperDash.Essentials
string SystemUuid;
public List<CotijaEssentialsHuddleSpaceRoomBridge> CotijaRooms { get; private set; }
public List<CotijaBridgeBase> CotijaRooms { get; private set; }
long ButtonHeartbeatInterval = 1000;
@@ -60,7 +60,7 @@ namespace PepperDash.Essentials
Config = config;
Debug.Console(0, this, "Mobile UI controller initializing for server:{0}", config.ServerUrl);
CotijaRooms = new List<CotijaEssentialsHuddleSpaceRoomBridge>();
CotijaRooms = new List<CotijaBridgeBase>();
//CrestronConsole.AddNewConsoleCommand(s => RegisterSystemToServer(),
// "CotiInitializeHttpClient", "Initializes a new HTTP client connection to a specified URL", ConsoleAccessLevelEnum.AccessOperator);
@@ -153,34 +153,37 @@ namespace PepperDash.Essentials
/// <param name="url">URL of the server, including the port number, if not 80. Format: "serverUrlOrIp:port"</param>
void RegisterSystemToServer()
{
#warning THIS SHOULD NOT GO until the config is ready - in cases of config populated from elsewhere (DDVC)
try
{
string filePath = string.Format(@"\NVRAM\Program{0}\configurationFile.json", Global.ControlSystem.ProgramNumber);
string postBody = null;
var confObject = ConfigReader.ConfigObject;
string postBody = JsonConvert.SerializeObject(confObject);
SystemUuid = confObject.SystemUuid;
if (string.IsNullOrEmpty(filePath))
{
Debug.Console(0, this, "Error reading file. No path specified.");
return;
}
//if (string.IsNullOrEmpty(filePath))
//{
// Debug.Console(0, this, "Error reading file. No path specified.");
// return;
//}
FileLock = new CCriticalSection();
#warning NEIL I think we need to review this usage. Don't think it ever blocks
// FileLock = new CCriticalSection();
//#warning NEIL I think we need to review this usage. Don't think it ever blocks
if (FileLock.TryEnter())
{
Debug.Console(1, this, "Reading configuration file to extract system UUID...");
// if (FileLock.TryEnter())
// {
// Debug.Console(1, this, "Reading configuration file to extract system UUID...");
postBody = File.ReadToEnd(filePath, Encoding.ASCII);
// postBody = File.ReadToEnd(filePath, Encoding.ASCII);
Debug.Console(2, this, "{0}", postBody);
// Debug.Console(2, this, "{0}", postBody);
FileLock.Leave();
}
// FileLock.Leave();
// }
if (string.IsNullOrEmpty(postBody))
{
Debug.Console(1, "Post Body is null or empty");
Debug.Console(1, this, "ERROR: Config post body is empty. Cannot register with server.");
}
else
{
@@ -188,11 +191,9 @@ namespace PepperDash.Essentials
Client = new HttpClient();
Client.Verbose = true;
Client.KeepAlive = true;
SystemUuid = Essentials.ConfigReader.ConfigObject.SystemUuid;
string url = string.Format("http://{0}/api/system/join/{1}", Config.ServerUrl, SystemUuid);
Debug.Console(1, this, "Sending config to {0}", url);
string url = string.Format("http://{0}/api/system/join/{1}", Config.ServerUrl, SystemUuid);
Debug.Console(1, this, "Joining server at {0}", url);
HttpClientRequest request = new HttpClientRequest();
request.Url.Parse(url);
@@ -200,13 +201,13 @@ namespace PepperDash.Essentials
request.Header.SetHeaderValue("Content-Type", "application/json");
request.ContentString = postBody;
Client.DispatchAsync(request, PostConnectionCallback);
var err = Client.DispatchAsync(request, PostConnectionCallback);
}
}
catch (Exception e)
{
Debug.Console(0, this, "Error Initilizing Room: {0}", e);
Debug.Console(0, this, "ERROR: Initilizing Room: {0}", e);
}
}
@@ -316,6 +317,7 @@ namespace PepperDash.Essentials
/// <param name="err"></param>
void PostConnectionCallback(HttpClientResponse resp, HTTP_CALLBACK_ERROR err)
{
Debug.Console(1, this, "PostConnectionCallback err: {0}", err);
try
{
if (resp != null && resp.Code == 200)
@@ -326,11 +328,7 @@ namespace PepperDash.Essentials
ServerReconnectTimer = null;
}
#warning The SSE Client from a previous session might need to be killed...
//if (SseClient == null)
//{
ConnectSseClient(null);
//}
ConnectSseClient(null);
}
else
{

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Room.Cotija
{
public interface IDelayedConfiguration
{
event EventHandler<EventArgs> ConfigurationIsReady;
}
}

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials
{
/// <summary>
///
/// </summary>
public abstract class CotijaBridgeBase: Device
{
public CotijaSystemController Parent { get; private set; }
public CotijaBridgeBase(string key, string name)
: base(key, name)
{
}
/// <summary>
///
/// </summary>
/// <param name="parent"></param>
public void AddParent(CotijaSystemController parent)
{
Parent = parent;
}
}
}

View File

@@ -10,10 +10,13 @@ using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials.Room.Cotija
{
public class CotijaDdvc01RoomBridge : Device
public class CotijaDdvc01RoomBridge : CotijaBridgeBase, IDelayedConfiguration
{
public class BoolJoin
{
@@ -108,17 +111,28 @@ namespace PepperDash.Essentials.Room.Cotija
public const uint ConfigRoomURI = 505;
}
/// <summary>
/// Fires when the config is ready, to be used by the controller class to forward config to server
/// </summary>
public event EventHandler<EventArgs> ConfigurationIsReady;
public ThreeSeriesTcpIpEthernetIntersystemCommunications EISC { get; private set; }
CotijaSystemController Parent;
/// <summary>
///
/// </summary>
public bool ConfigIsLoaded { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="ipId"></param>
public CotijaDdvc01RoomBridge(string key, string name, uint ipId)
: base(key, name)
{
Key = key;
try
{
EISC = new ThreeSeriesTcpIpEthernetIntersystemCommunications(ipId, "127.0.0.2", Global.ControlSystem);
@@ -133,22 +147,23 @@ namespace PepperDash.Essentials.Room.Cotija
}
/// <summary>
/// Finish wiring up everything after all devices are created
/// Finish wiring up everything after all devices are created. The base class will hunt down the related
/// parent controller and link them up.
/// </summary>
/// <returns></returns>
public override bool CustomActivate()
{
Parent = DeviceManager.AllDevices.FirstOrDefault(d => d is CotijaSystemController) as CotijaSystemController;
if (Parent == null)
{
Debug.Console(0, this, "ERROR: Cannot build CotijaDdvc01RoomBridge. System controller not present");
return false;
}
SetupFunctions();
SetupFeedbacks();
EISC.SigChange += EISC_SigChange;
EISC.OnlineStatusChange += (o, a) =>
{
if (a.DeviceOnLine)
LoadConfigValues();
};
// load config if it's already there
if (EISC.IsOnline) // || EISC.BooleanInput[BoolJoin.ConfigIsReady].BoolValue)
LoadConfigValues();
return base.CustomActivate();
}
@@ -234,8 +249,6 @@ namespace PepperDash.Essentials.Room.Cotija
// Config things
EISC.SetSigTrueAction(BoolJoin.ConfigIsReady, LoadConfigValues);
}
/// <summary>
@@ -243,7 +256,89 @@ namespace PepperDash.Essentials.Room.Cotija
/// </summary>
void LoadConfigValues()
{
Debug.Console(1, this, "Loading configuration from DDVC01 EISC bridge");
ConfigIsLoaded = false;
var co = ConfigReader.ConfigObject;
//Room
if (co.Rooms == null)
co.Rooms = new List<EssentialsRoomConfig>();
if (co.Rooms.Count == 0)
co.Rooms.Add(new EssentialsRoomConfig());
var rm = co.Rooms[0];
rm.Name = EISC.StringInput[501].StringValue;
rm.Key = "room1";
rm.Type = "ddvc01";
DDVC01RoomPropertiesConfig rmProps;
if (rm.Properties == null)
rmProps = new DDVC01RoomPropertiesConfig();
else
rmProps = JsonConvert.DeserializeObject<DDVC01RoomPropertiesConfig>(rm.Properties.ToString());
rmProps.Help = new EssentialsHelpPropertiesConfig();
rmProps.Help.Message = EISC.StringInput[502].StringValue;
rmProps.Help.CallButtonText = EISC.StringInput[503].StringValue;
rmProps.RoomPhoneNumber = EISC.StringInput[504].StringValue;
rmProps.RoomURI = EISC.StringInput[505].StringValue;
rmProps.SpeedDials = new List<DDVC01SpeedDial>();
// add speed dials as long as there are more - up to 4
for (uint i = 512; i <= 519; i = i + 2)
{
var num = EISC.StringInput[i].StringValue;
if (string.IsNullOrEmpty(num))
break;
var name = EISC.StringInput[i + 1].StringValue;
rmProps.SpeedDials.Add(new DDVC01SpeedDial { Number = num, Name = name});
}
// volume control names
var volCount = EISC.UShortInput[701].UShortValue;
rmProps.VolumeSliderNames = new List<string>();
for(uint i = 701; i <= 700 + volCount; i++)
{
rmProps.VolumeSliderNames.Add(EISC.StringInput[i].StringValue);
}
// There should be cotija devices in here, I think...
if(co.Devices == null)
co.Devices = new List<DeviceConfig>();
// Source list! This might be brutal!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
rmProps.SourceListKey = "default";
co.SourceLists = new Dictionary<string,Dictionary<string,SourceListItem>>();
var newSl = new Dictionary<string, SourceListItem>();
// add sources...
for (uint i = 0; i<= 19; i++)
{
var name = EISC.StringInput[601 + i].StringValue;
if(string.IsNullOrEmpty(name))
break;
var icon = EISC.StringInput[651 + i].StringValue;
var key = EISC.StringInput[671 + i].StringValue;
var type = EISC.StringInput[701 + i].StringValue;
var newSLI = new SourceListItem{
Icon = icon,
Name = name,
Order = (int)i + 1,
SourceKey = key,
};
// add dev to devices list
var devConf = new DeviceConfig {
Group = "ddvc01",
Key = key,
Name = name,
Type = type
};
co.Devices.Add(devConf);
}
co.SourceLists.Add("default", newSl);
Debug.Console(0, this, "******* CONFIG FROM DDVC: \r{0}", JsonConvert.SerializeObject(ConfigReader.ConfigObject, Formatting.Indented));
ConfigIsLoaded = true;
// send config changed status???

View File

@@ -10,15 +10,19 @@ using PepperDash.Essentials.Room.Cotija;
namespace PepperDash.Essentials
{
public class CotijaEssentialsHuddleSpaceRoomBridge
public class CotijaEssentialsHuddleSpaceRoomBridge : CotijaBridgeBase
{
CotijaSystemController Parent;
public EssentialsHuddleSpaceRoom Room { get; private set; }
public CotijaEssentialsHuddleSpaceRoomBridge(CotijaSystemController parent, EssentialsHuddleSpaceRoom room)
/// <summary>
///
/// </summary>
/// <param name="parent"></param>
/// <param name="room"></param>
public CotijaEssentialsHuddleSpaceRoomBridge(EssentialsHuddleSpaceRoom room):
base("cotijaController", "Cotija Controller")
{
Parent = parent;
Room = room;
// we add actions to the messaging system with a path, and a related action. Custom action

View File

@@ -317,7 +317,9 @@ namespace PepperDash.Essentials
}
// Set volume control on room, using default if non provided
// Set volume control, using default if non provided
IBasicVolumeControls volDev = null;
// Handle special cases for volume control
if (string.IsNullOrEmpty(item.VolumeControlKey)
@@ -334,7 +336,27 @@ namespace PepperDash.Essentials
else if (dev is IHasVolumeDevice)
volDev = (dev as IHasVolumeDevice).VolumeDevice;
}
CurrentVolumeControls = volDev;
if (volDev != CurrentVolumeControls)
{
// zero the volume on the device we are leaving.
// Set the volume to default on device we are entering
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
{
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
SavedVolumeLevels[vd] = (uint)vd.VolumeLevelFeedback.IntValue;
vd.SetVolume(0);
}
CurrentVolumeControls = volDev;
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
{
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
vd.SetVolume(vol);
}
}
// store the name and UI info for routes
if (item.SourceKey == "$off")

View File

@@ -122,7 +122,8 @@ namespace PepperDash.Essentials
string LastSourceKey;
/// <summary>
///
/// Sets the volume control device, and attaches/removes InUseTrackers with "audio"
/// tag to device.
/// </summary>
public IBasicVolumeControls CurrentVolumeControls
{
@@ -211,6 +212,7 @@ namespace PepperDash.Essentials
else if (defaultAudio is IHasVolumeDevice)
DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
CurrentVolumeControls = DefaultVolumeControls;
var disp = DefaultDisplay as DisplayBase;
if (disp != null)
@@ -270,7 +272,7 @@ namespace PepperDash.Essentials
RunDefaultPresentRoute();
CrestronEnvironment.Sleep(200);
CrestronEnvironment.Sleep(1000);
RunRouteAction("roomOff");
}
@@ -280,7 +282,7 @@ namespace PepperDash.Essentials
/// </summary>
public bool RunDefaultPresentRoute()
{
if (DefaultSourceItem != null)
//if (DefaultSourceItem != null)
RunRouteAction(DefaultSourceItem);
return DefaultSourceItem != null;
}
@@ -372,6 +374,52 @@ namespace PepperDash.Essentials
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
}
// See if this can be moved into common, base-class method -------------
// Set volume control, using default if non provided
IBasicVolumeControls volDev = null;
// Handle special cases for volume control
if (string.IsNullOrEmpty(item.VolumeControlKey)
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
volDev = DefaultVolumeControls;
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
volDev = DefaultDisplay as IBasicVolumeControls;
// Or a specific device, probably rarely used.
else
{
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
if (dev is IBasicVolumeControls)
volDev = dev as IBasicVolumeControls;
else if (dev is IHasVolumeDevice)
volDev = (dev as IHasVolumeDevice).VolumeDevice;
}
if (volDev != CurrentVolumeControls)
{
// zero the volume on the device we are leaving.
// Set the volume to default on device we are entering
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
{
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
SavedVolumeLevels[vd] = (uint)vd.VolumeLevelFeedback.IntValue;
vd.SetVolume(0);
}
CurrentVolumeControls = volDev;
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
{
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
vd.SetVolume(vol);
}
}
// -----------------------------------------------------------------------
// store the name and UI info for routes
if (item.SourceKey == "$off")
{

View File

@@ -74,6 +74,13 @@ namespace PepperDash.Essentials
/// </summary>
protected abstract Func<bool> OnFeedbackFunc { get; }
protected Dictionary<IBasicVolumeWithFeedback, uint> SavedVolumeLevels = new Dictionary<IBasicVolumeWithFeedback, uint>();
/// <summary>
/// When volume control devices change, should we zero the one that we are leaving?
/// </summary>
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; private set; }
/// <summary>
///
/// </summary>
@@ -123,8 +130,11 @@ namespace PepperDash.Essentials
StartRoomVacancyTimer(eVacancyMode.InShutdownWarning);
break;
case eVacancyMode.InShutdownWarning:
StartShutdown(eShutdownType.Vacancy);
break;
{
StartShutdown(eShutdownType.Vacancy);
Debug.Console(0, this, "Shutting Down due to vacancy.");
break;
}
default:
break;
}
@@ -154,6 +164,8 @@ namespace PepperDash.Essentials
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownSeconds;
VacancyMode = mode;
RoomVacancyShutdownTimer.Start();
Debug.Console(0, this, "Vacancy Timer Started.");
}
/// <summary>
@@ -181,12 +193,21 @@ namespace PepperDash.Essentials
/// Sets the object to be used as the IOccupancyStatusProvider for the room. Can be an Occupancy Aggregator or a specific device
/// </summary>
/// <param name="statusProvider"></param>
public void SetRoomOccupancy(IOccupancyStatusProvider statusProvider)
public void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes)
{
if (statusProvider == null)
{
Debug.Console(0, this, "ERROR: Occupancy sensor device is null");
return;
}
// If status provider is fusion, set flag to remote
if (statusProvider is PepperDash.Essentials.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase)
OccupancyStatusProviderIsRemote = true;
if(timeoutMinutes > 0)
RoomVacancyShutdownSeconds = timeoutMinutes * 60;
RoomOccupancy = statusProvider;
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += new EventHandler<EventArgs>(RoomIsOccupiedFeedback_OutputChange);
@@ -194,19 +215,26 @@ namespace PepperDash.Essentials
void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
{
if ((sender as IOccupancyStatusProvider).RoomIsOccupiedFeedback.BoolValue == false)
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
{
Debug.Console(1, this, "Notice: Vacancy Detected");
// Trigger the timer when the room is vacant
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
}
else
{
Debug.Console(1, this, "Notice: Occupancy Detected");
// Reset the timer when the room is occupied
if(RoomVacancyShutdownTimer.IsRunningFeedback.BoolValue)
RoomVacancyShutdownTimer.Cancel();
}
}
//void SwapVolumeDevices(IBasicVolumeControls currentDevice, IBasicVolumeControls newDevice)
//{
//}
/// <summary>
/// Executes when RoomVacancyShutdownTimer expires. Used to trigger specific room actions as needed. Must nullify the timer object when executed
/// </summary>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -87,8 +87,8 @@ namespace PepperDash.Essentials
+= ExtenderSystemReservedSigs_DeviceExtenderSigChange;
}
new CTimer(o =>
{
//CrestronInvoke.BeginInvoke(o =>
// {
var regSuccess = Panel.Register();
if (regSuccess != eDeviceRegistrationUnRegistrationResponse.Success)
Debug.Console(0, this, "WARNING: Registration failed. Continuing, but panel may not function: {0}", regSuccess);
@@ -177,7 +177,7 @@ namespace PepperDash.Essentials
{
Debug.Console(0, this, "ERROR: Cannot load AvFunctionsDriver for room '{0}'", props.DefaultRoomKey);
}
}, 0);
//}, 0);
});
}

View File

@@ -318,8 +318,6 @@ namespace PepperDash.Essentials
(CurrentRoom.DefaultDisplay as IPower).PowerToggle();
});
//TriList.SetSigFalseAction(UIBoolJoin.HeaderCallStatusButtonPress, ShowActiveCallsList );
SetupNextMeetingTimer();
base.Show();
@@ -635,6 +633,7 @@ namespace PepperDash.Essentials
/// </summary>
void ActivityShareButtonPressed()
{
SetupSourceList();
if (VCDriver.IsVisible)
VCDriver.Hide();
HideNextMeetingPopup();
@@ -644,9 +643,12 @@ namespace PepperDash.Essentials
// Run default source when room is off and share is pressed
if (!CurrentRoom.OnFeedback.BoolValue)
{
// If there's no default, show UI elements
if(!CurrentRoom.RunDefaultPresentRoute())
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
if (!CurrentRoom.OnFeedback.BoolValue)
{
// If there's no default, show UI elements
if (!CurrentRoom.RunDefaultPresentRoute())
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
}
}
else // room is on show what's active or select a source if nothing is yet active
{
@@ -903,6 +905,7 @@ namespace PepperDash.Essentials
_CurrentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange;
_CurrentRoom.IsWarmingUpFeedback.OutputChange -= CurrentRoom_IsWarmingFeedback_OutputChange;
_CurrentRoom.IsCoolingDownFeedback.OutputChange -= CurrentRoom_IsCoolingDownFeedback_OutputChange;
_CurrentRoom.InCallFeedback.OutputChange -= CurrentRoom_InCallFeedback_OutputChange;
}
_CurrentRoom = room;
@@ -910,27 +913,9 @@ namespace PepperDash.Essentials
if (_CurrentRoom != null)
{
// get the source list config and set up the source list
var config = ConfigReader.ConfigObject.SourceLists;
if (config.ContainsKey(_CurrentRoom.SourceListKey))
{
var srcList = config[_CurrentRoom.SourceListKey].OrderBy(kv => kv.Value.Order);
// Setup sources list
uint i = 1; // counter for UI list
foreach (var kvp in srcList)
{
var srcConfig = kvp.Value;
if (!srcConfig.IncludeInSourceList) // Skip sources marked this way
continue;
SetupSourceList();
var routeKey = kvp.Key;
var item = new SubpageReferenceListSourceItem(i++, SourceStagingSrl, srcConfig,
b => { if (!b) UiSelectSource(routeKey); });
SourceStagingSrl.AddItem(item); // add to the SRL
item.RegisterForSourceChange(_CurrentRoom);
}
SourceStagingSrl.Count = (ushort)(i - 1);
}
// Name and logo
TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = _CurrentRoom.Name;
ShowLogo();
@@ -945,6 +930,8 @@ namespace PepperDash.Essentials
CurrentRoom_SyncOnFeedback();
_CurrentRoom.IsWarmingUpFeedback.OutputChange += CurrentRoom_IsWarmingFeedback_OutputChange;
_CurrentRoom.IsCoolingDownFeedback.OutputChange += CurrentRoom_IsCoolingDownFeedback_OutputChange;
_CurrentRoom.InCallFeedback.OutputChange += CurrentRoom_InCallFeedback_OutputChange;
_CurrentRoom.CurrentVolumeDeviceChange += CurrentRoom_CurrentAudioDeviceChange;
RefreshAudioDeviceConnections();
@@ -973,6 +960,62 @@ namespace PepperDash.Essentials
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CurrentRoom_InCallFeedback_OutputChange(object sender, EventArgs e)
{
var inCall = CurrentRoom.InCallFeedback.BoolValue;
if (inCall)
{
// Check if transitioning to in call - and non-sharable source is in use
if (CurrentRoom.CurrentSourceInfo.DisableCodecSharing)
{
Debug.Console(1, CurrentRoom, "Transitioning to in-call, cancelling non-sharable source");
CurrentRoom.RunRouteAction("codecOsd");
}
}
SetupSourceList();
}
/// <summary>
///
/// </summary>
void SetupSourceList()
{
var inCall = CurrentRoom.InCallFeedback.BoolValue;
var config = ConfigReader.ConfigObject.SourceLists;
if (config.ContainsKey(_CurrentRoom.SourceListKey))
{
var srcList = config[_CurrentRoom.SourceListKey].OrderBy(kv => kv.Value.Order);
// Setup sources list
uint i = 1; // counter for UI list
foreach (var kvp in srcList)
{
var srcConfig = kvp.Value;
// Skip sources marked as not included, and filter list of non-sharable sources when in call
// or on share screen
if (!srcConfig.IncludeInSourceList || (inCall && srcConfig.DisableCodecSharing)
|| this.CurrentMode == UiDisplayMode.Call && srcConfig.DisableCodecSharing)
{
continue;
}
var routeKey = kvp.Key;
var item = new SubpageReferenceListSourceItem(i++, SourceStagingSrl, srcConfig,
b => { if (!b) UiSelectSource(routeKey); });
SourceStagingSrl.AddItem(item); // add to the SRL
item.RegisterForSourceChange(_CurrentRoom);
}
SourceStagingSrl.Count = (ushort)(i - 1);
}
}
/// <summary>
/// If the schedule changes, this event will fire
/// </summary>

View File

@@ -79,9 +79,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
StringBuilder SearchStringBuilder = new StringBuilder();
BoolFeedback SearchStringBackspaceVisibleFeedback;
#warning WHAT THE HELL happened to this?????
BoolFeedback LayoutButtonEnableFeedback;
ModalDialog IncomingCallModal;
eKeypadMode KeypadMode;
@@ -197,13 +194,16 @@ namespace PepperDash.Essentials.UIDrivers.VC
void Codec_IsReady()
{
string roomNumberSipUri = "";
#warning FIX PHONE FORMATTING TO ONLY SHOW WHEN APPROPRIATE - TALK TO NEIL
if (!string.IsNullOrEmpty(Codec.CodecInfo.SipUri)) // If both values are present, format the string with a pipe divider
roomNumberSipUri = string.Format("{0} | {1}", GetFormattedPhoneNumber(Codec.CodecInfo.SipPhoneNumber), Codec.CodecInfo.SipUri);
else // If only one value present, just show the phone number
roomNumberSipUri = Codec.CodecInfo.SipPhoneNumber;
if(string.IsNullOrEmpty(roomNumberSipUri))
roomNumberSipUri = string.Format("{0} | {1}", GetFormattedPhoneNumber(Codec.CodecInfo.E164Alias), Codec.CodecInfo.H323Id);
roomNumberSipUri = string.Format("{0} | {1}", Codec.CodecInfo.E164Alias, Codec.CodecInfo.H323Id);
TriList.SetString(UIStringJoin.RoomPhoneText, roomNumberSipUri);