mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-06 08:16:11 +00:00
Working 2-way communication with Cotija Node server for Essentials Huddle Room Type
This commit is contained in:
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
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<bool> PowerIsOnFeedbackFunc { get { return () => _PowerIsOn; } }
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
|
||||
protected override Func<bool> 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
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
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<bool> PowerIsOnFeedbackFunc { get { return () => _PowerIsOn; } }
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
|
||||
protected override Func<bool> 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
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -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
|
||||
|
||||
Binary file not shown.
@@ -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<CrestronTouchpanelPropertiesConfig>(
|
||||
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<ConsoleCommMockDevicePropertiesConfig>(
|
||||
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<CrestronTouchpanelPropertiesConfig>(
|
||||
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<ConsoleCommMockDevicePropertiesConfig>(
|
||||
properties.ToString());
|
||||
return new ConsoleCommMockDevice(key, name, props, comm);
|
||||
}
|
||||
|
||||
else if (typeName == "webserver")
|
||||
{
|
||||
var props = JsonConvert.DeserializeObject<CotijaConfig>(properties.ToString());
|
||||
return new CotijaSystemController(key, name, props);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
Binary file not shown.
226
Essentials/PepperDashEssentials/Room/Cotija/CotijaRoomBridge.cs
Normal file
226
Essentials/PepperDashEssentials/Room/Cotija/CotijaRoomBridge.cs
Normal file
@@ -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<SourceSelectMessageContent>(c => room.RunRouteAction(c.SourceSelect)));
|
||||
Parent.AddAction(string.Format(@"/room/{0}/event/masterVolumeUpBtn", Room.Key), new Action<bool>(b => room.CurrentVolumeControls.VolumeUp(b)));
|
||||
Parent.AddAction(string.Format(@"/room/{0}/event/masterVolumeDownBtn", Room.Key), new Action<bool>(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<VolumeDeviceChangeEventArgs>(Room_CurrentVolumeDeviceChange);
|
||||
|
||||
Room.OnFeedback.OutputChange += new EventHandler<EventArgs>(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<EventArgs>(VolumeLevelFeedback_OutputChange);
|
||||
newDev.VolumeLevelFeedback.OutputChange += new EventHandler<EventArgs>(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<EventArgs>(VolumeLevelFeedback_OutputChange);
|
||||
newDev.VolumeLevelFeedback.OutputChange += new EventHandler<EventArgs>(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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Posts the full status of the room to the server
|
||||
/// </summary>
|
||||
/// <param name="room"></param>
|
||||
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; }
|
||||
//}
|
||||
|
||||
}
|
||||
@@ -42,18 +42,33 @@ namespace PepperDash.Essentials
|
||||
|
||||
CotijaRooms = new List<CotijaEssentialsHuddleSpaceRoomBridge>();
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an action to the dictionary
|
||||
/// </summary>
|
||||
/// <param name="key">The path of the API command</param>
|
||||
/// <param name="action">The action to be triggered by the commmand</param>
|
||||
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.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes and action from the dictionary
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
public void RemoveAction(string key)
|
||||
{
|
||||
if (ActionDictionary.ContainsKey(key))
|
||||
@@ -135,22 +150,39 @@ namespace PepperDash.Essentials
|
||||
/// <param name="o">object to be serialized and sent in post body</param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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<string>();
|
||||
|
||||
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<bool>)
|
||||
if (action is Action)
|
||||
{
|
||||
(action as Action)();
|
||||
}
|
||||
else if (action is Action<bool>)
|
||||
{
|
||||
var stateString = messageObj["content"]["state"].Value<string>();
|
||||
|
||||
// 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<SourceSelectMessageContent>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user