diff --git a/Essentials Core/PepperDashEssentialsBase/Display/MockDisplay.cs b/Essentials Core/PepperDashEssentialsBase/Display/MockDisplay.cs
index 7e6708da..bffea411 100644
--- a/Essentials Core/PepperDashEssentialsBase/Display/MockDisplay.cs
+++ b/Essentials Core/PepperDashEssentialsBase/Display/MockDisplay.cs
@@ -1,157 +1,167 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
-using Crestron.SimplSharpPro;
-using Crestron.SimplSharpPro.DM;
-using Crestron.SimplSharpPro.DM.Endpoints;
-using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
-
-using PepperDash.Core;
-using PepperDash.Essentials.Core.Routing;
-
-
-namespace PepperDash.Essentials.Core
-{
- ///
- ///
- ///
- public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback
-
- {
- public RoutingInputPort HdmiIn1 { get; private set; }
- public RoutingInputPort HdmiIn2 { get; private set; }
- public RoutingInputPort HdmiIn3 { get; private set; }
- public RoutingInputPort ComponentIn1 { get; private set; }
- public RoutingInputPort VgaIn1 { get; private set; }
-
- bool _PowerIsOn;
- bool _IsWarmingUp;
- bool _IsCoolingDown;
-
- protected override Func PowerIsOnFeedbackFunc { get { return () => _PowerIsOn; } }
- protected override Func IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
- protected override Func IsWarmingUpFeedbackFunc { get { return () => _IsWarmingUp; } }
-
- ushort _FakeVolumeLevel = 31768;
- bool _IsMuted;
-
- public MockDisplay(string key, string name)
- : base(key, name)
- {
- HdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo,
- eRoutingPortConnectionType.Hdmi, null, this);
- HdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo,
- eRoutingPortConnectionType.Hdmi, null, this);
- HdmiIn3 = new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo,
- eRoutingPortConnectionType.Hdmi, null, this);
- ComponentIn1 = new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.Video,
- eRoutingPortConnectionType.Component, null, this);
- VgaIn1 = new RoutingInputPort(RoutingPortNames.VgaIn, eRoutingSignalType.Video,
- eRoutingPortConnectionType.Composite, null, this);
- InputPorts.AddRange(new[] { HdmiIn1, HdmiIn2, HdmiIn3, ComponentIn1, VgaIn1 });
-
- VolumeLevelFeedback = new IntFeedback(() => { return _FakeVolumeLevel; });
- MuteFeedback = new BoolFeedback(CommonBoolCue.MuteOn, () => _IsMuted);
- }
-
- public override void PowerOn()
- {
- if (!PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
- {
- _IsWarmingUp = true;
- IsWarmingUpFeedback.FireUpdate();
- // Fake power-up cycle
- WarmupTimer = new CTimer(o =>
- {
- _IsWarmingUp = false;
- _PowerIsOn = true;
- IsWarmingUpFeedback.FireUpdate();
- PowerIsOnFeedback.FireUpdate();
- }, WarmupTime);
- }
- }
-
- public override void PowerOff()
- {
- // If a display has unreliable-power off feedback, just override this and
- // remove this check.
- if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
- {
- _IsCoolingDown = true;
- _PowerIsOn = false;
- PowerIsOnFeedback.FireUpdate();
- IsCoolingDownFeedback.FireUpdate();
- // Fake cool-down cycle
- CooldownTimer = new CTimer(o =>
- {
- Debug.Console(2, this, "Cooldown timer ending");
- _IsCoolingDown = false;
- IsCoolingDownFeedback.FireUpdate();
- }, CooldownTime);
- }
- }
-
- public override void PowerToggle()
- {
- if (PowerIsOnFeedback.BoolValue && !IsWarmingUpFeedback.BoolValue)
- PowerOff();
- else if (!PowerIsOnFeedback.BoolValue && !IsCoolingDownFeedback.BoolValue)
- PowerOn();
- }
-
- public override void ExecuteSwitch(object selector)
- {
- Debug.Console(2, this, "ExecuteSwitch: {0}", selector);
- }
-
-
-
- #region IBasicVolumeWithFeedback Members
-
- public IntFeedback VolumeLevelFeedback { get; private set; }
-
- public void SetVolume(ushort level)
- {
- _FakeVolumeLevel = level;
- VolumeLevelFeedback.FireUpdate();
- }
-
- public void MuteOn()
- {
- _IsMuted = true;
- MuteFeedback.FireUpdate();
- }
-
- public void MuteOff()
- {
- _IsMuted = false;
- MuteFeedback.FireUpdate();
- }
-
- public BoolFeedback MuteFeedback { get; private set; }
-
- #endregion
-
- #region IBasicVolumeControls Members
-
- public void VolumeUp(bool pressRelease)
- {
- Debug.Console(0, this, "Volume Down {0}", pressRelease);
- }
-
- public void VolumeDown(bool pressRelease)
- {
- Debug.Console(0, this, "Volume Up {0}", pressRelease);
- }
-
- public void MuteToggle()
- {
- _IsMuted = !_IsMuted;
- MuteFeedback.FireUpdate();
- }
-
- #endregion
- }
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro;
+using Crestron.SimplSharpPro.DM;
+using Crestron.SimplSharpPro.DM.Endpoints;
+using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Core.Routing;
+
+
+namespace PepperDash.Essentials.Core
+{
+ ///
+ ///
+ ///
+ public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback
+
+ {
+ public RoutingInputPort HdmiIn1 { get; private set; }
+ public RoutingInputPort HdmiIn2 { get; private set; }
+ public RoutingInputPort HdmiIn3 { get; private set; }
+ public RoutingInputPort ComponentIn1 { get; private set; }
+ public RoutingInputPort VgaIn1 { get; private set; }
+
+ bool _PowerIsOn;
+ bool _IsWarmingUp;
+ bool _IsCoolingDown;
+
+ protected override Func PowerIsOnFeedbackFunc { get { return () => _PowerIsOn; } }
+ protected override Func IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
+ protected override Func IsWarmingUpFeedbackFunc { get { return () => _IsWarmingUp; } }
+
+ ushort _FakeVolumeLevel = 31768;
+ bool _IsMuted;
+
+ public MockDisplay(string key, string name)
+ : base(key, name)
+ {
+ HdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo,
+ eRoutingPortConnectionType.Hdmi, null, this);
+ HdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo,
+ eRoutingPortConnectionType.Hdmi, null, this);
+ HdmiIn3 = new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo,
+ eRoutingPortConnectionType.Hdmi, null, this);
+ ComponentIn1 = new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.Video,
+ eRoutingPortConnectionType.Component, null, this);
+ VgaIn1 = new RoutingInputPort(RoutingPortNames.VgaIn, eRoutingSignalType.Video,
+ eRoutingPortConnectionType.Composite, null, this);
+ InputPorts.AddRange(new[] { HdmiIn1, HdmiIn2, HdmiIn3, ComponentIn1, VgaIn1 });
+
+ VolumeLevelFeedback = new IntFeedback(() => { return _FakeVolumeLevel; });
+ MuteFeedback = new BoolFeedback(CommonBoolCue.MuteOn, () => _IsMuted);
+ }
+
+ public override void PowerOn()
+ {
+ if (!PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
+ {
+ _IsWarmingUp = true;
+ IsWarmingUpFeedback.FireUpdate();
+ // Fake power-up cycle
+ WarmupTimer = new CTimer(o =>
+ {
+ _IsWarmingUp = false;
+ _PowerIsOn = true;
+ IsWarmingUpFeedback.FireUpdate();
+ PowerIsOnFeedback.FireUpdate();
+ }, WarmupTime);
+ }
+ }
+
+ public override void PowerOff()
+ {
+ // If a display has unreliable-power off feedback, just override this and
+ // remove this check.
+ if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
+ {
+ _IsCoolingDown = true;
+ _PowerIsOn = false;
+ PowerIsOnFeedback.FireUpdate();
+ IsCoolingDownFeedback.FireUpdate();
+ // Fake cool-down cycle
+ CooldownTimer = new CTimer(o =>
+ {
+ Debug.Console(2, this, "Cooldown timer ending");
+ _IsCoolingDown = false;
+ IsCoolingDownFeedback.FireUpdate();
+ }, CooldownTime);
+ }
+ }
+
+ public override void PowerToggle()
+ {
+ if (PowerIsOnFeedback.BoolValue && !IsWarmingUpFeedback.BoolValue)
+ PowerOff();
+ else if (!PowerIsOnFeedback.BoolValue && !IsCoolingDownFeedback.BoolValue)
+ PowerOn();
+ }
+
+ public override void ExecuteSwitch(object selector)
+ {
+ Debug.Console(2, this, "ExecuteSwitch: {0}", selector);
+ }
+
+
+
+ #region IBasicVolumeWithFeedback Members
+
+ public IntFeedback VolumeLevelFeedback { get; private set; }
+
+ public void SetVolume(ushort level)
+ {
+ _FakeVolumeLevel = level;
+ VolumeLevelFeedback.FireUpdate();
+ }
+
+ public void MuteOn()
+ {
+ _IsMuted = true;
+ MuteFeedback.FireUpdate();
+ }
+
+ public void MuteOff()
+ {
+ _IsMuted = false;
+ MuteFeedback.FireUpdate();
+ }
+
+ public BoolFeedback MuteFeedback { get; private set; }
+
+ #endregion
+
+ #region IBasicVolumeControls Members
+
+ public void VolumeUp(bool pressRelease)
+ {
+ Debug.Console(2, this, "Volume Down {0}", pressRelease);
+ if (pressRelease)
+ {
+ var newLevel = _FakeVolumeLevel + 655;
+ SetVolume((ushort)newLevel);
+ }
+ }
+
+ public void VolumeDown(bool pressRelease)
+ {
+ Debug.Console(2, this, "Volume Up {0}", pressRelease);
+ if (pressRelease)
+ {
+ var newLevel = _FakeVolumeLevel - 655;
+ SetVolume((ushort)newLevel);
+ }
+ }
+
+ public void MuteToggle()
+ {
+ _IsMuted = !_IsMuted;
+ MuteFeedback.FireUpdate();
+ }
+
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.projectinfo b/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.projectinfo
index aedc307d..9fdf18f4 100644
Binary files a/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.projectinfo and b/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.projectinfo differ
diff --git a/Essentials DM/Essentials_DM/Essentials_DM.projectinfo b/Essentials DM/Essentials_DM/Essentials_DM.projectinfo
index 0c8e39d2..3811ad6a 100644
Binary files a/Essentials DM/Essentials_DM/Essentials_DM.projectinfo and b/Essentials DM/Essentials_DM/Essentials_DM.projectinfo differ
diff --git a/Essentials Devices Common/Essentials Devices Common/Display/NECPSXMDisplay.cs b/Essentials Devices Common/Essentials Devices Common/Display/NECPSXMDisplay.cs
index e699563c..bdf2fdf7 100644
--- a/Essentials Devices Common/Essentials Devices Common/Display/NECPSXMDisplay.cs
+++ b/Essentials Devices Common/Essentials Devices Common/Display/NECPSXMDisplay.cs
@@ -338,15 +338,15 @@ namespace PepperDash.Essentials.Devices.Displays
public void VolumeDown(bool pressRelease)
{
- throw new NotImplementedException();
-#warning need incrementer for these
- //Send(VolumeDownCmd);
+ //throw new NotImplementedException();
+//#warning need incrementer for these
+ SetVolume(_VolumeLevel++);
}
public void VolumeUp(bool pressRelease)
{
- throw new NotImplementedException();
- //Send(VolumeUpCmd);
+ //throw new NotImplementedException();
+ SetVolume(_VolumeLevel--);
}
#endregion
diff --git a/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.projectinfo b/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.projectinfo
index 814b9dc6..f4662abf 100644
Binary files a/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.projectinfo and b/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.projectinfo differ
diff --git a/Essentials/PepperDashEssentials/Config/DeviceFactory.cs b/Essentials/PepperDashEssentials/Config/DeviceFactory.cs
index 0a3bc4f6..d87e41b7 100644
--- a/Essentials/PepperDashEssentials/Config/DeviceFactory.cs
+++ b/Essentials/PepperDashEssentials/Config/DeviceFactory.cs
@@ -1,68 +1,73 @@
-using System;
-using System.Collections.Generic;
-using Crestron.SimplSharp;
-using Crestron.SimplSharp.CrestronIO;
-using Crestron.SimplSharpPro;
-
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using PepperDash.Core;
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.Config;
-
-namespace PepperDash.Essentials
-{
- public class DeviceFactory
- {
- public static IKeyed GetDevice(DeviceConfig dc)
- {
- var key = dc.Key;
- var name = dc.Name;
- var type = dc.Type;
- var properties = dc.Properties;
-
- var typeName = dc.Type.ToLower();
-
- if (typeName == "amplifier")
- {
- return new Amplifier(dc.Key, dc.Name);
- }
- else if (dc.Group.ToLower() == "touchpanel") // typeName.StartsWith("tsw"))
- {
- var comm = CommFactory.GetControlPropertiesConfig(dc);
-
- var props = JsonConvert.DeserializeObject(
- properties.ToString());
- return new EssentialsTouchpanelController(key, name, typeName, props, comm.IpIdInt);
- }
- else if (typeName == "mockdisplay")
- {
- return new MockDisplay(key, name);
- }
-
- // MOVE into something else???
- else if (typeName == "basicirdisplay")
- {
- var ir = IRPortHelper.GetIrPort(properties);
- if (ir != null)
- return new BasicIrDisplay(key, name, ir.Port, ir.FileName);
- }
-
- else if (typeName == "commmock")
- {
- var comm = CommFactory.CreateCommForDevice(dc);
- var props = JsonConvert.DeserializeObject(
- properties.ToString());
- return new ConsoleCommMockDevice(key, name, props, comm);
+using System;
+using System.Collections.Generic;
+using Crestron.SimplSharp;
+using Crestron.SimplSharp.CrestronIO;
+using Crestron.SimplSharpPro;
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Config;
+
+namespace PepperDash.Essentials
+{
+ public class DeviceFactory
+ {
+ public static IKeyed GetDevice(DeviceConfig dc)
+ {
+ var key = dc.Key;
+ var name = dc.Name;
+ var type = dc.Type;
+ var properties = dc.Properties;
+
+ var typeName = dc.Type.ToLower();
+
+ if (typeName == "amplifier")
+ {
+ return new Amplifier(dc.Key, dc.Name);
+ }
+ else if (dc.Group.ToLower() == "touchpanel") // typeName.StartsWith("tsw"))
+ {
+ var comm = CommFactory.GetControlPropertiesConfig(dc);
+
+ var props = JsonConvert.DeserializeObject(
+ properties.ToString());
+ return new EssentialsTouchpanelController(key, name, typeName, props, comm.IpIdInt);
+ }
+ else if (typeName == "mockdisplay")
+ {
+ return new MockDisplay(key, name);
+ }
+
+ else if (typeName == "generic")
+ {
+ return new Device(key, name);
+ }
+
+ // MOVE into something else???
+ else if (typeName == "basicirdisplay")
+ {
+ var ir = IRPortHelper.GetIrPort(properties);
+ if (ir != null)
+ return new BasicIrDisplay(key, name, ir.Port, ir.FileName);
+ }
+
+ else if (typeName == "commmock")
+ {
+ var comm = CommFactory.CreateCommForDevice(dc);
+ var props = JsonConvert.DeserializeObject(
+ properties.ToString());
+ return new ConsoleCommMockDevice(key, name, props, comm);
}
else if (typeName == "webserver")
{
var props = JsonConvert.DeserializeObject(properties.ToString());
return new CotijaSystemController(key, name, props);
- }
-
- return null;
- }
- }
-}
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/Essentials/PepperDashEssentials/ControlSystem.cs b/Essentials/PepperDashEssentials/ControlSystem.cs
index 4a270d62..6cba22e5 100644
--- a/Essentials/PepperDashEssentials/ControlSystem.cs
+++ b/Essentials/PepperDashEssentials/ControlSystem.cs
@@ -162,6 +162,8 @@ namespace PepperDash.Essentials
{
if (room is EssentialsHuddleSpaceRoom)
{
+ DeviceManager.AddDevice(room);
+
Debug.Console(1, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleSpaceFusionSystemController((EssentialsHuddleSpaceRoom)room, 0xf1));
diff --git a/Essentials/PepperDashEssentials/PepperDashEssentials.projectinfo b/Essentials/PepperDashEssentials/PepperDashEssentials.projectinfo
index b9a1020b..a3945a8e 100644
Binary files a/Essentials/PepperDashEssentials/PepperDashEssentials.projectinfo and b/Essentials/PepperDashEssentials/PepperDashEssentials.projectinfo differ
diff --git a/Essentials/PepperDashEssentials/Room/Cotija/CotijaRoomBridge.cs b/Essentials/PepperDashEssentials/Room/Cotija/CotijaRoomBridge.cs
new file mode 100644
index 00000000..570216f4
--- /dev/null
+++ b/Essentials/PepperDashEssentials/Room/Cotija/CotijaRoomBridge.cs
@@ -0,0 +1,226 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash.Essentials
+{
+ public class CotijaEssentialsHuddleSpaceRoomBridge
+ {
+ CotijaSystemController Parent;
+
+ public EssentialsHuddleSpaceRoom Room { get; private set; }
+
+ public CotijaEssentialsHuddleSpaceRoomBridge(CotijaSystemController parent, EssentialsHuddleSpaceRoom room)
+ {
+ Parent = parent;
+ Room = room;
+
+ // Source Changes and room off
+ Parent.AddAction(string.Format(@"/room/{0}/status",Room.Key), new Action(() => Room_RoomFullStatus(Room)));
+ Parent.AddAction(string.Format(@"/room/{0}/source", Room.Key), new Action(c => room.RunRouteAction(c.SourceSelect)));
+ Parent.AddAction(string.Format(@"/room/{0}/event/masterVolumeUpBtn", Room.Key), new Action(b => room.CurrentVolumeControls.VolumeUp(b)));
+ Parent.AddAction(string.Format(@"/room/{0}/event/masterVolumeDownBtn", Room.Key), new Action(b => room.CurrentVolumeControls.VolumeDown(b)));
+ Parent.AddAction(string.Format(@"/room/{0}/event/muteToggle", Room.Key), new Action(() => room.CurrentVolumeControls.MuteToggle()));
+
+ Room.CurrentSingleSourceChange += new SourceInfoChangeHandler(Room_CurrentSingleSourceChange);
+
+ Room.CurrentVolumeDeviceChange += new EventHandler(Room_CurrentVolumeDeviceChange);
+
+ Room.OnFeedback.OutputChange += new EventHandler(OnFeedback_OutputChange);
+
+ // Registers for initial volume events, if possible
+ var currentVolumeDevice = Room.CurrentVolumeControls;
+
+ if (currentVolumeDevice != null)
+ {
+ if (currentVolumeDevice is IBasicVolumeWithFeedback)
+ {
+ var newDev = currentVolumeDevice as IBasicVolumeWithFeedback;
+
+ newDev.MuteFeedback.OutputChange += new EventHandler(VolumeLevelFeedback_OutputChange);
+ newDev.VolumeLevelFeedback.OutputChange += new EventHandler(VolumeLevelFeedback_OutputChange);
+ }
+ }
+
+ }
+
+ void OnFeedback_OutputChange(object sender, EventArgs e)
+ {
+ /* Example message
+ * {
+ "type":"/room/status",
+ "content": {
+ "isOn": false
+ }
+ }
+ */
+
+ JObject roomStatus = new JObject();
+
+ roomStatus.Add("isOn", (sender as BoolFeedback).BoolValue);
+
+ JObject message = new JObject();
+
+ message.Add("type", "/room/status/");
+ message.Add("content", roomStatus);
+
+ Parent.PostToServer(Room, message);
+ }
+
+ void Room_CurrentVolumeDeviceChange(object sender, VolumeDeviceChangeEventArgs e)
+ {
+ if (e.OldDev is IBasicVolumeWithFeedback)
+ {
+ var oldDev = e.OldDev as IBasicVolumeWithFeedback;
+
+ oldDev.MuteFeedback.OutputChange -= VolumeLevelFeedback_OutputChange;
+ oldDev.VolumeLevelFeedback.OutputChange -= VolumeLevelFeedback_OutputChange;
+ }
+
+ if (e.NewDev is IBasicVolumeWithFeedback)
+ {
+ var newDev = e.NewDev as IBasicVolumeWithFeedback;
+
+ newDev.MuteFeedback.OutputChange += new EventHandler(VolumeLevelFeedback_OutputChange);
+ newDev.VolumeLevelFeedback.OutputChange += new EventHandler(VolumeLevelFeedback_OutputChange);
+ }
+ }
+
+ void VolumeLevelFeedback_OutputChange(object sender, EventArgs e)
+ {
+ /* Example message
+ * {
+ "type":"/room/status",
+ "content": {
+ "masterVolumeLevel": 12345,
+ "masterVolumeMuteState": false
+ }
+ }
+ */
+
+ var huddleRoom = Room as EssentialsHuddleSpaceRoom;
+
+ if(huddleRoom.CurrentVolumeControls is IBasicVolumeWithFeedback)
+ {
+ JObject roomStatus = new JObject();
+
+ if (huddleRoom.CurrentVolumeControls is IBasicVolumeWithFeedback)
+ {
+ var currentVolumeConstrols = huddleRoom.CurrentVolumeControls as IBasicVolumeWithFeedback;
+ roomStatus.Add("masterVolumeLevel", currentVolumeConstrols.VolumeLevelFeedback.IntValue);
+ roomStatus.Add("masterVolumeMuteState", currentVolumeConstrols.MuteFeedback.BoolValue);
+ }
+
+ JObject message = new JObject();
+
+ message.Add("type", "/room/status/");
+ message.Add("content", roomStatus);
+
+ Parent.PostToServer(Room, message);
+ }
+ }
+
+ void Room_CurrentSingleSourceChange(EssentialsRoomBase room, PepperDash.Essentials.Core.SourceListItem info, ChangeType type)
+ {
+ /* Example message
+ * {
+ "type":"/room/status",
+ "content": {
+ "selectedSourceKey": "off",
+ }
+ }
+ */
+
+ if (type != ChangeType.DidChange)
+ return;
+
+ JObject roomStatus = new JObject();
+
+ var huddleRoom = room as EssentialsHuddleSpaceRoom;
+ //roomStatus.Add("isOn", huddleRoom.OnFeedback.BoolValue);
+ roomStatus.Add("selectedSourceKey", huddleRoom.CurrentSourceInfoKey);
+
+ JObject message = new JObject();
+
+ message.Add("type", "/room/status/");
+ message.Add("content", roomStatus);
+
+ Parent.PostToServer(Room, message);
+ }
+
+ ///
+ /// Posts the full status of the room to the server
+ ///
+ ///
+ void Room_RoomFullStatus(EssentialsRoomBase room)
+ {
+ /* Example message
+ * {
+ "type":"/room/status",
+ "content": {
+ "selectedSourceKey": "off",
+ "isOn": false,
+ "masterVolumeLevel": 50,
+ "masterVolumeMuteState": false
+ }
+ }
+ */
+
+ JObject roomStatus = new JObject();
+
+ var huddleRoom = room as EssentialsHuddleSpaceRoom;
+ roomStatus.Add("isOn", huddleRoom.OnFeedback.BoolValue);
+ roomStatus.Add("selectedSourceKey", huddleRoom.CurrentSourceInfoKey);
+
+
+ if(huddleRoom.CurrentVolumeControls is IBasicVolumeWithFeedback)
+ {
+ var currentVolumeConstrols = huddleRoom.CurrentVolumeControls as IBasicVolumeWithFeedback;
+ roomStatus.Add("masterVolumeLevel", currentVolumeConstrols.VolumeLevelFeedback.IntValue);
+ roomStatus.Add("masterVolumeMuteState", currentVolumeConstrols.MuteFeedback.BoolValue);
+ }
+
+ JObject message = new JObject();
+
+ message.Add("type", "/room/status/");
+ message.Add("content", roomStatus);
+
+ Parent.PostToServer(Room, message);
+
+ }
+
+ }
+
+ public class SourceSelectMessageContent
+ {
+ public string Destination { get; set; }
+ public string SourceSelect { get; set; }
+ }
+
+ //public class PostMessage
+ //{
+ // [JsonProperty("type")]
+ // public string Type { get; set; }
+
+ // [JsonProperty("content")]
+ // public JToken Content { get; set; }
+ //}
+
+ //public class RoomStatusMessageContent
+ //{
+ // [JsonProperty("selectedSourceKey")]
+ // public string SelectedSourceKey { get; set; }
+ // [JsonProperty("isOn")]
+ // public bool? IsOn { get; set; }
+ // [JsonProperty("masterVolumeLevel")]
+ // public int? MasterVolumeLevel { get; set; }
+ // [JsonProperty("masterVolumeMuteState")]
+ // public bool? MasterVolumeMuteState { get; set; }
+ //}
+
+}
\ No newline at end of file
diff --git a/Essentials/PepperDashEssentials/Room/Cotija/CotijaSystemController.cs b/Essentials/PepperDashEssentials/Room/Cotija/CotijaSystemController.cs
index 7ac090f2..7ddffbd6 100644
--- a/Essentials/PepperDashEssentials/Room/Cotija/CotijaSystemController.cs
+++ b/Essentials/PepperDashEssentials/Room/Cotija/CotijaSystemController.cs
@@ -42,18 +42,33 @@ namespace PepperDash.Essentials
CotijaRooms = new List();
- CrestronConsole.AddNewConsoleCommand(ConnectSseClient, "InitializeHttpClient", "Initializes a new HTTP client connection to a specified URL", ConsoleAccessLevelEnum.AccessOperator);
+ CrestronConsole.AddNewConsoleCommand(RegisterSystemToServer, "InitializeHttpClient", "Initializes a new HTTP client connection to a specified URL", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(DisconnectSseClient, "CloseHttpClient", "Closes the active HTTP client", ConsoleAccessLevelEnum.AccessOperator);
AddPostActivationAction(() => RegisterSystemToServer(null));
}
+ ///
+ /// Adds an action to the dictionary
+ ///
+ /// The path of the API command
+ /// The action to be triggered by the commmand
public void AddAction(string key, object action)
{
- // This might blow up if an action with that key already exists
- ActionDictionary.Add(key, action);
+ if (!ActionDictionary.ContainsKey(key))
+ {
+ ActionDictionary.Add(key, action);
+ }
+ else
+ {
+ Debug.Console(1, this, "Cannot add action with key '{0}' because key already exists in ActionDictionary.");
+ }
}
+ ///
+ /// Removes and action from the dictionary
+ ///
+ ///
public void RemoveAction(string key)
{
if (ActionDictionary.ContainsKey(key))
@@ -135,22 +150,39 @@ namespace PepperDash.Essentials
/// object to be serialized and sent in post body
public void PostToServer(EssentialsRoomBase room, JObject o)
{
- if(Client == null)
- Client = new HttpClient();
+ try
+ {
+ if (Client == null)
+ Client = new HttpClient();
- HttpClientRequest request = new HttpClientRequest();
+ //HttpClient client = new HttpClient();
- Client.Verbose = true;
- Client.KeepAlive = true;
+ HttpClientRequest request = new HttpClientRequest();
- string url = string.Format("http://{0}/api/room/{1}", Config.serverUrl, string.Format("{0}-{1}", SystemUuid, room.Key));
+ Client.Verbose = true;
+ Client.KeepAlive = true;
- request.Url.Parse(url);
- request.RequestType = RequestType.Post;
- request.Header.SetHeaderValue("Content-Type", "application/json");
- request.ContentString = o.ToString();
+ string url = string.Format("http://{0}/api/room/{1}/status", Config.serverUrl, string.Format("{0}--{1}", SystemUuid, room.Key));
- Client.DispatchAsync(request, PostConnectionCallback);
+ request.Url.Parse(url);
+ request.RequestType = RequestType.Post;
+ request.Header.SetHeaderValue("Content-Type", "application/json");
+ request.KeepAlive = true;
+
+ // Ignore any null objects when serializing and remove formatting
+ string ignored = JsonConvert.SerializeObject(o, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
+ request.ContentString = ignored;
+
+ Debug.Console(1, this, "Posting to '{0}':\n{1}", url, request.ContentString);
+
+ Client.DispatchAsync(request, (r, err) => { if (r != null) { Debug.Console(1, this, "Status Response Code: {0}", r.Code); } });
+
+ StartReconnectTimer(5000, 5000);
+ }
+ catch(Exception e)
+ {
+ Debug.Console(1, this, "Error Posting to Server: {0}", e);
+ }
}
///
@@ -181,6 +213,13 @@ namespace PepperDash.Essentials
{
if (resp != null && resp.Code == 200)
{
+ if(Reconnect != null)
+ {
+ Reconnect.Stop();
+
+ Reconnect = null;
+ }
+
if (SseClient == null)
{
ConnectSseClient(null);
@@ -188,12 +227,12 @@ namespace PepperDash.Essentials
}
else
{
- Debug.Console(0, this, "Unable to initialize SSE Client");
+ Debug.Console(0, this, "Response from server: {0}\n{1}", resp.Code, err);
}
}
catch (Exception e)
{
- Debug.Console(1, this, "Error Initializeing SSE Client: {0}", e);
+ Debug.Console(1, this, "Error Initializing SSE Client: {0}", e);
}
}
@@ -205,15 +244,22 @@ namespace PepperDash.Essentials
{
if (Heartbeat != null)
{
+ Debug.Console(1, this, "Heartbeat Timer Expired.");
+
Heartbeat.Stop();
Heartbeat = null;
}
- // Start the reconnect timer
- Reconnect = new CTimer(ReconnectToServer, null, 5000, 5000);
+ StartReconnectTimer(5000, 5000);
+ }
- Reconnect.Reset(5000, 5000);
+ void StartReconnectTimer(long dueTime, long repeatTime)
+ {
+ // Start the reconnect timer
+ Reconnect = new CTimer(ReconnectToServer, null, dueTime, repeatTime);
+
+ Reconnect.Reset(dueTime, repeatTime);
}
@@ -246,11 +292,8 @@ namespace PepperDash.Essentials
SseClient.Url = string.Format("http://{0}/api/system/stream/{1}", Config.serverUrl, uuid);
SseClient.Connect();
-
- //Heartbeat = new CTimer(HeartbeatExpired, null, 20000, 20000);
-
- //Heartbeat.Reset(20000, 20000);
}
+
void LineGathered_LineReceived(object sender, GenericCommMethodReceiveTextArgs e)
{
@@ -260,8 +303,6 @@ namespace PepperDash.Essentials
{
var message = e.Text.Substring(6);
- string roomId = null;
-
Debug.Console(1, this, "Message: '{0}'", message);
try
@@ -270,11 +311,21 @@ namespace PepperDash.Essentials
var type = messageObj["type"].Value();
- if(type == "/system/hearbeat")
+ if (type == "hello")
{
- //Heartbeat.Reset(20000, 20000);
+ Heartbeat = new CTimer(HeartbeatExpired, null, 20000, 20000);
+
+ Debug.Console(2, this, "Heartbeat Timer Started.");
+
+ Heartbeat.Reset(20000, 20000);
}
- else if(type == "close")
+ else if (type == "/system/heartbeat")
+ {
+ Heartbeat.Reset(20000, 20000);
+
+ Debug.Console(2, this, "Heartbeat Timer Reset.");
+ }
+ else if (type == "close")
{
SseClient.Disconnect();
@@ -285,19 +336,21 @@ namespace PepperDash.Essentials
}
else
{
-
-
// Check path against Action dictionary
if (ActionDictionary.ContainsKey(type))
{
var action = ActionDictionary[type];
- if (action is Action)
+ if (action is Action)
+ {
+ (action as Action)();
+ }
+ else if (action is Action)
{
var stateString = messageObj["content"]["state"].Value();
// Look for a button press event
- if(!string.IsNullOrEmpty(stateString))
+ if (!string.IsNullOrEmpty(stateString))
{
#warning deal with held state later
if (stateString == "held")
@@ -320,7 +373,7 @@ namespace PepperDash.Essentials
.ToObject());
}
}
-
+
}
}
diff --git a/Essentials/PepperDashEssentials/Room/EssentialsHuddleSpaceRoom.cs b/Essentials/PepperDashEssentials/Room/EssentialsHuddleSpaceRoom.cs
index 9485ee10..fa7bee4c 100644
--- a/Essentials/PepperDashEssentials/Room/EssentialsHuddleSpaceRoom.cs
+++ b/Essentials/PepperDashEssentials/Room/EssentialsHuddleSpaceRoom.cs
@@ -80,14 +80,16 @@ namespace PepperDash.Essentials
_CurrentSourceInfo = value;
- // add to in-use tracking
+ // add to in-use tracking
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
if (handler != null)
handler(this, _CurrentSourceInfo, ChangeType.DidChange);
}
}
- SourceListItem _CurrentSourceInfo;
+ SourceListItem _CurrentSourceInfo;
+
+ public string CurrentSourceInfoKey { get; private set; }
///
///
@@ -154,9 +156,15 @@ namespace PepperDash.Essentials
Debug.Console(2, this, "Action {0} has {1} steps",
item.SourceKey, item.RouteList.Count);
- // Let's run it
- if (routeKey.ToLower() != "roomoff")
- LastSourceKey = routeKey;
+ // Let's run it
+ if (routeKey.ToLower() != "roomoff")
+ {
+ LastSourceKey = routeKey;
+ }
+ else
+ {
+ CurrentSourceInfoKey = null;
+ }
foreach (var route in item.RouteList)
{
@@ -203,9 +211,12 @@ namespace PepperDash.Essentials
}
CurrentVolumeControls = volDev;
- // store the name and UI info for routes
- if (item.SourceKey != null)
- CurrentSourceInfo = item;
+ // store the name and UI info for routes
+ if (item.SourceKey != null)
+ {
+ CurrentSourceInfoKey = routeKey;
+ CurrentSourceInfo = item;
+ }
// And finally, set the "control". This will trigger event
//CurrentControlDevice = DeviceManager.GetDeviceForKey(item.SourceKey) as Device;
diff --git a/Essentials/PepperDashEssentials/UI/EssentialsTouchpanelController.cs b/Essentials/PepperDashEssentials/UI/EssentialsTouchpanelController.cs
index 17321bb3..a6b1f623 100644
--- a/Essentials/PepperDashEssentials/UI/EssentialsTouchpanelController.cs
+++ b/Essentials/PepperDashEssentials/UI/EssentialsTouchpanelController.cs
@@ -94,7 +94,7 @@ namespace PepperDash.Essentials
var mainDriver = new EssentialsPanelMainInterfaceDriver(Panel, props);
// Then the AV driver
- // spin up different room drivers depending on room type
+ // spin up different room drivers depending on room type
var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey);
if (room is EssentialsHuddleSpaceRoom)
{