mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-29 04:15:00 +00:00
feat: removed deprecated diplay devices
This commit is contained in:
@@ -1,455 +0,0 @@
|
||||
extern alias Full;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using Full.Newtonsoft.Json;
|
||||
using Full.Newtonsoft.Json.Linq;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common
|
||||
{
|
||||
public class IRBlurayBase : EssentialsBridgeableDevice, IDiscPlayerControls, IUiDisplayInfo, IRoutingOutputs, IUsageTracking
|
||||
{
|
||||
public IrOutputPortController IrPort { get; private set; }
|
||||
|
||||
public uint DisplayUiType { get { return DisplayUiConstants.TypeBluray; } }
|
||||
|
||||
public IRBlurayBase(string key, string name, IrOutputPortController portCont)
|
||||
: base(key, name)
|
||||
{
|
||||
IrPort = portCont;
|
||||
DeviceManager.AddDevice(portCont);
|
||||
|
||||
HasKeypadAccessoryButton1 = true;
|
||||
KeypadAccessoryButton1Command = "Clear";
|
||||
KeypadAccessoryButton1Label = "Clear";
|
||||
|
||||
HasKeypadAccessoryButton2 = true;
|
||||
KeypadAccessoryButton2Command = "NumericEnter";
|
||||
KeypadAccessoryButton2Label = "Enter";
|
||||
|
||||
PowerIsOnFeedback = new BoolFeedback(() => _PowerIsOn);
|
||||
|
||||
HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, null, this);
|
||||
AnyAudioOut = new RoutingOutputPort(RoutingPortNames.AnyAudioOut, eRoutingSignalType.Audio,
|
||||
eRoutingPortConnectionType.DigitalAudio, null, this);
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { HdmiOut, AnyAudioOut };
|
||||
}
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new IRBlurayBaseJoinMap(joinStart);
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<IRBlurayBaseJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
Debug.Console(0, "Linking to SetTopBox: {0}", Name);
|
||||
|
||||
|
||||
trilist.OnlineStatusChange += new OnlineStatusChangeEventHandler((o, a) =>
|
||||
{
|
||||
if (a.DeviceOnLine)
|
||||
{
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = Name;
|
||||
}
|
||||
});
|
||||
|
||||
var powerDev = this as IHasPowerControl;
|
||||
if (powerDev != null)
|
||||
{
|
||||
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, powerDev.PowerOn);
|
||||
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, powerDev.PowerOff);
|
||||
trilist.SetSigTrueAction(joinMap.PowerToggle.JoinNumber, powerDev.PowerToggle);
|
||||
}
|
||||
|
||||
var dpadDev = this as IDPad;
|
||||
if (dpadDev != null)
|
||||
{
|
||||
trilist.SetBoolSigAction(joinMap.Up.JoinNumber, dpadDev.Up);
|
||||
trilist.SetBoolSigAction(joinMap.Down.JoinNumber, dpadDev.Down);
|
||||
trilist.SetBoolSigAction(joinMap.Left.JoinNumber, dpadDev.Left);
|
||||
trilist.SetBoolSigAction(joinMap.Right.JoinNumber, dpadDev.Right);
|
||||
trilist.SetBoolSigAction(joinMap.Select.JoinNumber, dpadDev.Select);
|
||||
trilist.SetBoolSigAction(joinMap.Menu.JoinNumber, dpadDev.Menu);
|
||||
trilist.SetBoolSigAction(joinMap.Exit.JoinNumber, dpadDev.Exit);
|
||||
}
|
||||
|
||||
var channelDev = this as IChannel;
|
||||
if (channelDev != null)
|
||||
{
|
||||
trilist.SetBoolSigAction(joinMap.ChannelUp.JoinNumber, channelDev.ChannelUp);
|
||||
trilist.SetBoolSigAction(joinMap.ChannelDown.JoinNumber, channelDev.ChannelDown);
|
||||
trilist.SetBoolSigAction(joinMap.LastChannel.JoinNumber, channelDev.LastChannel);
|
||||
trilist.SetBoolSigAction(joinMap.Guide.JoinNumber, channelDev.Guide);
|
||||
trilist.SetBoolSigAction(joinMap.Info.JoinNumber, channelDev.Info);
|
||||
trilist.SetBoolSigAction(joinMap.Exit.JoinNumber, channelDev.Exit);
|
||||
}
|
||||
|
||||
var colorDev = this as IColor;
|
||||
if (colorDev != null)
|
||||
{
|
||||
trilist.SetBoolSigAction(joinMap.Red.JoinNumber, colorDev.Red);
|
||||
trilist.SetBoolSigAction(joinMap.Green.JoinNumber, colorDev.Green);
|
||||
trilist.SetBoolSigAction(joinMap.Yellow.JoinNumber, colorDev.Yellow);
|
||||
trilist.SetBoolSigAction(joinMap.Blue.JoinNumber, colorDev.Blue);
|
||||
}
|
||||
|
||||
var keypadDev = this as ISetTopBoxNumericKeypad;
|
||||
if (keypadDev != null)
|
||||
{
|
||||
trilist.StringInput[joinMap.KeypadAccessoryButton1Label.JoinNumber].StringValue = keypadDev.KeypadAccessoryButton1Label;
|
||||
trilist.StringInput[joinMap.KeypadAccessoryButton2Label.JoinNumber].StringValue = keypadDev.KeypadAccessoryButton2Label;
|
||||
|
||||
trilist.BooleanInput[joinMap.HasKeypadAccessoryButton1.JoinNumber].BoolValue = keypadDev.HasKeypadAccessoryButton1;
|
||||
trilist.BooleanInput[joinMap.HasKeypadAccessoryButton2.JoinNumber].BoolValue = keypadDev.HasKeypadAccessoryButton2;
|
||||
|
||||
trilist.SetBoolSigAction(joinMap.Digit0.JoinNumber, keypadDev.Digit0);
|
||||
trilist.SetBoolSigAction(joinMap.Digit1.JoinNumber, keypadDev.Digit1);
|
||||
trilist.SetBoolSigAction(joinMap.Digit2.JoinNumber, keypadDev.Digit2);
|
||||
trilist.SetBoolSigAction(joinMap.Digit3.JoinNumber, keypadDev.Digit3);
|
||||
trilist.SetBoolSigAction(joinMap.Digit4.JoinNumber, keypadDev.Digit4);
|
||||
trilist.SetBoolSigAction(joinMap.Digit5.JoinNumber, keypadDev.Digit5);
|
||||
trilist.SetBoolSigAction(joinMap.Digit6.JoinNumber, keypadDev.Digit6);
|
||||
trilist.SetBoolSigAction(joinMap.Digit7.JoinNumber, keypadDev.Digit7);
|
||||
trilist.SetBoolSigAction(joinMap.Digit8.JoinNumber, keypadDev.Digit8);
|
||||
trilist.SetBoolSigAction(joinMap.Digit9.JoinNumber, keypadDev.Digit9);
|
||||
trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton1Press.JoinNumber, keypadDev.KeypadAccessoryButton1);
|
||||
trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton2Press.JoinNumber, keypadDev.KeypadAccessoryButton1);
|
||||
trilist.SetBoolSigAction(joinMap.KeypadEnter.JoinNumber, keypadDev.KeypadEnter);
|
||||
}
|
||||
|
||||
var transportDev = this as ITransport;
|
||||
if (transportDev != null)
|
||||
{
|
||||
trilist.SetBoolSigAction(joinMap.Play.JoinNumber, transportDev.Play);
|
||||
trilist.SetBoolSigAction(joinMap.Pause.JoinNumber, transportDev.Pause);
|
||||
trilist.SetBoolSigAction(joinMap.Rewind.JoinNumber, transportDev.Rewind);
|
||||
trilist.SetBoolSigAction(joinMap.FFwd.JoinNumber, transportDev.FFwd);
|
||||
trilist.SetBoolSigAction(joinMap.ChapMinus.JoinNumber, transportDev.ChapMinus);
|
||||
trilist.SetBoolSigAction(joinMap.ChapPlus.JoinNumber, transportDev.ChapPlus);
|
||||
trilist.SetBoolSigAction(joinMap.Stop.JoinNumber, transportDev.Stop);
|
||||
trilist.SetBoolSigAction(joinMap.Record.JoinNumber, transportDev.Record);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region IDPad Members
|
||||
|
||||
public void Up(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_UP_ARROW, pressRelease);
|
||||
}
|
||||
|
||||
public void Down(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_DN_ARROW, pressRelease);
|
||||
}
|
||||
|
||||
public void Left(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_LEFT_ARROW, pressRelease);
|
||||
}
|
||||
|
||||
public void Right(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_RIGHT_ARROW, pressRelease);
|
||||
}
|
||||
|
||||
public void Select(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_ENTER, pressRelease);
|
||||
}
|
||||
|
||||
public void Menu(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_MENU, pressRelease);
|
||||
}
|
||||
|
||||
public void Exit(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_EXIT, pressRelease);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region INumericKeypad Members
|
||||
|
||||
public void Digit0(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_0, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit1(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_1, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit2(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_2, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit3(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_3, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit4(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_4, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit5(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_5, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit6(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_6, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit7(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_7, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit8(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_8, pressRelease);
|
||||
}
|
||||
|
||||
public void Digit9(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_9, pressRelease);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defaults to true
|
||||
/// </summary>
|
||||
public bool HasKeypadAccessoryButton1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defaults to "-"
|
||||
/// </summary>
|
||||
public string KeypadAccessoryButton1Label { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Defaults to "Dash"
|
||||
/// </summary>
|
||||
public string KeypadAccessoryButton1Command { get; set; }
|
||||
|
||||
public void KeypadAccessoryButton1(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(KeypadAccessoryButton1Command, pressRelease);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defaults to true
|
||||
/// </summary>
|
||||
public bool HasKeypadAccessoryButton2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defaults to "Enter"
|
||||
/// </summary>
|
||||
public string KeypadAccessoryButton2Label { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Defaults to "Enter"
|
||||
/// </summary>
|
||||
public string KeypadAccessoryButton2Command { get; set; }
|
||||
|
||||
public void KeypadAccessoryButton2(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(KeypadAccessoryButton2Command, pressRelease);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IChannelFunctions Members
|
||||
|
||||
public void ChannelUp(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_CH_PLUS, pressRelease);
|
||||
}
|
||||
|
||||
public void ChannelDown(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_CH_MINUS, pressRelease);
|
||||
}
|
||||
|
||||
public void LastChannel(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_LAST, pressRelease);
|
||||
}
|
||||
|
||||
public void Guide(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_GUIDE, pressRelease);
|
||||
}
|
||||
|
||||
public void Info(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_INFO, pressRelease);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IColorFunctions Members
|
||||
|
||||
public void Red(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_RED, pressRelease);
|
||||
}
|
||||
|
||||
public void Green(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_GREEN, pressRelease);
|
||||
}
|
||||
|
||||
public void Yellow(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_YELLOW, pressRelease);
|
||||
}
|
||||
|
||||
public void Blue(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_BLUE, pressRelease);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRoutingOutputs Members
|
||||
|
||||
public RoutingOutputPort HdmiOut { get; private set; }
|
||||
public RoutingOutputPort AnyAudioOut { get; private set; }
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPower Members
|
||||
|
||||
public void PowerOn()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, 200);
|
||||
_PowerIsOn = true;
|
||||
}
|
||||
|
||||
public void PowerOff()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, 200);
|
||||
_PowerIsOn = false;
|
||||
}
|
||||
|
||||
public void PowerToggle()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER, 200);
|
||||
_PowerIsOn = false;
|
||||
}
|
||||
|
||||
public BoolFeedback PowerIsOnFeedback { get; set; }
|
||||
bool _PowerIsOn;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ITransport Members
|
||||
|
||||
public void Play(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_PLAY, pressRelease);
|
||||
}
|
||||
|
||||
public void Pause(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_PAUSE, pressRelease);
|
||||
}
|
||||
|
||||
public void Rewind(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_RSCAN, pressRelease);
|
||||
}
|
||||
|
||||
public void FFwd(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_FSCAN, pressRelease);
|
||||
}
|
||||
|
||||
public void ChapMinus(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_TRACK_MINUS, pressRelease);
|
||||
}
|
||||
|
||||
public void ChapPlus(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_TRACK_PLUS, pressRelease);
|
||||
}
|
||||
|
||||
public void Stop(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_STOP, pressRelease);
|
||||
}
|
||||
|
||||
public void Record(bool pressRelease)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IUsageTracking Members
|
||||
|
||||
public UsageTracking UsageTracker { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class IRBlurayBaseFactory : EssentialsDeviceFactory<IRBlurayBase>
|
||||
{
|
||||
public IRBlurayBaseFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "discplayer", "bluray" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new IRBlurayPlayer Device");
|
||||
|
||||
if (dc.Properties["control"]["method"].Value<string>() == "ir")
|
||||
{
|
||||
var irCont = IRPortHelper.GetIrOutputPortController(dc);
|
||||
return new IRBlurayBase(dc.Key, dc.Name, irCont);
|
||||
}
|
||||
else if (dc.Properties["control"]["method"].Value<string>() == "com")
|
||||
{
|
||||
Debug.Console(0, "[{0}] COM Device type not implemented YET!", dc.Key);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,749 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.CrestronThread;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Displays
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class AvocorDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, ICommunicationMonitor, IInputDisplayPort1,
|
||||
IInputHdmi1, IInputHdmi2, IInputHdmi3, IInputHdmi4, IInputVga1, IBridgeAdvanced
|
||||
{
|
||||
public IBasicCommunication Communication { get; private set; }
|
||||
public CommunicationGather PortGather { get; private set; }
|
||||
|
||||
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
||||
|
||||
public byte ID { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 0x08
|
||||
/// </summary>
|
||||
const byte InputVga1Value = 0x00;
|
||||
/// <summary>
|
||||
/// 0x09
|
||||
/// </summary>
|
||||
const byte InputHdmi1Value = 0x09;
|
||||
/// <summary>
|
||||
/// 0x0a
|
||||
/// </summary>
|
||||
const byte InputHdmi2Value = 0x0a;
|
||||
/// <summary>
|
||||
/// 0x0b
|
||||
/// </summary>
|
||||
const byte InputHdmi3Value = 0x0b;
|
||||
/// <summary>
|
||||
/// 0x0c
|
||||
/// </summary>
|
||||
const byte InputHdmi4Value = 0x0c;
|
||||
/// <summary>
|
||||
/// 0c0d
|
||||
/// </summary>
|
||||
const byte InputDisplayPort1Value = 0x0d;
|
||||
/// <summary>
|
||||
/// 0x0e
|
||||
/// </summary>
|
||||
const byte InputIpcOpsValue = 0x0e;
|
||||
/// <summary>
|
||||
/// 0x11
|
||||
/// </summary>
|
||||
const byte InputHdmi5Value = 0x11;
|
||||
/// <summary>
|
||||
/// 0x12
|
||||
/// </summary>
|
||||
const byte InputMediaPlayerValue = 0x12;
|
||||
|
||||
|
||||
bool _PowerIsOn;
|
||||
bool _IsWarmingUp;
|
||||
bool _IsCoolingDown;
|
||||
ushort _VolumeLevelForSig;
|
||||
int _LastVolumeSent;
|
||||
ushort _PreMuteVolumeLevel;
|
||||
bool _IsMuted;
|
||||
RoutingInputPort _CurrentInputPort;
|
||||
ActionIncrementer VolumeIncrementer;
|
||||
bool VolumeIsRamping;
|
||||
public bool IsInStandby { get; private set; }
|
||||
|
||||
protected override Func<bool> PowerIsOnFeedbackFunc { get { return () => _PowerIsOn; } }
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
|
||||
protected override Func<bool> IsWarmingUpFeedbackFunc { get { return () => _IsWarmingUp; } }
|
||||
protected override Func<string> CurrentInputFeedbackFunc { get { return () => _CurrentInputPort.Key; } }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for IBasicCommunication
|
||||
/// </summary>
|
||||
public AvocorDisplay(string key, string name, IBasicCommunication comm, string id)
|
||||
: base(key, name)
|
||||
{
|
||||
Communication = comm;
|
||||
//Communication.BytesReceived += new EventHandler<GenericCommMethodReceiveBytesArgs>(Communication_BytesReceived);
|
||||
|
||||
PortGather = new CommunicationGather(Communication, '\x08');
|
||||
PortGather.IncludeDelimiter = true;
|
||||
PortGather.LineReceived += new EventHandler<GenericCommMethodReceiveTextArgs>(PortGather_LineReceived);
|
||||
|
||||
ID = id == null ? (byte)0x01 : Convert.ToByte(id, 16); // If id is null, set default value of 0x01, otherwise assign value passed in constructor
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for TCP
|
||||
/// </summary>
|
||||
public AvocorDisplay(string key, string name, string hostname, int port, string id)
|
||||
: base(key, name)
|
||||
{
|
||||
Communication = new GenericTcpIpClient(key + "-tcp", hostname, port, 5000);
|
||||
|
||||
PortGather = new CommunicationGather(Communication, '\x0d');
|
||||
PortGather.IncludeDelimiter = true;
|
||||
PortGather.LineReceived += new EventHandler<GenericCommMethodReceiveTextArgs>(PortGather_LineReceived);
|
||||
|
||||
ID = id == null ? (byte)0x01 : Convert.ToByte(id, 16); // If id is null, set default value of 0x01, otherwise assign value passed in constructor
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for COM
|
||||
/// </summary>
|
||||
public AvocorDisplay(string key, string name, ComPort port, ComPort.ComPortSpec spec, string id)
|
||||
: base(key, name)
|
||||
{
|
||||
Communication = new ComPortController(key + "-com", port, spec);
|
||||
|
||||
PortGather = new CommunicationGather(Communication, '\x0d');
|
||||
PortGather.IncludeDelimiter = true;
|
||||
PortGather.LineReceived += new EventHandler<GenericCommMethodReceiveTextArgs>(PortGather_LineReceived);
|
||||
|
||||
ID = id == null ? (byte)0x01 : Convert.ToByte(id, 16); // If id is null, set default value of 0x01, otherwise assign value passed in constructor
|
||||
Init();
|
||||
}
|
||||
|
||||
void AddRoutingInputPort(RoutingInputPort port, byte fbMatch)
|
||||
{
|
||||
port.FeedbackMatchObject = fbMatch;
|
||||
InputPorts.Add(port);
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
WarmupTime = 10000;
|
||||
CooldownTime = 8000;
|
||||
|
||||
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 30000, 120000, 300000, StatusGet);
|
||||
DeviceManager.AddDevice(CommunicationMonitor);
|
||||
|
||||
VolumeIncrementer = new ActionIncrementer(655, 0, 65535, 800, 80,
|
||||
v => SetVolume((ushort)v),
|
||||
() => _LastVolumeSent);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi1), this), InputHdmi1Value);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi2), this), InputHdmi2Value);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi3), this), InputHdmi3Value);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi4), this), InputHdmi4Value);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.HdmiIn5, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi5), this), InputHdmi5Value);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.DisplayPortIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.DisplayPort, new Action(InputDisplayPort1), this), InputDisplayPort1Value);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.VgaIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Dvi, new Action(InputVga1), this), InputVga1Value);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.IpcOps, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Composite, new Action(InputIpcOps), this), InputIpcOpsValue);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.MediaPlayer, eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Vga, new Action(InputMediaPlayer), this), InputMediaPlayerValue);
|
||||
|
||||
VolumeLevelFeedback = new IntFeedback(() => { return _VolumeLevelForSig; });
|
||||
MuteFeedback = new BoolFeedback(() => _IsMuted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
Communication.Connect();
|
||||
|
||||
var socket = Communication as ISocketStatus;
|
||||
if (socket != null)
|
||||
{
|
||||
socket.ConnectionChange += new EventHandler<GenericSocketStatusChageEventArgs>(socket_ConnectionChange);
|
||||
}
|
||||
|
||||
CommunicationMonitor.StatusChange += (o, a) => { Debug.Console(2, this, "Communication monitor state: {0}", CommunicationMonitor.Status); };
|
||||
CommunicationMonitor.Start();
|
||||
|
||||
StatusGet();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
|
||||
void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e)
|
||||
{
|
||||
if (e.Client.IsConnected)
|
||||
StatusGet();
|
||||
}
|
||||
|
||||
public override FeedbackCollection<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
var list = base.Feedbacks;
|
||||
list.AddRange(new List<Feedback>
|
||||
{
|
||||
VolumeLevelFeedback,
|
||||
MuteFeedback,
|
||||
CurrentInputFeedback
|
||||
});
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// /
|
||||
///// </summary>
|
||||
///// <param name="sender"></param>
|
||||
//void Communication_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e)
|
||||
//{
|
||||
// // This is probably not thread-safe buffering
|
||||
// // Append the incoming bytes with whatever is in the buffer
|
||||
// var newBytes = new byte[IncomingBuffer.Length + e.Bytes.Length];
|
||||
// IncomingBuffer.CopyTo(newBytes, 0);
|
||||
// e.Bytes.CopyTo(newBytes, IncomingBuffer.Length);
|
||||
|
||||
// if (Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1
|
||||
// Debug.Console(2, this, "Received:{0}", ComTextHelper.GetEscapedText(newBytes));
|
||||
|
||||
// // Need to find AA FF and have
|
||||
// for (int i = 0; i < newBytes.Length; i++)
|
||||
// {
|
||||
// if (newBytes[i] == 0xAA && newBytes[i + 1] == 0xFF)
|
||||
// {
|
||||
// newBytes = newBytes.Skip(i).ToArray(); // Trim off junk if there's "dirt" in the buffer
|
||||
|
||||
// // parse it
|
||||
// // If it's at least got the header, then process it,
|
||||
// while (newBytes.Length > 4 && newBytes[0] == 0xAA && newBytes[1] == 0xFF)
|
||||
// {
|
||||
// var msgLen = newBytes[3];
|
||||
// // if the buffer is shorter than the header (3) + message (msgLen) + checksum (1),
|
||||
// // give and save it for next time
|
||||
// if (newBytes.Length < msgLen + 4)
|
||||
// break;
|
||||
|
||||
// // Good length, grab the message
|
||||
// var message = newBytes.Skip(4).Take(msgLen).ToArray();
|
||||
|
||||
// // At this point, the ack/nak is the first byte
|
||||
// if (message[0] == 0x41)
|
||||
// {
|
||||
// switch (message[1]) // type byte
|
||||
// {
|
||||
// case 0x00: // General status
|
||||
// UpdatePowerFB(message[2], message[5]); // "power" can be misrepresented when the display sleeps
|
||||
// UpdateInputFb(message[5]);
|
||||
// UpdateVolumeFB(message[3]);
|
||||
// UpdateMuteFb(message[4]);
|
||||
// UpdateInputFb(message[5]);
|
||||
// break;
|
||||
|
||||
// case 0x11:
|
||||
// UpdatePowerFB(message[2]);
|
||||
// break;
|
||||
|
||||
// case 0x12:
|
||||
// UpdateVolumeFB(message[2]);
|
||||
// break;
|
||||
|
||||
// case 0x13:
|
||||
// UpdateMuteFb(message[2]);
|
||||
// break;
|
||||
|
||||
// case 0x14:
|
||||
// UpdateInputFb(message[2]);
|
||||
// break;
|
||||
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// // Skip over what we've used and save the rest for next time
|
||||
// newBytes = newBytes.Skip(5 + msgLen).ToArray();
|
||||
// }
|
||||
|
||||
// break; // parsing will mean we can stop looking for header in loop
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Save whatever partial message is here
|
||||
// IncomingBuffer = newBytes;
|
||||
//}
|
||||
|
||||
void PortGather_LineReceived(object sender, GenericCommMethodReceiveTextArgs e)
|
||||
{
|
||||
Debug.Console(1, this, "Receivied: '{0}'", ComTextHelper.GetEscapedText(e.Text));
|
||||
|
||||
if (e.Text.IndexOf("\x50\x4F\x57") > -1)
|
||||
{
|
||||
// Power Status Response
|
||||
|
||||
var value = e.Text.ToCharArray();
|
||||
|
||||
switch (value[6])
|
||||
{
|
||||
case '\x00':
|
||||
{
|
||||
_PowerIsOn = false;
|
||||
break;
|
||||
}
|
||||
case '\x01':
|
||||
{
|
||||
_PowerIsOn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
Debug.Console(1, this, "PowerIsOn State: {0}", PowerIsOnFeedback.BoolValue);
|
||||
|
||||
}
|
||||
else if (e.Text.IndexOf("\x4D\x49\x4E") > -1)
|
||||
{
|
||||
var value = e.Text.ToCharArray();
|
||||
|
||||
var b = value[6];
|
||||
|
||||
var newInput = InputPorts.FirstOrDefault(i => i.FeedbackMatchObject.Equals(b));
|
||||
if (newInput != null && newInput != _CurrentInputPort)
|
||||
{
|
||||
_CurrentInputPort = newInput;
|
||||
CurrentInputFeedback.FireUpdate();
|
||||
Debug.Console(1, this, "Current Input: {0}", CurrentInputFeedback.StringValue);
|
||||
}
|
||||
|
||||
}
|
||||
else if (e.Text.IndexOf("\x56\x4F\x4C") > -1)
|
||||
{
|
||||
// Volume Status Response
|
||||
|
||||
var value = e.Text.ToCharArray();
|
||||
|
||||
var b = value[6];
|
||||
|
||||
var newVol = (ushort)NumericalHelpers.Scale((double)b, 0, 100, 0, 65535);
|
||||
if (!VolumeIsRamping)
|
||||
_LastVolumeSent = newVol;
|
||||
if (newVol != _VolumeLevelForSig)
|
||||
{
|
||||
_VolumeLevelForSig = newVol;
|
||||
VolumeLevelFeedback.FireUpdate();
|
||||
|
||||
if (_VolumeLevelForSig > 0)
|
||||
_IsMuted = false;
|
||||
else
|
||||
_IsMuted = true;
|
||||
|
||||
MuteFeedback.FireUpdate();
|
||||
|
||||
Debug.Console(1, this, "Volume Level: {0}", VolumeLevelFeedback.IntValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void UpdatePowerFB(byte powerByte)
|
||||
{
|
||||
var newVal = powerByte == 1;
|
||||
if (newVal != _PowerIsOn)
|
||||
{
|
||||
_PowerIsOn = newVal;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates power status from general updates where source is included.
|
||||
/// Compensates for errant standby / power off hiccups by ignoring
|
||||
/// power off states with input < 0x10
|
||||
/// </summary>
|
||||
void UpdatePowerFB(byte powerByte, byte inputByte)
|
||||
{
|
||||
// This should reject errant power feedbacks when switching away from input on standby.
|
||||
if (powerByte == 0x01 && inputByte < 0x10)
|
||||
IsInStandby = true;
|
||||
if (powerByte == 0x00 && IsInStandby) // Ignore power off if coming from standby - glitch
|
||||
{
|
||||
IsInStandby = false;
|
||||
return;
|
||||
}
|
||||
|
||||
UpdatePowerFB(powerByte);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void UpdateVolumeFB(byte b)
|
||||
{
|
||||
var newVol = (ushort)NumericalHelpers.Scale((double)b, 0, 100, 0, 65535);
|
||||
if (!VolumeIsRamping)
|
||||
_LastVolumeSent = newVol;
|
||||
if (newVol != _VolumeLevelForSig)
|
||||
{
|
||||
_VolumeLevelForSig = newVol;
|
||||
VolumeLevelFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void UpdateMuteFb(byte b)
|
||||
{
|
||||
var newMute = b == 1;
|
||||
if (newMute != _IsMuted)
|
||||
{
|
||||
_IsMuted = newMute;
|
||||
MuteFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void UpdateInputFb(byte b)
|
||||
{
|
||||
var newInput = InputPorts.FirstOrDefault(i => i.FeedbackMatchObject.Equals(b));
|
||||
if (newInput != null && newInput != _CurrentInputPort)
|
||||
{
|
||||
_CurrentInputPort = newInput;
|
||||
CurrentInputFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats an outgoing message. Replaces third byte with ID and replaces last byte with checksum
|
||||
/// </summary>
|
||||
/// <param name="b"></param>
|
||||
void SendBytes(byte[] b)
|
||||
{
|
||||
b[1] = ID;
|
||||
|
||||
var command = b.ToString();
|
||||
|
||||
Debug.Console(1, this, "Sending: '{0}'",ComTextHelper.GetEscapedText(b));
|
||||
|
||||
Communication.SendBytes(b);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void StatusGet()
|
||||
{
|
||||
PowerGet();
|
||||
|
||||
CrestronEnvironment.Sleep(100);
|
||||
|
||||
InputGet();
|
||||
|
||||
CrestronEnvironment.Sleep(100);
|
||||
|
||||
VolumeGet();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void PowerOn()
|
||||
{
|
||||
//Send(PowerOnCmd);
|
||||
SendBytes(new byte[] { 0x07, ID, 0x02, 0x50, 0x4F, 0x57, 0x01, 0x08, 0x0d });
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void PowerOff()
|
||||
{
|
||||
// If a display has unreliable-power off feedback, just override this and
|
||||
// remove this check.
|
||||
if (!_IsWarmingUp && !_IsCoolingDown) // PowerIsOnFeedback.BoolValue &&
|
||||
{
|
||||
//Send(PowerOffCmd);
|
||||
SendBytes(new byte[] { 0x07, ID, 0x02, 0x50, 0x4F, 0x57, 0x00, 0x08, 0x0d });
|
||||
_IsCoolingDown = true;
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
// Fake cool-down cycle
|
||||
CooldownTimer = new CTimer(o =>
|
||||
{
|
||||
_IsCoolingDown = false;
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
}, CooldownTime);
|
||||
}
|
||||
}
|
||||
|
||||
public override void PowerToggle()
|
||||
{
|
||||
if (PowerIsOnFeedback.BoolValue && !IsWarmingUpFeedback.BoolValue)
|
||||
PowerOff();
|
||||
else if (!PowerIsOnFeedback.BoolValue && !IsCoolingDownFeedback.BoolValue)
|
||||
PowerOn();
|
||||
}
|
||||
|
||||
public void PowerGet()
|
||||
{
|
||||
SendBytes(new byte[] { 0x07, ID, 0x01, 0x50, 0x4F, 0x57, 0x08, 0x0d });
|
||||
}
|
||||
|
||||
public void InputHdmi1()
|
||||
{
|
||||
SendBytes(new byte[] { 0x07, ID, 0x02, 0x4D, 0x49, 0x4E, InputHdmi1Value, 0x08, 0x0d });
|
||||
}
|
||||
|
||||
public void InputHdmi2()
|
||||
{
|
||||
SendBytes(new byte[] { 0x07, ID, 0x02, 0x4D, 0x49, 0x4E, InputHdmi2Value, 0x08, 0x0d });
|
||||
}
|
||||
|
||||
public void InputHdmi3()
|
||||
{
|
||||
SendBytes(new byte[] { 0x07, ID, 0x02, 0x4D, 0x49, 0x4E, InputHdmi3Value, 0x08, 0x0d });
|
||||
}
|
||||
|
||||
public void InputHdmi4()
|
||||
{
|
||||
SendBytes(new byte[] { 0x07, ID, 0x02, 0x4D, 0x49, 0x4E, InputHdmi4Value, 0x08, 0x0d });
|
||||
}
|
||||
|
||||
public void InputHdmi5()
|
||||
{
|
||||
SendBytes(new byte[] { 0x07, ID, 0x02, 0x4D, 0x49, 0x4E, InputHdmi5Value, 0x08, 0x0d });
|
||||
}
|
||||
|
||||
public void InputDisplayPort1()
|
||||
{
|
||||
SendBytes(new byte[] { 0x07, ID, 0x02, 0x4D, 0x49, 0x4E, InputDisplayPort1Value, 0x08, 0x0d });
|
||||
}
|
||||
|
||||
public void InputVga1()
|
||||
{
|
||||
SendBytes(new byte[] { 0x07, ID, 0x02, 0x4D, 0x49, 0x4E, InputVga1Value, 0x08, 0x0d });
|
||||
}
|
||||
|
||||
public void InputIpcOps()
|
||||
{
|
||||
SendBytes(new byte[] { 0x07, ID, 0x02, 0x4D, 0x49, 0x4E, InputIpcOpsValue, 0x08, 0x0d });
|
||||
}
|
||||
|
||||
public void InputMediaPlayer()
|
||||
{
|
||||
SendBytes(new byte[] { 0x07, ID, 0x02, 0x4D, 0x49, 0x4E, InputMediaPlayerValue, 0x08, 0x0d });
|
||||
}
|
||||
|
||||
public void InputGet()
|
||||
{
|
||||
SendBytes(new byte[] { 0x07, ID, 0x01, 0x4D, 0x49, 0x4E, 0x08, 0x0d });
|
||||
}
|
||||
|
||||
public void VolumeGet()
|
||||
{
|
||||
SendBytes(new byte[] { 0x07, ID, 0x01, 0x56, 0x4F, 0x4C, 0x08, 0x0d });
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Executes a switch, turning on display if necessary.
|
||||
/// </summary>
|
||||
/// <param name="selector"></param>
|
||||
public override void ExecuteSwitch(object selector)
|
||||
{
|
||||
//if (!(selector is Action))
|
||||
// Debug.Console(1, this, "WARNING: ExecuteSwitch cannot handle type {0}", selector.GetType());
|
||||
|
||||
if (_PowerIsOn)
|
||||
(selector as Action)();
|
||||
else // if power is off, wait until we get on FB to send it.
|
||||
{
|
||||
// One-time event handler to wait for power on before executing switch
|
||||
EventHandler<FeedbackEventArgs> handler = null; // necessary to allow reference inside lambda to handler
|
||||
handler = (o, a) =>
|
||||
{
|
||||
if (!_IsWarmingUp) // Done warming
|
||||
{
|
||||
IsWarmingUpFeedback.OutputChange -= handler;
|
||||
(selector as Action)();
|
||||
}
|
||||
};
|
||||
IsWarmingUpFeedback.OutputChange += handler; // attach and wait for on FB
|
||||
PowerOn();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales the level to the range of the display and sends the command
|
||||
/// </summary>
|
||||
/// <param name="level"></param>
|
||||
public void SetVolume(ushort level)
|
||||
{
|
||||
_LastVolumeSent = level;
|
||||
var scaled = (int)NumericalHelpers.Scale(level, 0, 65535, 0, 100);
|
||||
// The inputs to Scale ensure that byte won't overflow
|
||||
SendBytes(new byte[] { 0x07, ID, 0x02, 0x56, 0x4F, 0x4C, Convert.ToByte(scaled), 0x08, 0x0d });
|
||||
}
|
||||
|
||||
#region IBasicVolumeWithFeedback Members
|
||||
|
||||
public IntFeedback VolumeLevelFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback MuteFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void MuteOff()
|
||||
{
|
||||
SetVolume(_PreMuteVolumeLevel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void MuteOn()
|
||||
{
|
||||
_PreMuteVolumeLevel = _VolumeLevelForSig;
|
||||
|
||||
SetVolume(0);
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
/////
|
||||
///// </summary>
|
||||
//public void MuteGet()
|
||||
//{
|
||||
// SendBytes(new byte[] { 0x07, ID, 0x01, });
|
||||
//}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IBasicVolumeControls Members
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void MuteToggle()
|
||||
{
|
||||
if (_IsMuted)
|
||||
MuteOff();
|
||||
else
|
||||
MuteOn();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void VolumeDown(bool pressRelease)
|
||||
{
|
||||
if (pressRelease)
|
||||
{
|
||||
VolumeIncrementer.StartDown();
|
||||
VolumeIsRamping = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
VolumeIsRamping = false;
|
||||
VolumeIncrementer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void VolumeUp(bool pressRelease)
|
||||
{
|
||||
if (pressRelease)
|
||||
{
|
||||
VolumeIncrementer.StartUp();
|
||||
VolumeIsRamping = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
VolumeIsRamping = false;
|
||||
VolumeIncrementer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class AvocorDisplayFactory : EssentialsDeviceFactory<AvocorDisplay>
|
||||
{
|
||||
public AvocorDisplayFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "avocorvtf" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new Generic Comm Device");
|
||||
var comm = CommFactory.CreateCommForDevice(dc);
|
||||
if (comm != null)
|
||||
return new AvocorDisplay(dc.Key, dc.Name, comm, null);
|
||||
else
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Displays
|
||||
{
|
||||
public interface IInputHdmi1 { void InputHdmi1(); }
|
||||
public interface IInputHdmi2 { void InputHdmi2(); }
|
||||
public interface IInputHdmi3 { void InputHdmi3(); }
|
||||
public interface IInputHdmi4 { void InputHdmi4(); }
|
||||
public interface IInputDisplayPort1 { void InputDisplayPort1(); }
|
||||
public interface IInputDisplayPort2 { void InputDisplayPort2(); }
|
||||
public interface IInputVga1 { void InputVga1(); }
|
||||
|
||||
}
|
||||
@@ -1,387 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Displays
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NecPSXMDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, ICommunicationMonitor, IBridgeAdvanced
|
||||
{
|
||||
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; } }
|
||||
protected override Func<string> CurrentInputFeedbackFunc { get { return () => "Not Implemented"; } }
|
||||
|
||||
|
||||
/// <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.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi1), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi2), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi3), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi4), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.DisplayPortIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.DisplayPort, new Action(InputDisplayPort1), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.DisplayPortIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.DisplayPort, new Action(InputDisplayPort2), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.DviIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Dvi, new Action(InputDvi1), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
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 void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
|
||||
public override FeedbackCollection<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);
|
||||
}
|
||||
|
||||
public 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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public 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)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
SetVolume(_VolumeLevel--);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class NecPSXMDisplayFactory : EssentialsDeviceFactory<NecPSXMDisplay>
|
||||
{
|
||||
public NecPSXMDisplayFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "necmpsx" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new Generic Comm Device");
|
||||
var comm = CommFactory.CreateCommForDevice(dc);
|
||||
if (comm != null)
|
||||
return new NecPSXMDisplay(dc.Key, dc.Name, comm);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,232 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Displays
|
||||
{
|
||||
//public class NecPaSeriesProjector : TwoWayDisplayBase, IBridgeAdvanced
|
||||
//{
|
||||
// public readonly IntFeedback Lamp1RemainingPercent;
|
||||
// int _Lamp1RemainingPercent;
|
||||
// public readonly IntFeedback Lamp2RemainingPercent;
|
||||
// int _Lamp2RemainingPercent;
|
||||
|
||||
// RoutingInputPort _CurrentInputPort;
|
||||
|
||||
// protected override Func<string> CurrentInputFeedbackFunc { get { return () => _CurrentInputPort.Key; } }
|
||||
|
||||
// protected override Func<bool> PowerIsOnFeedbackFunc
|
||||
// {
|
||||
// get { return () => _PowerIsOn; }
|
||||
// }
|
||||
// bool _PowerIsOn;
|
||||
|
||||
// protected override Func<bool> IsCoolingDownFeedbackFunc
|
||||
// {
|
||||
// get { return () => false; }
|
||||
// }
|
||||
|
||||
// protected override Func<bool> IsWarmingUpFeedbackFunc
|
||||
// {
|
||||
// get { return () => false; }
|
||||
// }
|
||||
|
||||
// public override void PowerToggle()
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
// public override void ExecuteSwitch(object selector)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
// Dictionary<string, string> InputMap;
|
||||
|
||||
// /// <summary>
|
||||
// /// Constructor
|
||||
// /// </summary>
|
||||
// public NecPaSeriesProjector(string key, string name)
|
||||
// : base(key, name)
|
||||
// {
|
||||
// Lamp1RemainingPercent = new IntFeedback("Lamp1RemainingPercent", () => _Lamp1RemainingPercent);
|
||||
// Lamp2RemainingPercent = new IntFeedback("Lamp2RemainingPercent", () => _Lamp2RemainingPercent);
|
||||
|
||||
// InputMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
// {
|
||||
// { "computer1", "\x02\x03\x00\x00\x02\x01\x01\x09" },
|
||||
// { "computer2", "\x02\x03\x00\x00\x02\x01\x02\x0a" },
|
||||
// { "computer3", "\x02\x03\x00\x00\x02\x01\x03\x0b" },
|
||||
// { "hdmi", "\x02\x03\x00\x00\x02\x01\x1a\x22" },
|
||||
// { "dp", "\x02\x03\x00\x00\x02\x01\x1b\x23" },
|
||||
// { "video", "\x02\x03\x00\x00\x02\x01\x06\x0e" },
|
||||
// { "viewer", "\x02\x03\x00\x00\x02\x01\x1f\x27" },
|
||||
// { "network", "\x02\x03\x00\x00\x02\x01\x20\x28" },
|
||||
// };
|
||||
// }
|
||||
|
||||
// void IsConnected_OutputChange(object sender, EventArgs e)
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
// public void SetEnable(bool state)
|
||||
// {
|
||||
// var tcp = CommunicationMethod as GenericTcpIpClient;
|
||||
// if (tcp != null)
|
||||
// {
|
||||
// tcp.Connect();
|
||||
// }
|
||||
// }
|
||||
|
||||
// public override void PowerOn()
|
||||
// {
|
||||
// SendText("\x02\x00\x00\x00\x00\x02");
|
||||
// }
|
||||
|
||||
// public override void PowerOff()
|
||||
// {
|
||||
// SendText("\x02\x01\x00\x00\x00\x03");
|
||||
// }
|
||||
|
||||
// public void PictureMuteOn()
|
||||
// {
|
||||
// SendText("\x02\x10\x00\x00\x00\x12");
|
||||
// }
|
||||
|
||||
// public void PictureMuteOff()
|
||||
// {
|
||||
// SendText("\x02\x11\x00\x00\x00\x13");
|
||||
// }
|
||||
|
||||
// public void GetRunningStatus()
|
||||
// {
|
||||
// SendText("\x00\x85\x00\x00\x01\x01\x87");
|
||||
// }
|
||||
|
||||
// public void GetLampRemaining(int lampNum)
|
||||
// {
|
||||
// if (!_PowerIsOn) return;
|
||||
|
||||
// var bytes = new byte[]{0x03,0x96,0x00,0x00,0x02,0x00,0x04};
|
||||
// if (lampNum == 2)
|
||||
// bytes[5] = 0x01;
|
||||
// SendBytes(AppendChecksum(bytes));
|
||||
// }
|
||||
|
||||
// public void SelectInput(string inputKey)
|
||||
// {
|
||||
// if (InputMap.ContainsKey(inputKey))
|
||||
// SendText(InputMap[inputKey]);
|
||||
// }
|
||||
|
||||
// void SendText(string text)
|
||||
// {
|
||||
// if (CommunicationMethod != null)
|
||||
// CommunicationMethod.SendText(text);
|
||||
// }
|
||||
|
||||
// void SendBytes(byte[] bytes)
|
||||
// {
|
||||
// if (CommunicationMethod != null)
|
||||
// CommunicationMethod.SendBytes(bytes);
|
||||
// }
|
||||
|
||||
// byte[] AppendChecksum(byte[] bytes)
|
||||
// {
|
||||
// byte sum = unchecked((byte)bytes.Sum(x => (int)x));
|
||||
// var retVal = new byte[bytes.Length + 1];
|
||||
// bytes.CopyTo(retVal, 0);
|
||||
// retVal[retVal.Length - 1] = sum;
|
||||
// return retVal;
|
||||
// }
|
||||
|
||||
// protected override void CommunicationMethod_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs args)
|
||||
// {
|
||||
// var bytes = args.Bytes;
|
||||
// ParseBytes(args.Bytes);
|
||||
// }
|
||||
|
||||
// void ParseBytes(byte[] bytes)
|
||||
// {
|
||||
// if (bytes[0] == 0x22)
|
||||
// {
|
||||
// // Power on
|
||||
// if (bytes[1] == 0x00)
|
||||
// {
|
||||
// _PowerIsOn = true;
|
||||
// PowerIsOnFeedback.FireUpdate();
|
||||
// }
|
||||
// // Power off
|
||||
// else if (bytes[1] == 0x01)
|
||||
// {
|
||||
// _PowerIsOn = false;
|
||||
// PowerIsOnFeedback.FireUpdate();
|
||||
// }
|
||||
// }
|
||||
// // Running Status
|
||||
// else if (bytes[0] == 0x20 && bytes[1] == 0x85 && bytes[4] == 0x10)
|
||||
// {
|
||||
// var operationStates = new Dictionary<int, string>
|
||||
// {
|
||||
// { 0x00, "Standby" },
|
||||
// { 0x04, "Power On" },
|
||||
// { 0x05, "Cooling" },
|
||||
// { 0x06, "Standby (error)" },
|
||||
// { 0x0f, "Standby (power saving" },
|
||||
// { 0x10, "Network Standby" },
|
||||
// { 0xff, "Not supported" }
|
||||
// };
|
||||
|
||||
// var newPowerIsOn = bytes[7] == 0x01;
|
||||
// if (newPowerIsOn != _PowerIsOn)
|
||||
// {
|
||||
// _PowerIsOn = newPowerIsOn;
|
||||
// PowerIsOnFeedback.FireUpdate();
|
||||
// }
|
||||
|
||||
// Debug.Console(2, this, "PowerIsOn={0}\rCooling={1}\rPowering on/off={2}\rStatus={3}",
|
||||
// _PowerIsOn,
|
||||
// bytes[8] == 0x01,
|
||||
// bytes[9] == 0x01,
|
||||
// operationStates[bytes[10]]);
|
||||
|
||||
// }
|
||||
// // Lamp remaining
|
||||
// else if (bytes[0] == 0x23 && bytes[1] == 0x96 && bytes[4] == 0x06 && bytes[6] == 0x04)
|
||||
// {
|
||||
// var newValue = bytes[7];
|
||||
// if (bytes[5] == 0x00)
|
||||
// {
|
||||
// if (newValue != _Lamp1RemainingPercent)
|
||||
// {
|
||||
// _Lamp1RemainingPercent = newValue;
|
||||
// Lamp1RemainingPercent.FireUpdate();
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (newValue != _Lamp2RemainingPercent)
|
||||
// {
|
||||
// _Lamp2RemainingPercent = newValue;
|
||||
// Lamp2RemainingPercent.FireUpdate();
|
||||
// }
|
||||
// }
|
||||
// Debug.Console(0, this, "Lamp {0}, {1}% remaining", (bytes[5] + 1), bytes[7]);
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
// {
|
||||
// LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
@@ -1,367 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Displays
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class PanasonicThDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, ICommunicationMonitor, IBridgeAdvanced
|
||||
{
|
||||
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 = "\x02QMI\x03";
|
||||
public const string Hdmi1Cmd = "\x02IMS:HM1\x03";
|
||||
public const string Hdmi2Cmd = "\x02IMS:HM2\x03";
|
||||
public const string Hdmi3Cmd = "";
|
||||
public const string Hdmi4Cmd = "";
|
||||
public const string Dp1Cmd = "";
|
||||
public const string Dp2Cmd = "";
|
||||
public const string Dvi1Cmd = "\x02IMS:DV1";
|
||||
public const string Video1Cmd = "";
|
||||
public const string VgaCmd = "";
|
||||
public const string RgbCmd = "";
|
||||
|
||||
public const string PowerOnCmd = "\x02PON\x03";
|
||||
public const string PowerOffCmd = "\x02POF\x03";
|
||||
public const string PowerToggleIrCmd = "";
|
||||
|
||||
public const string MuteOffCmd = "\x02AMT:0\x03";
|
||||
public const string MuteOnCmd = "\x02AMT:1\x03";
|
||||
public const string MuteToggleIrCmd = "\x02AMT\x03";
|
||||
public const string MuteGetCmd = "\x02QAM\x03";
|
||||
|
||||
public const string VolumeGetCmd = "\x02QAV\x03";
|
||||
public const string VolumeLevelPartialCmd = "\x02AVL:"; //
|
||||
public const string VolumeUpCmd = "\x02AUU\x03";
|
||||
public const string VolumeDownCmd = "\x02AUD\x03";
|
||||
|
||||
public const string MenuIrCmd = "";
|
||||
public const string UpIrCmd = "";
|
||||
public const string DownIrCmd = "";
|
||||
public const string LeftIrCmd = "";
|
||||
public const string RightIrCmd = "";
|
||||
public const string SelectIrCmd = "";
|
||||
public const string ExitIrCmd = "";
|
||||
#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; } }
|
||||
protected override Func<string> CurrentInputFeedbackFunc { get { return () => "Not Implemented"; } }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for IBasicCommunication
|
||||
/// </summary>
|
||||
public PanasonicThDisplay(string key, string name, IBasicCommunication comm)
|
||||
: base(key, name)
|
||||
{
|
||||
Communication = comm;
|
||||
Init();
|
||||
}
|
||||
/// <summary>
|
||||
/// Constructor for TCP
|
||||
/// </summary>
|
||||
public PanasonicThDisplay(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 PanasonicThDisplay(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, "\x02QPW\x03"); // Query Power
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi1), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi2), this));
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.DviIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Dvi, new Action(InputDvi1), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Composite, new Action(InputVideo1), this));
|
||||
InputPorts.Add(new RoutingInputPort(RoutingPortNames.VgaIn, eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Vga, new Action(InputVga), 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); }),
|
||||
//};
|
||||
}
|
||||
|
||||
~PanasonicThDisplay()
|
||||
{
|
||||
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 void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
|
||||
public override FeedbackCollection<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 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);
|
||||
}
|
||||
|
||||
public void SetVolume(ushort level)
|
||||
{
|
||||
var levelString = string.Format("{0}{1:X3}\x03", VolumeLevelPartialCmd, level);
|
||||
|
||||
//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)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
SetVolume(_VolumeLevel--);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class PanasonicThDisplayFactory : EssentialsDeviceFactory<PanasonicThDisplay>
|
||||
{
|
||||
public PanasonicThDisplayFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "panasonicthef" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new Generic Comm Device");
|
||||
var comm = CommFactory.CreateCommForDevice(dc);
|
||||
if (comm != null)
|
||||
return new PanasonicThDisplay(dc.Key, dc.Name, comm);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,665 +0,0 @@
|
||||
extern alias Full;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.CrestronThread;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||
|
||||
using Full.Newtonsoft.Json.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Displays
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class SamsungMDC : TwoWayDisplayBase, IBasicVolumeWithFeedback, ICommunicationMonitor, IInputDisplayPort1, IInputDisplayPort2,
|
||||
IInputHdmi1, IInputHdmi2, IInputHdmi3, IInputHdmi4, IBridgeAdvanced
|
||||
{
|
||||
public IBasicCommunication Communication { get; private set; }
|
||||
|
||||
|
||||
|
||||
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
||||
|
||||
public byte ID { get; private set; }
|
||||
|
||||
bool LastCommandSentWasVolume;
|
||||
|
||||
bool _PowerIsOn;
|
||||
bool _IsWarmingUp;
|
||||
bool _IsCoolingDown;
|
||||
ushort _VolumeLevelForSig;
|
||||
int _LastVolumeSent;
|
||||
bool _IsMuted;
|
||||
RoutingInputPort _CurrentInputPort;
|
||||
byte[] IncomingBuffer = new byte[]{};
|
||||
ActionIncrementer VolumeIncrementer;
|
||||
bool VolumeIsRamping;
|
||||
public bool IsInStandby { get; private set; }
|
||||
bool IsPoweringOnIgnorePowerFb;
|
||||
|
||||
protected override Func<bool> PowerIsOnFeedbackFunc { get { return () => _PowerIsOn; } }
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
|
||||
protected override Func<bool> IsWarmingUpFeedbackFunc { get { return () => _IsWarmingUp; } }
|
||||
protected override Func<string> CurrentInputFeedbackFunc { get { return () => _CurrentInputPort.Key; } }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for IBasicCommunication
|
||||
/// </summary>
|
||||
public SamsungMDC(string key, string name, IBasicCommunication comm, string id)
|
||||
: base(key, name)
|
||||
{
|
||||
Communication = comm;
|
||||
Communication.BytesReceived += new EventHandler<GenericCommMethodReceiveBytesArgs>(Communication_BytesReceived);
|
||||
|
||||
ID = id == null ? (byte)0x01 : Convert.ToByte(id, 16); // If id is null, set default value of 0x01, otherwise assign value passed in constructor
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for TCP
|
||||
/// </summary>
|
||||
public SamsungMDC(string key, string name, string hostname, int port, string id)
|
||||
: base(key, name)
|
||||
{
|
||||
Communication = new GenericTcpIpClient(key + "-tcp", hostname, port, 5000);
|
||||
ID = id == null ? (byte)0x01 : Convert.ToByte(id, 16); // If id is null, set default value of 0x01, otherwise assign value passed in constructor
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for COM
|
||||
/// </summary>
|
||||
public SamsungMDC(string key, string name, ComPort port, ComPort.ComPortSpec spec, string id)
|
||||
: base(key, name)
|
||||
{
|
||||
Communication = new ComPortController(key + "-com", port, spec);
|
||||
//Communication.TextReceived += new EventHandler<GenericCommMethodReceiveTextArgs>(Communication_TextReceived);
|
||||
|
||||
ID = id == null ? (byte)0x01 : Convert.ToByte(id, 16); // If id is null, set default value of 0x01, otherwise assign value passed in constructor
|
||||
Init();
|
||||
}
|
||||
|
||||
void AddRoutingInputPort(RoutingInputPort port, byte fbMatch)
|
||||
{
|
||||
port.FeedbackMatchObject = fbMatch;
|
||||
InputPorts.Add(port);
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
WarmupTime = 10000;
|
||||
CooldownTime = 8000;
|
||||
|
||||
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 2000, 120000, 300000, StatusGet, true);
|
||||
DeviceManager.AddDevice(CommunicationMonitor);
|
||||
|
||||
VolumeIncrementer = new ActionIncrementer(655, 0, 65535, 800, 80,
|
||||
v => SetVolume((ushort)v),
|
||||
() => _LastVolumeSent);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi1), this), 0x21);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.HdmiIn1PC, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi1PC), this), 0x22);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi2), this), 0x23);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.HdmiIn2PC, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi2PC), this), 0x24);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(InputHdmi3), this), 0x32);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.DisplayPortIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.DisplayPort, new Action(InputDisplayPort1), this), 0x25);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.DviIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Dvi, new Action(InputDvi1), this), 0x18);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Composite, new Action(InputVideo1), this), 0x08);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.RgbIn1, eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Vga, new Action(InputRgb1), this), 0x14);
|
||||
|
||||
AddRoutingInputPort(new RoutingInputPort(RoutingPortNames.RgbIn2, eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Rgb, new Action(new Action(InputRgb2)), this), 0x1E);
|
||||
|
||||
VolumeLevelFeedback = new IntFeedback(() => { return _VolumeLevelForSig; });
|
||||
MuteFeedback = new BoolFeedback(() => _IsMuted);
|
||||
|
||||
StatusGet();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
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 void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
|
||||
public override FeedbackCollection<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
var list = base.Feedbacks;
|
||||
list.AddRange(new List<Feedback>
|
||||
{
|
||||
VolumeLevelFeedback,
|
||||
MuteFeedback,
|
||||
CurrentInputFeedback
|
||||
});
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// /
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
void Communication_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// This is probably not thread-safe buffering
|
||||
// Append the incoming bytes with whatever is in the buffer
|
||||
var newBytes = new byte[IncomingBuffer.Length + e.Bytes.Length];
|
||||
IncomingBuffer.CopyTo(newBytes, 0);
|
||||
e.Bytes.CopyTo(newBytes, IncomingBuffer.Length);
|
||||
|
||||
// Need to find AA FF and have
|
||||
for (int i = 0; i < newBytes.Length; i++)
|
||||
{
|
||||
if (newBytes[i] == 0xAA && newBytes[i + 1] == 0xFF)
|
||||
{
|
||||
newBytes = newBytes.Skip(i).ToArray(); // Trim off junk if there's "dirt" in the buffer
|
||||
|
||||
// parse it
|
||||
// If it's at least got the header, then process it,
|
||||
while (newBytes.Length > 4 && newBytes[0] == 0xAA && newBytes[1] == 0xFF)
|
||||
{
|
||||
var msgLen = newBytes[3];
|
||||
// if the buffer is shorter than the header (3) + message (msgLen) + checksum (1),
|
||||
// give and save it for next time
|
||||
if (newBytes.Length < msgLen + 4)
|
||||
break;
|
||||
|
||||
// Good length, grab the message
|
||||
var message = newBytes.Skip(4).Take(msgLen).ToArray();
|
||||
|
||||
// At this point, the ack/nak is the first byte
|
||||
if (message[0] == 0x41)
|
||||
{
|
||||
switch (message[1]) // type byte
|
||||
{
|
||||
case 0x00: // General status
|
||||
//UpdatePowerFB(message[2], message[5]); // "power" can be misrepresented when the display sleeps
|
||||
|
||||
// Handle the first power on fb when waiting for it.
|
||||
if (IsPoweringOnIgnorePowerFb && message[2] == 0x01)
|
||||
IsPoweringOnIgnorePowerFb = false;
|
||||
// Ignore general-status power off messages when powering up
|
||||
if (!(IsPoweringOnIgnorePowerFb && message[2] == 0x00))
|
||||
UpdatePowerFB(message[2]);
|
||||
UpdateVolumeFB(message[3]);
|
||||
UpdateMuteFb(message[4]);
|
||||
UpdateInputFb(message[5]);
|
||||
break;
|
||||
|
||||
case 0x11:
|
||||
UpdatePowerFB(message[2]);
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
UpdateVolumeFB(message[2]);
|
||||
break;
|
||||
|
||||
case 0x13:
|
||||
UpdateMuteFb(message[2]);
|
||||
break;
|
||||
|
||||
case 0x14:
|
||||
UpdateInputFb(message[2]);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Skip over what we've used and save the rest for next time
|
||||
newBytes = newBytes.Skip(5 + msgLen).ToArray();
|
||||
}
|
||||
|
||||
break; // parsing will mean we can stop looking for header in loop
|
||||
}
|
||||
}
|
||||
|
||||
// Save whatever partial message is here
|
||||
IncomingBuffer = newBytes;
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
Debug.Console(2, this, "Error parsing feedback: {0}", err);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void UpdatePowerFB(byte powerByte)
|
||||
{
|
||||
var newVal = powerByte == 1;
|
||||
if (newVal != _PowerIsOn)
|
||||
{
|
||||
_PowerIsOn = newVal;
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Feedback Power State: {0}", _PowerIsOn);
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates power status from general updates where source is included.
|
||||
/// Compensates for errant standby / power off hiccups by ignoring
|
||||
/// power off states with input < 0x10
|
||||
/// </summary>
|
||||
void UpdatePowerFB(byte powerByte, byte inputByte)
|
||||
{
|
||||
// This should reject errant power feedbacks when switching away from input on standby.
|
||||
if (powerByte == 0x01 && inputByte < 0x10)
|
||||
IsInStandby = true;
|
||||
if (powerByte == 0x00 && IsInStandby) // Ignore power off if coming from standby - glitch
|
||||
{
|
||||
IsInStandby = false;
|
||||
return;
|
||||
}
|
||||
|
||||
UpdatePowerFB(powerByte);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void UpdateVolumeFB(byte b)
|
||||
{
|
||||
var newVol = (ushort)NumericalHelpers.Scale((double)b, 0, 100, 0, 65535);
|
||||
if (!VolumeIsRamping)
|
||||
_LastVolumeSent = newVol;
|
||||
if (newVol != _VolumeLevelForSig)
|
||||
{
|
||||
_VolumeLevelForSig = newVol;
|
||||
VolumeLevelFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void UpdateMuteFb(byte b)
|
||||
{
|
||||
var newMute = b == 1;
|
||||
if (newMute != _IsMuted)
|
||||
{
|
||||
_IsMuted = newMute;
|
||||
MuteFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void UpdateInputFb(byte b)
|
||||
{
|
||||
var newInput = InputPorts.FirstOrDefault(i => i.FeedbackMatchObject.Equals(b));
|
||||
if (newInput != null && newInput != _CurrentInputPort)
|
||||
{
|
||||
_CurrentInputPort = newInput;
|
||||
CurrentInputFeedback.FireUpdate();
|
||||
OnSwitchChange(new RoutingNumericEventArgs(null, _CurrentInputPort, eRoutingSignalType.AudioVideo));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats an outgoing message. Replaces third byte with ID and replaces last byte with checksum
|
||||
/// </summary>
|
||||
/// <param name="b"></param>
|
||||
void SendBytes(byte[] b)
|
||||
{
|
||||
if (LastCommandSentWasVolume) // If the last command sent was volume
|
||||
if (b[1] != 0x12) // Check if this command is volume, and if not, delay this command
|
||||
CrestronEnvironment.Sleep(100);
|
||||
|
||||
b[2] = ID;
|
||||
// append checksum by adding all bytes, except last which should be 00
|
||||
int checksum = 0;
|
||||
for (var i = 1; i < b.Length - 1; i++) // add 2nd through 2nd-to-last bytes
|
||||
{
|
||||
checksum += b[i];
|
||||
}
|
||||
checksum = checksum & 0x000000FF; // mask off MSBs
|
||||
b[b.Length - 1] = (byte)checksum;
|
||||
|
||||
if (b[1] == 0x12)
|
||||
LastCommandSentWasVolume = true;
|
||||
else
|
||||
LastCommandSentWasVolume = false;
|
||||
|
||||
Communication.SendBytes(b);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void StatusGet()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x00, 0x00, 0x00, 0x00 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void PowerOn()
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Powering On Display");
|
||||
|
||||
IsPoweringOnIgnorePowerFb = true;
|
||||
//Send(PowerOnCmd);
|
||||
SendBytes(new byte[] { 0xAA, 0x11, 0x00, 0x01, 0x01, 0x00 });
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void PowerOff()
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Powering Off Display");
|
||||
|
||||
IsPoweringOnIgnorePowerFb = false;
|
||||
// If a display has unreliable-power off feedback, just override this and
|
||||
// remove this check.
|
||||
if (!_IsWarmingUp && !_IsCoolingDown) // PowerIsOnFeedback.BoolValue &&
|
||||
{
|
||||
//Send(PowerOffCmd);
|
||||
SendBytes(new byte[] { 0xAA, 0x11, 0x00, 0x01, 0x00, 0x00 });
|
||||
_IsCoolingDown = true;
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
// Fake cool-down cycle
|
||||
CooldownTimer = new CTimer(o =>
|
||||
{
|
||||
_IsCoolingDown = false;
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
}, CooldownTime);
|
||||
}
|
||||
}
|
||||
|
||||
public override void PowerToggle()
|
||||
{
|
||||
if (PowerIsOnFeedback.BoolValue && !IsWarmingUpFeedback.BoolValue)
|
||||
PowerOff();
|
||||
else if (!PowerIsOnFeedback.BoolValue && !IsCoolingDownFeedback.BoolValue)
|
||||
PowerOn();
|
||||
}
|
||||
|
||||
public void PowerGet()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x11, 0x00, 0x00, 0x00 });
|
||||
}
|
||||
|
||||
public void InputHdmi1()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x14, 0x00, 0x01, 0x21, 0x00 });
|
||||
}
|
||||
|
||||
public void InputHdmi1PC()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x14, 0x00, 0x01, 0x22, 0x00 });
|
||||
}
|
||||
|
||||
public void InputHdmi2()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x14, 0x00, 0x01, 0x23, 0x00 });
|
||||
}
|
||||
|
||||
public void InputHdmi2PC()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x14, 0x00, 0x01, 0x24, 0x00 });
|
||||
}
|
||||
|
||||
public void InputHdmi3()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x14, 0x00, 0x01, 0x32, 0x00 });
|
||||
}
|
||||
|
||||
public void InputHdmi4()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x14, 0x00, 0x01, 0x34, 0x00 });
|
||||
}
|
||||
|
||||
public void InputDisplayPort1()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x14, 0x00, 0x01, 0x25, 0x00 });
|
||||
}
|
||||
|
||||
public void InputDisplayPort2()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x14, 0x00, 0x01, 0x26, 0x00 });
|
||||
}
|
||||
|
||||
public void InputDvi1()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x14, 0x00, 0x01, 0x18, 0x00 });
|
||||
}
|
||||
|
||||
public void InputVideo1()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x14, 0x00, 0x01, 0x08, 0x00 });
|
||||
}
|
||||
|
||||
public void InputRgb1()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x14, 0x00, 0x01, 0x14, 0x00 });
|
||||
}
|
||||
|
||||
public void InputRgb2()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x14, 0x00, 0x01, 0x1E, 0x00 });
|
||||
}
|
||||
|
||||
public void InputGet()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x14, 0x00, 0x00, 0x00 });
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Executes a switch, turning on display if necessary.
|
||||
/// </summary>
|
||||
/// <param name="selector"></param>
|
||||
public override void ExecuteSwitch(object selector)
|
||||
{
|
||||
//if (!(selector is Action))
|
||||
// Debug.Console(1, this, "WARNING: ExecuteSwitch cannot handle type {0}", selector.GetType());
|
||||
|
||||
if (_PowerIsOn)
|
||||
(selector as Action)();
|
||||
else // if power is off, wait until we get on FB to send it.
|
||||
{
|
||||
// One-time event handler to wait for power on before executing switch
|
||||
EventHandler<FeedbackEventArgs> handler = null; // necessary to allow reference inside lambda to handler
|
||||
handler = (o, a) =>
|
||||
{
|
||||
if (!_IsWarmingUp) // Done warming
|
||||
{
|
||||
IsWarmingUpFeedback.OutputChange -= handler;
|
||||
(selector as Action)();
|
||||
}
|
||||
};
|
||||
IsWarmingUpFeedback.OutputChange += handler; // attach and wait for on FB
|
||||
PowerOn();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales the level to the range of the display and sends the command
|
||||
/// </summary>
|
||||
/// <param name="level"></param>
|
||||
public void SetVolume(ushort level)
|
||||
{
|
||||
_LastVolumeSent = level;
|
||||
var scaled = (int)NumericalHelpers.Scale(level, 0, 65535, 0, 100);
|
||||
// The inputs to Scale ensure that byte won't overflow
|
||||
SendBytes(new byte[] { 0xAA, 0x12, 0x00, 0x01, Convert.ToByte(scaled), 0x00 });
|
||||
}
|
||||
|
||||
#region IBasicVolumeWithFeedback Members
|
||||
|
||||
public IntFeedback VolumeLevelFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback MuteFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void MuteOff()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x13, 0x00, 0x01, 0x00, 0x00 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void MuteOn()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x13, 0x00, 0x01, 0x01, 0x00 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void MuteGet()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x13, 0x00, 0x00, 0x00 });
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IBasicVolumeControls Members
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void MuteToggle()
|
||||
{
|
||||
if (_IsMuted)
|
||||
MuteOff();
|
||||
else
|
||||
MuteOn();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void VolumeDown(bool pressRelease)
|
||||
{
|
||||
if (pressRelease)
|
||||
{
|
||||
VolumeIncrementer.StartDown();
|
||||
VolumeIsRamping = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
VolumeIsRamping = false;
|
||||
VolumeIncrementer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void VolumeUp(bool pressRelease)
|
||||
{
|
||||
if (pressRelease)
|
||||
{
|
||||
VolumeIncrementer.StartUp();
|
||||
VolumeIsRamping = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
VolumeIsRamping = false;
|
||||
VolumeIncrementer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void VolumeGet()
|
||||
{
|
||||
SendBytes(new byte[] { 0xAA, 0x12, 0x00, 0x00, 0x00 });
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class SamsungMDCFactory : EssentialsDeviceFactory<SamsungMDC>
|
||||
{
|
||||
public SamsungMDCFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "samsungmdc" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new Generic Comm Device");
|
||||
var comm = CommFactory.CreateCommForDevice(dc);
|
||||
if (comm != null)
|
||||
return new SamsungMDC(dc.Key, dc.Name, comm, dc.Properties["id"].Value<string>());
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user