mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-03 23:05:00 +00:00
Added IPad Extension methods to link actions between Cotija server and devices for proof of concept
This commit is contained in:
@@ -45,6 +45,6 @@ namespace PepperDash.Essentials.Core
|
||||
triList.ClearBoolSigAction(142);
|
||||
triList.ClearBoolSigAction(130);
|
||||
triList.ClearBoolSigAction(134);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,8 @@ namespace PepperDash.Essentials.Core
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
|
||||
protected override Func<bool> IsWarmingUpFeedbackFunc { get { return () => _IsWarmingUp; } }
|
||||
|
||||
int VolumeHeldRepeatInterval = 200;
|
||||
ushort VolumeInterval = 655;
|
||||
ushort _FakeVolumeLevel = 31768;
|
||||
bool _IsMuted;
|
||||
|
||||
@@ -138,22 +140,30 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
public void VolumeUp(bool pressRelease)
|
||||
{
|
||||
Debug.Console(2, this, "Volume Down {0}", pressRelease);
|
||||
if (pressRelease)
|
||||
{
|
||||
var newLevel = _FakeVolumeLevel + 655;
|
||||
SetVolume((ushort)newLevel);
|
||||
}
|
||||
//while (pressRelease)
|
||||
//{
|
||||
Debug.Console(2, this, "Volume Down {0}", pressRelease);
|
||||
if (pressRelease)
|
||||
{
|
||||
var newLevel = _FakeVolumeLevel + VolumeInterval;
|
||||
SetVolume((ushort)newLevel);
|
||||
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
public void VolumeDown(bool pressRelease)
|
||||
{
|
||||
Debug.Console(2, this, "Volume Up {0}", pressRelease);
|
||||
if (pressRelease)
|
||||
{
|
||||
var newLevel = _FakeVolumeLevel - 655;
|
||||
SetVolume((ushort)newLevel);
|
||||
}
|
||||
//while (pressRelease)
|
||||
//{
|
||||
Debug.Console(2, this, "Volume Up {0}", pressRelease);
|
||||
if (pressRelease)
|
||||
{
|
||||
var newLevel = _FakeVolumeLevel - VolumeInterval;
|
||||
SetVolume((ushort)newLevel);
|
||||
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
public void MuteToggle()
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,354 +1,354 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Displays
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NecPSXMDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, ICommunicationMonitor
|
||||
{
|
||||
public IBasicCommunication Communication { get; private set; }
|
||||
public CommunicationGather PortGather { get; private set; }
|
||||
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
||||
|
||||
#region Command constants
|
||||
public const string InputGetCmd = "\x01\x30\x41\x30\x43\x30\x36\x02\x30\x30\x36\x30\x03\x03\x0D";
|
||||
public const string Hdmi1Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x31\x31\x03\x72\x0d";
|
||||
public const string Hdmi2Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x31\x32\x03\x71\x0D";
|
||||
public const string Hdmi3Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x38\x32\x03\x78\x0D";
|
||||
public const string Hdmi4Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x38\x33\x03\x79\x0D";
|
||||
public const string Dp1Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x30\x46\x03\x04\x0D";
|
||||
public const string Dp2Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x31\x30\x03\x73\x0D";
|
||||
public const string Dvi1Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x30\x33\x03\x71\x0d";
|
||||
public const string Video1Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x30\x35\x03\x77\x0D";
|
||||
public const string VgaCmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x30\x31\x03\x73\x0D";
|
||||
public const string RgbCmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x30\x32\x03\x70\x0D";
|
||||
|
||||
public const string PowerOnCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x30\x33\x44\x36\x30\x30\x30\x31\x03\x73\x0D";
|
||||
public const string PowerOffCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x30\x33\x44\x36\x30\x30\x30\x34\x03\x76\x0D";
|
||||
public const string PowerToggleIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x30\x33\x30\x33\x03\x02\x0D";
|
||||
|
||||
public const string MuteOffCmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x38\x44\x30\x30\x30\x30\x03\x08\x0D";
|
||||
public const string MuteOnCmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x38\x44\x30\x30\x30\x31\x03\x09\x0D";
|
||||
public const string MuteToggleIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x31\x42\x30\x33\x03\x72\x0D";
|
||||
public const string MuteGetCmd = "\x01\x30\x41\x30\x43\x30\x36\x02\x30\x30\x38\x44\x03\x79\x0D";
|
||||
|
||||
public const string VolumeGetCmd = "\x01\x30\x41\x30\x43\x30\x36\x02\x30\x30\x36\x32\x03\x01\x0D";
|
||||
public const string VolumeLevelPartialCmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x32"; //\x46\x46\x46\x46\x03\xNN\x0D
|
||||
public const string VolumeUpCmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x31\x30\x41\x44\x30\x30\x30\x31\x03\x71\x0D";
|
||||
public const string VolumeDownCmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x31\x30\x41\x44\x30\x30\x30\x32\x03\x72\x0D";
|
||||
|
||||
public const string MenuIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x32\x30\x30\x33\x03\x03\x0D";
|
||||
public const string UpIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x31\x35\x30\x33\x03\x05\x0D";
|
||||
public const string DownIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x31\x34\x30\x33\x03\x04\x0D";
|
||||
public const string LeftIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x32\x31\x30\x33\x03\x02\x0D";
|
||||
public const string RightIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x32\x32\x30\x33\x03\x01\x0D";
|
||||
public const string SelectIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x32\x33\x30\x33\x03\x00\x0D";
|
||||
public const string ExitIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x31\x46\x30\x33\x03\x76\x0D";
|
||||
#endregion
|
||||
|
||||
bool _PowerIsOn;
|
||||
bool _IsWarmingUp;
|
||||
bool _IsCoolingDown;
|
||||
ushort _VolumeLevel;
|
||||
bool _IsMuted;
|
||||
|
||||
protected override Func<bool> PowerIsOnFeedbackFunc { get { return () => _PowerIsOn; } }
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
|
||||
protected override Func<bool> IsWarmingUpFeedbackFunc { get { return () => _IsWarmingUp; } }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for IBasicCommunication
|
||||
/// </summary>
|
||||
public NecPSXMDisplay(string key, string name, IBasicCommunication comm)
|
||||
: base(key, name)
|
||||
{
|
||||
Communication = comm;
|
||||
Init();
|
||||
}
|
||||
/// <summary>
|
||||
/// Constructor for TCP
|
||||
/// </summary>
|
||||
public NecPSXMDisplay(string key, string name, string hostname, int port)
|
||||
: base(key, name)
|
||||
{
|
||||
Communication = new GenericTcpIpClient(key + "-tcp", hostname, port, 5000);
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for COM
|
||||
/// </summary>
|
||||
public NecPSXMDisplay(string key, string name, ComPort port, ComPort.ComPortSpec spec)
|
||||
: base(key, name)
|
||||
{
|
||||
Communication = new ComPortController(key + "-com", port, spec);
|
||||
Init();
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
PortGather = new CommunicationGather(Communication, '\x0d');
|
||||
PortGather.LineReceived += this.Port_LineReceived;
|
||||
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 30000, 120000, 300000, "xx\x0d");
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi1), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi2), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi3), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi4), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.DisplayPortIn1, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.DisplayPort, new Action(InputDisplayPort1), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.DisplayPortIn2, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.DisplayPort, new Action(InputDisplayPort2), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.DviIn, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Dvi, new Action(InputDvi1), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Composite, new Action(InputVideo1), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.VgaIn, eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Vga, new Action(InputVga), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.RgbIn, eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Rgb, new Action(new Action(InputRgb)), this));
|
||||
|
||||
VolumeLevelFeedback = new IntFeedback(() => { return _VolumeLevel; });
|
||||
MuteFeedback = new BoolFeedback(() => _IsMuted);
|
||||
|
||||
// new BoolCueActionPair(CommonBoolCue.Menu, b => { if(b) Send(MenuIrCmd); }),
|
||||
// new BoolCueActionPair(CommonBoolCue.Up, b => { if(b) Send(UpIrCmd); }),
|
||||
// new BoolCueActionPair(CommonBoolCue.Down, b => { if(b) Send(DownIrCmd); }),
|
||||
// new BoolCueActionPair(CommonBoolCue.Left, b => { if(b) Send(LeftIrCmd); }),
|
||||
// new BoolCueActionPair(CommonBoolCue.Right, b => { if(b) Send(RightIrCmd); }),
|
||||
// new BoolCueActionPair(CommonBoolCue.Select, b => { if(b) Send(SelectIrCmd); }),
|
||||
// new BoolCueActionPair(CommonBoolCue.Exit, b => { if(b) Send(ExitIrCmd); }),
|
||||
//};
|
||||
}
|
||||
|
||||
~NecPSXMDisplay()
|
||||
{
|
||||
PortGather = null;
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
Communication.Connect();
|
||||
CommunicationMonitor.StatusChange += (o, a) => { Debug.Console(2, this, "Communication monitor state: {0}", CommunicationMonitor.Status); };
|
||||
CommunicationMonitor.Start();
|
||||
return true;
|
||||
}
|
||||
|
||||
public override List<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
var list = base.Feedbacks;
|
||||
list.AddRange(new List<Feedback>
|
||||
{
|
||||
|
||||
});
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args)
|
||||
{
|
||||
if (Debug.Level == 2)
|
||||
Debug.Console(2, this, "Received: '{0}'", ComTextHelper.GetEscapedText(args.Text));
|
||||
|
||||
if (args.Text=="DO SOMETHING HERE EVENTUALLY")
|
||||
{
|
||||
_IsMuted = true;
|
||||
MuteFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void AppendChecksumAndSend(string s)
|
||||
{
|
||||
int x = 0;
|
||||
for (int i = 1; i < s.Length; i++)
|
||||
x = x ^ s[i];
|
||||
|
||||
string send = s + (char)x + '\x0d';
|
||||
Send(send);
|
||||
}
|
||||
|
||||
void Send(string s)
|
||||
{
|
||||
if (Debug.Level == 2)
|
||||
Debug.Console(2, this, "Send: '{0}'", ComTextHelper.GetEscapedText(s));
|
||||
Communication.SendText(s);
|
||||
}
|
||||
|
||||
|
||||
public override void PowerOn()
|
||||
{
|
||||
Send(PowerOnCmd);
|
||||
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)
|
||||
{
|
||||
Send(PowerOffCmd);
|
||||
_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 void InputHdmi1()
|
||||
{
|
||||
Send(Hdmi1Cmd);
|
||||
}
|
||||
|
||||
public void InputHdmi2()
|
||||
{
|
||||
Send(Hdmi2Cmd);
|
||||
}
|
||||
|
||||
public void InputHdmi3()
|
||||
{
|
||||
Send(Hdmi3Cmd);
|
||||
}
|
||||
|
||||
public void InputHdmi4()
|
||||
{
|
||||
Send(Hdmi4Cmd);
|
||||
}
|
||||
|
||||
public void InputDisplayPort1()
|
||||
{
|
||||
Send(Dp1Cmd);
|
||||
}
|
||||
|
||||
public void InputDisplayPort2()
|
||||
{
|
||||
Send(Dp2Cmd);
|
||||
}
|
||||
|
||||
public void InputDvi1()
|
||||
{
|
||||
Send(Dvi1Cmd);
|
||||
}
|
||||
|
||||
public void InputVideo1()
|
||||
{
|
||||
Send(Video1Cmd);
|
||||
}
|
||||
|
||||
public void InputVga()
|
||||
{
|
||||
Send(VgaCmd);
|
||||
}
|
||||
|
||||
public void InputRgb()
|
||||
{
|
||||
Send(RgbCmd);
|
||||
}
|
||||
|
||||
public override void ExecuteSwitch(object selector)
|
||||
{
|
||||
if (selector is Action)
|
||||
(selector as Action).Invoke();
|
||||
else
|
||||
Debug.Console(1, this, "WARNING: ExecuteSwitch cannot handle type {0}", selector.GetType());
|
||||
//Send((string)selector);
|
||||
}
|
||||
|
||||
void SetVolume(ushort level)
|
||||
{
|
||||
var levelString = string.Format("{0}{1:X4}\x03", VolumeLevelPartialCmd, level);
|
||||
AppendChecksumAndSend(levelString);
|
||||
//Debug.Console(2, this, "Volume:{0}", ComTextHelper.GetEscapedText(levelString));
|
||||
_VolumeLevel = level;
|
||||
VolumeLevelFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
#region IBasicVolumeWithFeedback Members
|
||||
|
||||
public IntFeedback VolumeLevelFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback MuteFeedback { get; private set; }
|
||||
|
||||
public void MuteOff()
|
||||
{
|
||||
Send(MuteOffCmd);
|
||||
}
|
||||
|
||||
public void MuteOn()
|
||||
{
|
||||
Send(MuteOnCmd);
|
||||
}
|
||||
|
||||
void IBasicVolumeWithFeedback.SetVolume(ushort level)
|
||||
{
|
||||
SetVolume(level);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IBasicVolumeControls Members
|
||||
|
||||
public void MuteToggle()
|
||||
{
|
||||
Send(MuteToggleIrCmd);
|
||||
}
|
||||
|
||||
public void VolumeDown(bool pressRelease)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
//#warning need incrementer for these
|
||||
SetVolume(_VolumeLevel++);
|
||||
}
|
||||
|
||||
public void VolumeUp(bool pressRelease)
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Displays
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NecPSXMDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, ICommunicationMonitor
|
||||
{
|
||||
public IBasicCommunication Communication { get; private set; }
|
||||
public CommunicationGather PortGather { get; private set; }
|
||||
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
||||
|
||||
#region Command constants
|
||||
public const string InputGetCmd = "\x01\x30\x41\x30\x43\x30\x36\x02\x30\x30\x36\x30\x03\x03\x0D";
|
||||
public const string Hdmi1Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x31\x31\x03\x72\x0d";
|
||||
public const string Hdmi2Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x31\x32\x03\x71\x0D";
|
||||
public const string Hdmi3Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x38\x32\x03\x78\x0D";
|
||||
public const string Hdmi4Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x38\x33\x03\x79\x0D";
|
||||
public const string Dp1Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x30\x46\x03\x04\x0D";
|
||||
public const string Dp2Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x31\x30\x03\x73\x0D";
|
||||
public const string Dvi1Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x30\x33\x03\x71\x0d";
|
||||
public const string Video1Cmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x30\x35\x03\x77\x0D";
|
||||
public const string VgaCmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x30\x31\x03\x73\x0D";
|
||||
public const string RgbCmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x30\x30\x30\x30\x32\x03\x70\x0D";
|
||||
|
||||
public const string PowerOnCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x30\x33\x44\x36\x30\x30\x30\x31\x03\x73\x0D";
|
||||
public const string PowerOffCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x30\x33\x44\x36\x30\x30\x30\x34\x03\x76\x0D";
|
||||
public const string PowerToggleIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x30\x33\x30\x33\x03\x02\x0D";
|
||||
|
||||
public const string MuteOffCmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x38\x44\x30\x30\x30\x30\x03\x08\x0D";
|
||||
public const string MuteOnCmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x38\x44\x30\x30\x30\x31\x03\x09\x0D";
|
||||
public const string MuteToggleIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x31\x42\x30\x33\x03\x72\x0D";
|
||||
public const string MuteGetCmd = "\x01\x30\x41\x30\x43\x30\x36\x02\x30\x30\x38\x44\x03\x79\x0D";
|
||||
|
||||
public const string VolumeGetCmd = "\x01\x30\x41\x30\x43\x30\x36\x02\x30\x30\x36\x32\x03\x01\x0D";
|
||||
public const string VolumeLevelPartialCmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x30\x30\x36\x32"; //\x46\x46\x46\x46\x03\xNN\x0D
|
||||
public const string VolumeUpCmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x31\x30\x41\x44\x30\x30\x30\x31\x03\x71\x0D";
|
||||
public const string VolumeDownCmd = "\x01\x30\x41\x30\x45\x30\x41\x02\x31\x30\x41\x44\x30\x30\x30\x32\x03\x72\x0D";
|
||||
|
||||
public const string MenuIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x32\x30\x30\x33\x03\x03\x0D";
|
||||
public const string UpIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x31\x35\x30\x33\x03\x05\x0D";
|
||||
public const string DownIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x31\x34\x30\x33\x03\x04\x0D";
|
||||
public const string LeftIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x32\x31\x30\x33\x03\x02\x0D";
|
||||
public const string RightIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x32\x32\x30\x33\x03\x01\x0D";
|
||||
public const string SelectIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x32\x33\x30\x33\x03\x00\x0D";
|
||||
public const string ExitIrCmd = "\x01\x30\x41\x30\x41\x30\x43\x02\x43\x32\x31\x30\x30\x30\x31\x46\x30\x33\x03\x76\x0D";
|
||||
#endregion
|
||||
|
||||
bool _PowerIsOn;
|
||||
bool _IsWarmingUp;
|
||||
bool _IsCoolingDown;
|
||||
ushort _VolumeLevel;
|
||||
bool _IsMuted;
|
||||
|
||||
protected override Func<bool> PowerIsOnFeedbackFunc { get { return () => _PowerIsOn; } }
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
|
||||
protected override Func<bool> IsWarmingUpFeedbackFunc { get { return () => _IsWarmingUp; } }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for IBasicCommunication
|
||||
/// </summary>
|
||||
public NecPSXMDisplay(string key, string name, IBasicCommunication comm)
|
||||
: base(key, name)
|
||||
{
|
||||
Communication = comm;
|
||||
Init();
|
||||
}
|
||||
/// <summary>
|
||||
/// Constructor for TCP
|
||||
/// </summary>
|
||||
public NecPSXMDisplay(string key, string name, string hostname, int port)
|
||||
: base(key, name)
|
||||
{
|
||||
Communication = new GenericTcpIpClient(key + "-tcp", hostname, port, 5000);
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for COM
|
||||
/// </summary>
|
||||
public NecPSXMDisplay(string key, string name, ComPort port, ComPort.ComPortSpec spec)
|
||||
: base(key, name)
|
||||
{
|
||||
Communication = new ComPortController(key + "-com", port, spec);
|
||||
Init();
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
PortGather = new CommunicationGather(Communication, '\x0d');
|
||||
PortGather.LineReceived += this.Port_LineReceived;
|
||||
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 30000, 120000, 300000, "xx\x0d");
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi1), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi2), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi3), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi4), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.DisplayPortIn1, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.DisplayPort, new Action(InputDisplayPort1), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.DisplayPortIn2, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.DisplayPort, new Action(InputDisplayPort2), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.DviIn, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Dvi, new Action(InputDvi1), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Composite, new Action(InputVideo1), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.VgaIn, eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Vga, new Action(InputVga), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.RgbIn, eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Rgb, new Action(new Action(InputRgb)), this));
|
||||
|
||||
VolumeLevelFeedback = new IntFeedback(() => { return _VolumeLevel; });
|
||||
MuteFeedback = new BoolFeedback(() => _IsMuted);
|
||||
|
||||
// new BoolCueActionPair(CommonBoolCue.Menu, b => { if(b) Send(MenuIrCmd); }),
|
||||
// new BoolCueActionPair(CommonBoolCue.Up, b => { if(b) Send(UpIrCmd); }),
|
||||
// new BoolCueActionPair(CommonBoolCue.Down, b => { if(b) Send(DownIrCmd); }),
|
||||
// new BoolCueActionPair(CommonBoolCue.Left, b => { if(b) Send(LeftIrCmd); }),
|
||||
// new BoolCueActionPair(CommonBoolCue.Right, b => { if(b) Send(RightIrCmd); }),
|
||||
// new BoolCueActionPair(CommonBoolCue.Select, b => { if(b) Send(SelectIrCmd); }),
|
||||
// new BoolCueActionPair(CommonBoolCue.Exit, b => { if(b) Send(ExitIrCmd); }),
|
||||
//};
|
||||
}
|
||||
|
||||
~NecPSXMDisplay()
|
||||
{
|
||||
PortGather = null;
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
Communication.Connect();
|
||||
CommunicationMonitor.StatusChange += (o, a) => { Debug.Console(2, this, "Communication monitor state: {0}", CommunicationMonitor.Status); };
|
||||
CommunicationMonitor.Start();
|
||||
return true;
|
||||
}
|
||||
|
||||
public override List<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
var list = base.Feedbacks;
|
||||
list.AddRange(new List<Feedback>
|
||||
{
|
||||
|
||||
});
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args)
|
||||
{
|
||||
if (Debug.Level == 2)
|
||||
Debug.Console(2, this, "Received: '{0}'", ComTextHelper.GetEscapedText(args.Text));
|
||||
|
||||
if (args.Text=="DO SOMETHING HERE EVENTUALLY")
|
||||
{
|
||||
_IsMuted = true;
|
||||
MuteFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void AppendChecksumAndSend(string s)
|
||||
{
|
||||
int x = 0;
|
||||
for (int i = 1; i < s.Length; i++)
|
||||
x = x ^ s[i];
|
||||
|
||||
string send = s + (char)x + '\x0d';
|
||||
Send(send);
|
||||
}
|
||||
|
||||
void Send(string s)
|
||||
{
|
||||
if (Debug.Level == 2)
|
||||
Debug.Console(2, this, "Send: '{0}'", ComTextHelper.GetEscapedText(s));
|
||||
Communication.SendText(s);
|
||||
}
|
||||
|
||||
|
||||
public override void PowerOn()
|
||||
{
|
||||
Send(PowerOnCmd);
|
||||
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)
|
||||
{
|
||||
Send(PowerOffCmd);
|
||||
_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 void InputHdmi1()
|
||||
{
|
||||
Send(Hdmi1Cmd);
|
||||
}
|
||||
|
||||
public void InputHdmi2()
|
||||
{
|
||||
Send(Hdmi2Cmd);
|
||||
}
|
||||
|
||||
public void InputHdmi3()
|
||||
{
|
||||
Send(Hdmi3Cmd);
|
||||
}
|
||||
|
||||
public void InputHdmi4()
|
||||
{
|
||||
Send(Hdmi4Cmd);
|
||||
}
|
||||
|
||||
public void InputDisplayPort1()
|
||||
{
|
||||
Send(Dp1Cmd);
|
||||
}
|
||||
|
||||
public void InputDisplayPort2()
|
||||
{
|
||||
Send(Dp2Cmd);
|
||||
}
|
||||
|
||||
public void InputDvi1()
|
||||
{
|
||||
Send(Dvi1Cmd);
|
||||
}
|
||||
|
||||
public void InputVideo1()
|
||||
{
|
||||
Send(Video1Cmd);
|
||||
}
|
||||
|
||||
public void InputVga()
|
||||
{
|
||||
Send(VgaCmd);
|
||||
}
|
||||
|
||||
public void InputRgb()
|
||||
{
|
||||
Send(RgbCmd);
|
||||
}
|
||||
|
||||
public override void ExecuteSwitch(object selector)
|
||||
{
|
||||
if (selector is Action)
|
||||
(selector as Action).Invoke();
|
||||
else
|
||||
Debug.Console(1, this, "WARNING: ExecuteSwitch cannot handle type {0}", selector.GetType());
|
||||
//Send((string)selector);
|
||||
}
|
||||
|
||||
void SetVolume(ushort level)
|
||||
{
|
||||
var levelString = string.Format("{0}{1:X4}\x03", VolumeLevelPartialCmd, level);
|
||||
AppendChecksumAndSend(levelString);
|
||||
//Debug.Console(2, this, "Volume:{0}", ComTextHelper.GetEscapedText(levelString));
|
||||
_VolumeLevel = level;
|
||||
VolumeLevelFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
#region IBasicVolumeWithFeedback Members
|
||||
|
||||
public IntFeedback VolumeLevelFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback MuteFeedback { get; private set; }
|
||||
|
||||
public void MuteOff()
|
||||
{
|
||||
Send(MuteOffCmd);
|
||||
}
|
||||
|
||||
public void MuteOn()
|
||||
{
|
||||
Send(MuteOnCmd);
|
||||
}
|
||||
|
||||
void IBasicVolumeWithFeedback.SetVolume(ushort level)
|
||||
{
|
||||
SetVolume(level);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IBasicVolumeControls Members
|
||||
|
||||
public void MuteToggle()
|
||||
{
|
||||
Send(MuteToggleIrCmd);
|
||||
}
|
||||
|
||||
public void VolumeDown(bool pressRelease)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
SetVolume(_VolumeLevel--);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
//#warning need incrementer for these
|
||||
SetVolume(_VolumeLevel++);
|
||||
}
|
||||
|
||||
public void VolumeUp(bool pressRelease)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
SetVolume(_VolumeLevel--);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -142,6 +142,7 @@
|
||||
<Compile Include="FOR REFERENCE Room\EssentialsRoom.cs" />
|
||||
<Compile Include="Room\Cotija\CotijaConfig.cs" />
|
||||
<Compile Include="Room\Cotija\CotijaRoomBridge.cs" />
|
||||
<Compile Include="Room\Cotija\DeviceTypeInterfaces\IDPadExtensions.cs" />
|
||||
<Compile Include="Room\EssentialsPresentationRoom.cs" />
|
||||
<Compile Include="Room\EssentialsRoomBase.cs" />
|
||||
<Compile Include="Room\EssentialsRoomConfig.cs" />
|
||||
|
||||
Binary file not shown.
@@ -135,22 +135,73 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (type == ChangeType.WillChange)
|
||||
{
|
||||
// Disconnect from previous source
|
||||
|
||||
if (type != ChangeType.DidChange)
|
||||
return;
|
||||
if (info != null)
|
||||
{
|
||||
var previousDev = info.SourceDevice;
|
||||
|
||||
JObject roomStatus = new JObject();
|
||||
// device type interfaces
|
||||
//if (previousDev is ISetTopBoxControls)
|
||||
// (previousDev as ISetTopBoxControls).UnlinkButtons(TriList);
|
||||
//// common interfaces
|
||||
//if (previousDev is IChannel)
|
||||
// (previousDev as IChannel).UnlinkButtons(TriList);
|
||||
//if (previousDev is IColor)
|
||||
// (previousDev as IColor).UnlinkButtons(TriList);
|
||||
if (previousDev is IDPad)
|
||||
(previousDev as IDPad).UnlinkActions(Parent);
|
||||
//if (previousDev is IDvr)
|
||||
// (previousDev as IDvr).UnlinkButtons(TriList);
|
||||
//if (previousDev is INumericKeypad)
|
||||
// (previousDev as INumericKeypad).UnlinkButtons(TriList);
|
||||
//if (previousDev is IPower)
|
||||
// (previousDev as IPower).UnlinkButtons(TriList);
|
||||
//if (previousDev is ITransport)
|
||||
// (previousDev as ITransport).UnlinkButtons(TriList);
|
||||
}
|
||||
|
||||
var huddleRoom = room as EssentialsHuddleSpaceRoom;
|
||||
//roomStatus.Add("isOn", huddleRoom.OnFeedback.BoolValue);
|
||||
roomStatus.Add("selectedSourceKey", huddleRoom.CurrentSourceInfoKey);
|
||||
JObject roomStatus = new JObject();
|
||||
|
||||
JObject message = new JObject();
|
||||
var huddleRoom = room as EssentialsHuddleSpaceRoom;
|
||||
//roomStatus.Add("isOn", huddleRoom.OnFeedback.BoolValue);
|
||||
roomStatus.Add("selectedSourceKey", huddleRoom.CurrentSourceInfoKey);
|
||||
|
||||
message.Add("type", "/room/status/");
|
||||
message.Add("content", roomStatus);
|
||||
JObject message = new JObject();
|
||||
|
||||
Parent.PostToServer(Room, message);
|
||||
message.Add("type", "/room/status/");
|
||||
message.Add("content", roomStatus);
|
||||
|
||||
Parent.PostToServer(Room, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info != null)
|
||||
{
|
||||
var dev = info.SourceDevice;
|
||||
|
||||
//if (dev is ISetTopBoxControls)
|
||||
// (dev as ISetTopBoxControls).LinkButtons(TriList);
|
||||
//if (dev is IChannel)
|
||||
// (dev as IChannel).LinkButtons(TriList);
|
||||
//if (dev is IColor)
|
||||
// (dev as IColor).LinkButtons(TriList);
|
||||
if (dev is IDPad)
|
||||
(dev as IDPad).LinkActions(Parent);
|
||||
//if (dev is IDvr)
|
||||
// (dev as IDvr).LinkButtons(TriList);
|
||||
//if (dev is INumericKeypad)
|
||||
// (dev as INumericKeypad).LinkButtons(TriList);
|
||||
//if (dev is IPower)
|
||||
// (dev as IPower).LinkButtons(TriList);
|
||||
//if (dev is ITransport)
|
||||
// (dev as ITransport).LinkButtons(TriList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
if (FileLock.TryEnter())
|
||||
{
|
||||
Debug.Console(1, this, "Reading Configuration File");
|
||||
Debug.Console(1, this, "Reading configuration file to extract system UUID...");
|
||||
|
||||
postBody = File.ReadToEnd(filePath, Encoding.ASCII);
|
||||
|
||||
@@ -268,6 +268,20 @@ namespace PepperDash.Essentials
|
||||
ServerReconnect.Reset(dueTime, repeatTime);
|
||||
}
|
||||
|
||||
void StartHearbeatTimer(long dueTime, long repeatTime)
|
||||
{
|
||||
if (ServerHeartbeat == null)
|
||||
{
|
||||
ServerHeartbeat = new CTimer(HeartbeatExpired, null, dueTime, repeatTime);
|
||||
|
||||
Debug.Console(2, this, "Heartbeat Timer Started.");
|
||||
}
|
||||
|
||||
ServerHeartbeat.Reset(dueTime, repeatTime);
|
||||
|
||||
Debug.Console(2, this, "Heartbeat Timer Reset.");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Connects the SSE Client
|
||||
@@ -319,17 +333,11 @@ namespace PepperDash.Essentials
|
||||
|
||||
if (type == "hello")
|
||||
{
|
||||
ServerHeartbeat = new CTimer(HeartbeatExpired, null, ServerHeartbeatInterval, ServerHeartbeatInterval);
|
||||
|
||||
Debug.Console(2, this, "Heartbeat Timer Started.");
|
||||
|
||||
ServerHeartbeat.Reset(ServerHeartbeatInterval, ServerHeartbeatInterval);
|
||||
StartHearbeatTimer(ServerHeartbeatInterval, ServerHeartbeatInterval);
|
||||
}
|
||||
else if (type == "/system/heartbeat")
|
||||
{
|
||||
ServerHeartbeat.Reset(ServerHeartbeatInterval, ServerHeartbeatInterval);
|
||||
|
||||
Debug.Console(2, this, "Heartbeat Timer Reset.");
|
||||
StartHearbeatTimer(ServerHeartbeatInterval, ServerHeartbeatInterval);
|
||||
}
|
||||
else if (type == "close")
|
||||
{
|
||||
@@ -366,7 +374,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
PushedActions.Add(type, new CTimer(o =>
|
||||
{
|
||||
(action as Action<bool>)(false);
|
||||
(action as PressAndHoldAction)(false);
|
||||
PushedActions.Remove(type);
|
||||
}, null, ButtonHeartbeatInterval, ButtonHeartbeatInterval));
|
||||
}
|
||||
@@ -383,7 +391,7 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
case "false":
|
||||
{
|
||||
if (!PushedActions.ContainsKey(type))
|
||||
if (PushedActions.ContainsKey(type))
|
||||
{
|
||||
PushedActions[type].Stop();
|
||||
PushedActions.Remove(type);
|
||||
@@ -392,7 +400,7 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
(action as Action<bool>)(stateString == "true");
|
||||
(action as PressAndHoldAction)(stateString == "true");
|
||||
}
|
||||
}
|
||||
else if (action is Action<bool>)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public static class IDPadExtensions
|
||||
{
|
||||
public static void LinkActions(this IDPad dev, CotijaSystemController controller)
|
||||
{
|
||||
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
|
||||
|
||||
controller.AddAction(prefix + "up", new Action<bool>(dev.Up));
|
||||
controller.AddAction(prefix + "down", new Action<bool>(dev.Down));
|
||||
controller.AddAction(prefix + "left", new Action<bool>(dev.Left));
|
||||
controller.AddAction(prefix + "right", new Action<bool>(dev.Right));
|
||||
controller.AddAction(prefix + "select", new Action<bool>(dev.Select));
|
||||
controller.AddAction(prefix + "menu", new Action<bool>(dev.Menu));
|
||||
controller.AddAction(prefix + "exit", new Action<bool>(dev.Exit));
|
||||
}
|
||||
|
||||
public static void UnlinkActions(this IDPad dev, CotijaSystemController controller)
|
||||
{
|
||||
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
|
||||
|
||||
controller.RemoveAction(prefix + "up");
|
||||
controller.RemoveAction(prefix + "down");
|
||||
controller.RemoveAction(prefix + "left");
|
||||
controller.RemoveAction(prefix + "right");
|
||||
controller.RemoveAction(prefix + "select");
|
||||
controller.RemoveAction(prefix + "menu");
|
||||
controller.RemoveAction(prefix + "exit");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,161 +1,161 @@
|
||||
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
|
||||
{
|
||||
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange
|
||||
{
|
||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||
|
||||
public EssentialsRoomPropertiesConfig Config { get; private set; }
|
||||
|
||||
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||
public IRoutingSinkNoSwitching DefaultAudioDevice { get; private set; }
|
||||
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||
|
||||
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The config name of the source list
|
||||
/// </summary>
|
||||
public string SourceListKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If room is off, enables power on to last source. Default true
|
||||
/// </summary>
|
||||
public bool EnablePowerOnToLastSource { get; set; }
|
||||
string LastSourceKey;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IBasicVolumeControls CurrentVolumeControls
|
||||
{
|
||||
get { return _CurrentAudioDevice; }
|
||||
set
|
||||
{
|
||||
if (value == _CurrentAudioDevice) return;
|
||||
|
||||
var oldDev = _CurrentAudioDevice;
|
||||
// derigister this room from the device, if it can
|
||||
if (oldDev is IInUseTracking)
|
||||
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||
var handler = CurrentVolumeDeviceChange;
|
||||
if (handler != null)
|
||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||
_CurrentAudioDevice = value;
|
||||
if (handler != null)
|
||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||
// register this room with new device, if it can
|
||||
if (_CurrentAudioDevice is IInUseTracking)
|
||||
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||
}
|
||||
}
|
||||
IBasicVolumeControls _CurrentAudioDevice;
|
||||
|
||||
/// <summary>
|
||||
/// The SourceListItem last run - containing names and icons
|
||||
/// </summary>
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get { return _CurrentSourceInfo; }
|
||||
private set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSingleSourceChange;
|
||||
// remove from in-use tracker, if so equipped
|
||||
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||
|
||||
if (handler != null)
|
||||
handler(this, _CurrentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
|
||||
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
|
||||
{
|
||||
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange
|
||||
{
|
||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||
|
||||
public EssentialsRoomPropertiesConfig Config { get; private set; }
|
||||
|
||||
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||
public IRoutingSinkNoSwitching DefaultAudioDevice { get; private set; }
|
||||
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||
|
||||
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The config name of the source list
|
||||
/// </summary>
|
||||
public string SourceListKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If room is off, enables power on to last source. Default true
|
||||
/// </summary>
|
||||
public bool EnablePowerOnToLastSource { get; set; }
|
||||
string LastSourceKey;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IBasicVolumeControls CurrentVolumeControls
|
||||
{
|
||||
get { return _CurrentAudioDevice; }
|
||||
set
|
||||
{
|
||||
if (value == _CurrentAudioDevice) return;
|
||||
|
||||
var oldDev = _CurrentAudioDevice;
|
||||
// derigister this room from the device, if it can
|
||||
if (oldDev is IInUseTracking)
|
||||
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||
var handler = CurrentVolumeDeviceChange;
|
||||
if (handler != null)
|
||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||
_CurrentAudioDevice = value;
|
||||
if (handler != null)
|
||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||
// register this room with new device, if it can
|
||||
if (_CurrentAudioDevice is IInUseTracking)
|
||||
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||
}
|
||||
}
|
||||
IBasicVolumeControls _CurrentAudioDevice;
|
||||
|
||||
/// <summary>
|
||||
/// The SourceListItem last run - containing names and icons
|
||||
/// </summary>
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get { return _CurrentSourceInfo; }
|
||||
private set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSingleSourceChange;
|
||||
// remove from in-use tracker, if so equipped
|
||||
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||
|
||||
if (handler != null)
|
||||
handler(this, _CurrentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
public string CurrentSourceInfoKey { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public BoolFeedback OnFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="name"></param>
|
||||
public EssentialsHuddleSpaceRoom(string key, string name, IRoutingSinkWithSwitching defaultDisplay,
|
||||
IRoutingSinkNoSwitching defaultAudio, EssentialsRoomPropertiesConfig config)
|
||||
: base(key, name)
|
||||
{
|
||||
Config = config;
|
||||
DefaultDisplay = defaultDisplay;
|
||||
DefaultAudioDevice = defaultAudio;
|
||||
if (defaultAudio is IBasicVolumeControls)
|
||||
DefaultVolumeControls = defaultAudio as IBasicVolumeControls;
|
||||
else if (defaultAudio is IHasVolumeDevice)
|
||||
DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
|
||||
CurrentVolumeControls = DefaultVolumeControls;
|
||||
|
||||
OnFeedback = new BoolFeedback(() =>
|
||||
{ return CurrentSourceInfo != null
|
||||
&& CurrentSourceInfo.Type == eSourceListItemType.Route; });
|
||||
SourceListKey = "default";
|
||||
EnablePowerOnToLastSource = true;
|
||||
}
|
||||
|
||||
public void RunRouteAction(string routeKey)
|
||||
{
|
||||
RunRouteAction(routeKey, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||
/// route or commands
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public void RunRouteAction(string routeKey, Action successCallback)
|
||||
{
|
||||
// Run this on a separate thread
|
||||
new CTimer(o =>
|
||||
{
|
||||
Debug.Console(1, this, "Run room action '{0}'", routeKey);
|
||||
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||
if(dict == null)
|
||||
{
|
||||
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to get the list item by it's string key
|
||||
if (!dict.ContainsKey(routeKey))
|
||||
{
|
||||
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||
routeKey, SourceListKey);
|
||||
return;
|
||||
}
|
||||
|
||||
var item = dict[routeKey];
|
||||
Debug.Console(2, this, "Action {0} has {1} steps",
|
||||
item.SourceKey, item.RouteList.Count);
|
||||
|
||||
public string CurrentSourceInfoKey { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public BoolFeedback OnFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="name"></param>
|
||||
public EssentialsHuddleSpaceRoom(string key, string name, IRoutingSinkWithSwitching defaultDisplay,
|
||||
IRoutingSinkNoSwitching defaultAudio, EssentialsRoomPropertiesConfig config)
|
||||
: base(key, name)
|
||||
{
|
||||
Config = config;
|
||||
DefaultDisplay = defaultDisplay;
|
||||
DefaultAudioDevice = defaultAudio;
|
||||
if (defaultAudio is IBasicVolumeControls)
|
||||
DefaultVolumeControls = defaultAudio as IBasicVolumeControls;
|
||||
else if (defaultAudio is IHasVolumeDevice)
|
||||
DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
|
||||
CurrentVolumeControls = DefaultVolumeControls;
|
||||
|
||||
OnFeedback = new BoolFeedback(() =>
|
||||
{ return CurrentSourceInfo != null
|
||||
&& CurrentSourceInfo.Type == eSourceListItemType.Route; });
|
||||
SourceListKey = "default";
|
||||
EnablePowerOnToLastSource = true;
|
||||
}
|
||||
|
||||
public void RunRouteAction(string routeKey)
|
||||
{
|
||||
RunRouteAction(routeKey, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||
/// route or commands
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public void RunRouteAction(string routeKey, Action successCallback)
|
||||
{
|
||||
// Run this on a separate thread
|
||||
new CTimer(o =>
|
||||
{
|
||||
Debug.Console(1, this, "Run room action '{0}'", routeKey);
|
||||
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||
if(dict == null)
|
||||
{
|
||||
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to get the list item by it's string key
|
||||
if (!dict.ContainsKey(routeKey))
|
||||
{
|
||||
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||
routeKey, SourceListKey);
|
||||
return;
|
||||
}
|
||||
|
||||
var item = dict[routeKey];
|
||||
Debug.Console(2, this, "Action {0} has {1} steps",
|
||||
item.SourceKey, item.RouteList.Count);
|
||||
|
||||
// Let's run it
|
||||
if (routeKey.ToLower() != "roomoff")
|
||||
{
|
||||
@@ -164,133 +164,133 @@ namespace PepperDash.Essentials
|
||||
else
|
||||
{
|
||||
CurrentSourceInfoKey = null;
|
||||
}
|
||||
|
||||
foreach (var route in item.RouteList)
|
||||
{
|
||||
// if there is a $defaultAll on route, run two separate
|
||||
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var tempAudio = new SourceRouteListItem
|
||||
{
|
||||
DestinationKey = "$defaultDisplay",
|
||||
SourceKey = route.SourceKey,
|
||||
Type = eRoutingSignalType.Video
|
||||
};
|
||||
DoRoute(tempAudio);
|
||||
|
||||
var tempVideo = new SourceRouteListItem
|
||||
{
|
||||
DestinationKey = "$defaultAudio",
|
||||
SourceKey = route.SourceKey,
|
||||
Type = eRoutingSignalType.Audio
|
||||
};
|
||||
DoRoute(tempVideo);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
DoRoute(route);
|
||||
}
|
||||
|
||||
// Set volume control on room, 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;
|
||||
}
|
||||
CurrentVolumeControls = volDev;
|
||||
|
||||
}
|
||||
|
||||
foreach (var route in item.RouteList)
|
||||
{
|
||||
// if there is a $defaultAll on route, run two separate
|
||||
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var tempAudio = new SourceRouteListItem
|
||||
{
|
||||
DestinationKey = "$defaultDisplay",
|
||||
SourceKey = route.SourceKey,
|
||||
Type = eRoutingSignalType.Video
|
||||
};
|
||||
DoRoute(tempAudio);
|
||||
|
||||
var tempVideo = new SourceRouteListItem
|
||||
{
|
||||
DestinationKey = "$defaultAudio",
|
||||
SourceKey = route.SourceKey,
|
||||
Type = eRoutingSignalType.Audio
|
||||
};
|
||||
DoRoute(tempVideo);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
DoRoute(route);
|
||||
}
|
||||
|
||||
// Set volume control on room, 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;
|
||||
}
|
||||
CurrentVolumeControls = volDev;
|
||||
|
||||
// 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;
|
||||
|
||||
OnFeedback.FireUpdate();
|
||||
|
||||
// report back when done
|
||||
if (successCallback != null)
|
||||
successCallback();
|
||||
|
||||
#warning Need to again handle special commands in here.
|
||||
|
||||
}, 0); // end of CTimer
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will power the room on with the last-used source
|
||||
/// </summary>
|
||||
public void PowerOnToDefaultOrLastSource()
|
||||
{
|
||||
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||
return;
|
||||
RunRouteAction(LastSourceKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="route"></param>
|
||||
/// <returns></returns>
|
||||
bool DoRoute(SourceRouteListItem route)
|
||||
{
|
||||
IRoutingSinkNoSwitching dest = null;
|
||||
|
||||
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultAudioDevice;
|
||||
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultDisplay;
|
||||
else
|
||||
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
|
||||
|
||||
if (dest == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
dest.ReleaseRoute();
|
||||
if (dest is IPower)
|
||||
(dest as IPower).PowerOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||
if (source == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||
return false;
|
||||
}
|
||||
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||
/// </summary>
|
||||
public static void AllRoomsOff()
|
||||
{
|
||||
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||
foreach (var room in allRooms)
|
||||
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||
}
|
||||
}
|
||||
}
|
||||
// And finally, set the "control". This will trigger event
|
||||
//CurrentControlDevice = DeviceManager.GetDeviceForKey(item.SourceKey) as Device;
|
||||
|
||||
OnFeedback.FireUpdate();
|
||||
|
||||
// report back when done
|
||||
if (successCallback != null)
|
||||
successCallback();
|
||||
|
||||
#warning Need to again handle special commands in here.
|
||||
|
||||
}, 0); // end of CTimer
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will power the room on with the last-used source
|
||||
/// </summary>
|
||||
public void PowerOnToDefaultOrLastSource()
|
||||
{
|
||||
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||
return;
|
||||
RunRouteAction(LastSourceKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="route"></param>
|
||||
/// <returns></returns>
|
||||
bool DoRoute(SourceRouteListItem route)
|
||||
{
|
||||
IRoutingSinkNoSwitching dest = null;
|
||||
|
||||
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultAudioDevice;
|
||||
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultDisplay;
|
||||
else
|
||||
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
|
||||
|
||||
if (dest == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
dest.ReleaseRoute();
|
||||
if (dest is IPower)
|
||||
(dest as IPower).PowerOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||
if (source == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||
return false;
|
||||
}
|
||||
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||
/// </summary>
|
||||
public static void AllRoomsOff()
|
||||
{
|
||||
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||
foreach (var room in allRooms)
|
||||
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,196 +1,196 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.UI;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.PageManagers;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class EssentialsTouchpanelController : Device
|
||||
{
|
||||
public BasicTriListWithSmartObject Panel { get; private set; }
|
||||
|
||||
public PanelDriverBase PanelDriver { get; private set; }
|
||||
|
||||
CTimer BacklightTransitionedOnTimer;
|
||||
|
||||
public EssentialsTouchpanelController(string key, string name, Tswx52ButtonVoiceControl tsw,
|
||||
string projectName, string sgdPath)
|
||||
: base(key, name)
|
||||
{
|
||||
Panel = tsw;
|
||||
tsw.LoadSmartObjects(sgdPath);
|
||||
tsw.SigChange += new Crestron.SimplSharpPro.DeviceSupport.SigEventHandler(Tsw_SigChange);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Config constructor
|
||||
/// </summary>
|
||||
public EssentialsTouchpanelController(string key, string name, string type, CrestronTouchpanelPropertiesConfig props, uint id)
|
||||
: base(key, name)
|
||||
{
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
Debug.Console(2, this, "post-activation linking");
|
||||
type = type.ToLower();
|
||||
try
|
||||
{
|
||||
if (type == "crestronapp")
|
||||
{
|
||||
var app = new CrestronApp(id, Global.ControlSystem);
|
||||
app.ParameterProjectName.Value = props.ProjectName;
|
||||
Panel = app;
|
||||
}
|
||||
else if (type == "tsw752")
|
||||
Panel = new Tsw752(id, Global.ControlSystem);
|
||||
else if (type == "tsw1052")
|
||||
Panel = new Tsw1052(id, Global.ControlSystem);
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "WARNING: Cannot create TSW controller with type '{0}'", type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, this, "WARNING: Cannot create TSW base class. Panel will not function: {0}", e.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
// Reserved sigs
|
||||
if (Panel is TswFt5ButtonSystem)
|
||||
{
|
||||
var tsw = Panel as TswFt5ButtonSystem;
|
||||
tsw.ExtenderSystemReservedSigs.Use();
|
||||
tsw.ExtenderSystemReservedSigs.DeviceExtenderSigChange
|
||||
+= ExtenderSystemReservedSigs_DeviceExtenderSigChange;
|
||||
}
|
||||
|
||||
new CTimer(o =>
|
||||
{
|
||||
var regSuccess = Panel.Register();
|
||||
if (regSuccess != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
Debug.Console(0, this, "WARNING: Registration failed. Continuing, but panel may not function: {0}", regSuccess);
|
||||
|
||||
// Give up cleanly if SGD is not present.
|
||||
var sgdName = @"\NVRAM\Program" + InitialParametersClass.ApplicationNumber
|
||||
+ @"\sgd\" + props.SgdFile;
|
||||
if (!File.Exists(sgdName))
|
||||
{
|
||||
Debug.Console(0, this, "WARNING: Smart object file '{0}' not present. Exiting TSW load", sgdName);
|
||||
return;
|
||||
}
|
||||
|
||||
Panel.LoadSmartObjects(sgdName);
|
||||
Panel.SigChange += Tsw_SigChange;
|
||||
|
||||
var mainDriver = new EssentialsPanelMainInterfaceDriver(Panel, props);
|
||||
// Then the AV driver
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.UI;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.PageManagers;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class EssentialsTouchpanelController : Device
|
||||
{
|
||||
public BasicTriListWithSmartObject Panel { get; private set; }
|
||||
|
||||
public PanelDriverBase PanelDriver { get; private set; }
|
||||
|
||||
CTimer BacklightTransitionedOnTimer;
|
||||
|
||||
public EssentialsTouchpanelController(string key, string name, Tswx52ButtonVoiceControl tsw,
|
||||
string projectName, string sgdPath)
|
||||
: base(key, name)
|
||||
{
|
||||
Panel = tsw;
|
||||
tsw.LoadSmartObjects(sgdPath);
|
||||
tsw.SigChange += new Crestron.SimplSharpPro.DeviceSupport.SigEventHandler(Tsw_SigChange);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Config constructor
|
||||
/// </summary>
|
||||
public EssentialsTouchpanelController(string key, string name, string type, CrestronTouchpanelPropertiesConfig props, uint id)
|
||||
: base(key, name)
|
||||
{
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
Debug.Console(2, this, "post-activation linking");
|
||||
type = type.ToLower();
|
||||
try
|
||||
{
|
||||
if (type == "crestronapp")
|
||||
{
|
||||
var app = new CrestronApp(id, Global.ControlSystem);
|
||||
app.ParameterProjectName.Value = props.ProjectName;
|
||||
Panel = app;
|
||||
}
|
||||
else if (type == "tsw752")
|
||||
Panel = new Tsw752(id, Global.ControlSystem);
|
||||
else if (type == "tsw1052")
|
||||
Panel = new Tsw1052(id, Global.ControlSystem);
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "WARNING: Cannot create TSW controller with type '{0}'", type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, this, "WARNING: Cannot create TSW base class. Panel will not function: {0}", e.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
// Reserved sigs
|
||||
if (Panel is TswFt5ButtonSystem)
|
||||
{
|
||||
var tsw = Panel as TswFt5ButtonSystem;
|
||||
tsw.ExtenderSystemReservedSigs.Use();
|
||||
tsw.ExtenderSystemReservedSigs.DeviceExtenderSigChange
|
||||
+= ExtenderSystemReservedSigs_DeviceExtenderSigChange;
|
||||
}
|
||||
|
||||
new CTimer(o =>
|
||||
{
|
||||
var regSuccess = Panel.Register();
|
||||
if (regSuccess != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
Debug.Console(0, this, "WARNING: Registration failed. Continuing, but panel may not function: {0}", regSuccess);
|
||||
|
||||
// Give up cleanly if SGD is not present.
|
||||
var sgdName = @"\NVRAM\Program" + InitialParametersClass.ApplicationNumber
|
||||
+ @"\sgd\" + props.SgdFile;
|
||||
if (!File.Exists(sgdName))
|
||||
{
|
||||
Debug.Console(0, this, "WARNING: Smart object file '{0}' not present. Exiting TSW load", sgdName);
|
||||
return;
|
||||
}
|
||||
|
||||
Panel.LoadSmartObjects(sgdName);
|
||||
Panel.SigChange += Tsw_SigChange;
|
||||
|
||||
var mainDriver = new EssentialsPanelMainInterfaceDriver(Panel, props);
|
||||
// Then the AV driver
|
||||
|
||||
// spin up different room drivers depending on room type
|
||||
var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey);
|
||||
if (room is EssentialsHuddleSpaceRoom)
|
||||
{
|
||||
Debug.Console(0, this, "Adding huddle space driver");
|
||||
var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props);
|
||||
avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom;
|
||||
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
||||
mainDriver.AvDriver = avDriver;
|
||||
LoadAndShowDriver(mainDriver); // This is a little convoluted.
|
||||
|
||||
if (Panel is TswFt5ButtonSystem)
|
||||
{
|
||||
var tsw = Panel as TswFt5ButtonSystem;
|
||||
// Wire up hard keys
|
||||
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.PowerButtonPressed(); });
|
||||
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
|
||||
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
|
||||
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
||||
tsw.ButtonStateChange += new ButtonEventHandler(Tsw_ButtonStateChange);
|
||||
}
|
||||
}
|
||||
else if (room is EssentialsPresentationRoom)
|
||||
{
|
||||
Debug.Console(0, this, "Adding presentation room driver");
|
||||
var avDriver = new EssentialsPresentationPanelAvFunctionsDriver(mainDriver, props);
|
||||
avDriver.CurrentRoom = room as EssentialsPresentationRoom;
|
||||
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
||||
mainDriver.AvDriver = avDriver;
|
||||
LoadAndShowDriver(mainDriver);
|
||||
|
||||
if (Panel is TswFt5ButtonSystem)
|
||||
{
|
||||
var tsw = Panel as TswFt5ButtonSystem;
|
||||
// Wire up hard keys
|
||||
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.PowerButtonPressed(); });
|
||||
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
|
||||
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
|
||||
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
||||
tsw.ButtonStateChange += new ButtonEventHandler(Tsw_ButtonStateChange);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "ERROR: Cannot load AvFunctionsDriver for room '{0}'", props.DefaultRoomKey);
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
|
||||
public void LoadAndShowDriver(PanelDriverBase driver)
|
||||
{
|
||||
PanelDriver = driver;
|
||||
driver.Show();
|
||||
}
|
||||
|
||||
void HomePressed()
|
||||
{
|
||||
if (BacklightTransitionedOnTimer != null)
|
||||
Debug.Console(2, this, "Home pressed from dark screen");
|
||||
else
|
||||
PanelDriver.BackButtonPressed();
|
||||
}
|
||||
|
||||
|
||||
void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
|
||||
{
|
||||
// If the sig is transitioning on, mark it in case it was home button that transitioned it
|
||||
var blOnSig = (Panel as TswFt5ButtonSystem).ExtenderSystemReservedSigs.BacklightOnFeedback;
|
||||
if (args.Sig == blOnSig && blOnSig.BoolValue)
|
||||
{
|
||||
Debug.Console(2, this, "Backlight transitioning on");
|
||||
BacklightTransitionedOnTimer = new CTimer(o =>
|
||||
{
|
||||
BacklightTransitionedOnTimer = null;
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
|
||||
void Tsw_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
|
||||
{
|
||||
if (Debug.Level == 2)
|
||||
Debug.Console(2, this, "Sig change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
|
||||
var uo = args.Sig.UserObject;
|
||||
if (uo is Action<bool>)
|
||||
(uo as Action<bool>)(args.Sig.BoolValue);
|
||||
else if (uo is Action<ushort>)
|
||||
(uo as Action<ushort>)(args.Sig.UShortValue);
|
||||
else if (uo is Action<string>)
|
||||
(uo as Action<string>)(args.Sig.StringValue);
|
||||
}
|
||||
|
||||
void Tsw_ButtonStateChange(GenericBase device, ButtonEventArgs args)
|
||||
{
|
||||
var uo = args.Button.UserObject;
|
||||
if(uo is Action<bool>)
|
||||
(uo as Action<bool>)(args.Button.State == eButtonState.Pressed);
|
||||
}
|
||||
}
|
||||
var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey);
|
||||
if (room is EssentialsHuddleSpaceRoom)
|
||||
{
|
||||
Debug.Console(0, this, "Adding huddle space driver");
|
||||
var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props);
|
||||
avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom;
|
||||
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
||||
mainDriver.AvDriver = avDriver;
|
||||
LoadAndShowDriver(mainDriver); // This is a little convoluted.
|
||||
|
||||
if (Panel is TswFt5ButtonSystem)
|
||||
{
|
||||
var tsw = Panel as TswFt5ButtonSystem;
|
||||
// Wire up hard keys
|
||||
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.PowerButtonPressed(); });
|
||||
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
|
||||
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
|
||||
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
||||
tsw.ButtonStateChange += new ButtonEventHandler(Tsw_ButtonStateChange);
|
||||
}
|
||||
}
|
||||
else if (room is EssentialsPresentationRoom)
|
||||
{
|
||||
Debug.Console(0, this, "Adding presentation room driver");
|
||||
var avDriver = new EssentialsPresentationPanelAvFunctionsDriver(mainDriver, props);
|
||||
avDriver.CurrentRoom = room as EssentialsPresentationRoom;
|
||||
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
||||
mainDriver.AvDriver = avDriver;
|
||||
LoadAndShowDriver(mainDriver);
|
||||
|
||||
if (Panel is TswFt5ButtonSystem)
|
||||
{
|
||||
var tsw = Panel as TswFt5ButtonSystem;
|
||||
// Wire up hard keys
|
||||
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.PowerButtonPressed(); });
|
||||
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
|
||||
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
|
||||
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
||||
tsw.ButtonStateChange += new ButtonEventHandler(Tsw_ButtonStateChange);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "ERROR: Cannot load AvFunctionsDriver for room '{0}'", props.DefaultRoomKey);
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
|
||||
public void LoadAndShowDriver(PanelDriverBase driver)
|
||||
{
|
||||
PanelDriver = driver;
|
||||
driver.Show();
|
||||
}
|
||||
|
||||
void HomePressed()
|
||||
{
|
||||
if (BacklightTransitionedOnTimer != null)
|
||||
Debug.Console(2, this, "Home pressed from dark screen");
|
||||
else
|
||||
PanelDriver.BackButtonPressed();
|
||||
}
|
||||
|
||||
|
||||
void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
|
||||
{
|
||||
// If the sig is transitioning on, mark it in case it was home button that transitioned it
|
||||
var blOnSig = (Panel as TswFt5ButtonSystem).ExtenderSystemReservedSigs.BacklightOnFeedback;
|
||||
if (args.Sig == blOnSig && blOnSig.BoolValue)
|
||||
{
|
||||
Debug.Console(2, this, "Backlight transitioning on");
|
||||
BacklightTransitionedOnTimer = new CTimer(o =>
|
||||
{
|
||||
BacklightTransitionedOnTimer = null;
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
|
||||
void Tsw_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
|
||||
{
|
||||
if (Debug.Level == 2)
|
||||
Debug.Console(2, this, "Sig change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
|
||||
var uo = args.Sig.UserObject;
|
||||
if (uo is Action<bool>)
|
||||
(uo as Action<bool>)(args.Sig.BoolValue);
|
||||
else if (uo is Action<ushort>)
|
||||
(uo as Action<ushort>)(args.Sig.UShortValue);
|
||||
else if (uo is Action<string>)
|
||||
(uo as Action<string>)(args.Sig.StringValue);
|
||||
}
|
||||
|
||||
void Tsw_ButtonStateChange(GenericBase device, ButtonEventArgs args)
|
||||
{
|
||||
var uo = args.Button.UserObject;
|
||||
if(uo is Action<bool>)
|
||||
(uo as Action<bool>)(args.Button.State == eButtonState.Pressed);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user