diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs
index 97c1775e..30a398fa 100644
--- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs
+++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs
@@ -190,6 +190,12 @@ namespace PepperDash.Essentials
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.DidChange);
+
+ var vc = VideoCodec as IHasExternalSourceSwitching;
+ if (vc != null)
+ {
+ vc.SetSelectedSource(_CurrentSourceInfo.SourceKey);
+ }
}
}
SourceListItem _CurrentSourceInfo;
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IPower.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IPower.cs
index a392d149..41d54159 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IPower.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IPower.cs
@@ -14,16 +14,23 @@ using PepperDash.Essentials.Core.SmartObjects;
namespace PepperDash.Essentials.Core
{
///
- ///
+ /// Defines the ability to power a device on and off
///
public interface IPower
{
void PowerOn();
void PowerOff();
void PowerToggle();
- BoolFeedback PowerIsOnFeedback { get; }
}
+ ///
+ /// Adds feedback for current power state
+ ///
+ public interface IPowerWithFeedback : IPower
+ {
+ BoolFeedback PowerIsOnFeedback { get; }
+ }
+
///
///
///
@@ -34,7 +41,12 @@ namespace PepperDash.Essentials.Core
triList.SetSigFalseAction(101, dev.PowerOn);
triList.SetSigFalseAction(102, dev.PowerOff);
triList.SetSigFalseAction(103, dev.PowerToggle);
- dev.PowerIsOnFeedback.LinkInputSig(triList.BooleanInput[101]);
+
+ var fbdev = dev as IPowerWithFeedback;
+ if (fbdev != null)
+ {
+ fbdev.PowerIsOnFeedback.LinkInputSig(triList.BooleanInput[101]);
+ }
}
public static void UnlinkButtons(this IPower dev, BasicTriList triList)
@@ -42,7 +54,12 @@ namespace PepperDash.Essentials.Core
triList.ClearBoolSigAction(101);
triList.ClearBoolSigAction(102);
triList.ClearBoolSigAction(103);
- dev.PowerIsOnFeedback.UnlinkInputSig(triList.BooleanInput[101]);
+
+ var fbdev = dev as IPowerWithFeedback;
+ if (fbdev != null)
+ {
+ fbdev.PowerIsOnFeedback.UnlinkInputSig(triList.BooleanInput[101]);
+ }
}
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs
index 35d696c7..61f23267 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs
@@ -181,14 +181,18 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
});
}
- if (cameraDevice is IPower)
+ var powerCamera = cameraDevice as IPower;
+ if (powerCamera != null)
{
- var powerCamera = cameraDevice as IPower;
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () => powerCamera.PowerOn());
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () => powerCamera.PowerOff());
- powerCamera.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
- powerCamera.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
+ var powerFbCamera = powerCamera as IPowerWithFeedback;
+ if (powerFbCamera != null)
+ {
+ powerFbCamera.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
+ powerFbCamera.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
+ }
}
if (cameraDevice is ICommunicationMonitor)
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs
index d86f628e..b4449d86 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs
@@ -14,6 +14,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
void AddExternalSource(string connectorId, string key, string name, eExternalSourceType type);
void SetExternalSourceState(string key, eExternalSourceMode mode);
void ClearExternalSources();
+ void SetSelectedSource(string key);
Action RunRouteAction { set;}
}
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/SamsungMDCDisplay.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/SamsungMDCDisplay.cs
index b8525e1e..47c08cea 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/SamsungMDCDisplay.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/SamsungMDCDisplay.cs
@@ -1,668 +1,668 @@
-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 Newtonsoft.Json.Linq;
-
-namespace PepperDash.Essentials.Devices.Displays
-{
- ///
- ///
- ///
+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 Newtonsoft.Json.Linq;
+
+namespace PepperDash.Essentials.Devices.Displays
+{
+ ///
+ ///
+ ///
public class SamsungMDC : TwoWayDisplayBase, IBasicVolumeWithFeedback, ICommunicationMonitor, IInputDisplayPort1, IInputDisplayPort2,
- IInputHdmi1, IInputHdmi2, IInputHdmi3, IInputHdmi4, IBridgeAdvanced
- {
+ 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 PowerIsOnFeedbackFunc { get { return () => _PowerIsOn; } }
- protected override Func IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
- protected override Func IsWarmingUpFeedbackFunc { get { return () => _IsWarmingUp; } }
- protected override Func CurrentInputFeedbackFunc { get { return () => _CurrentInputPort.Key; } }
-
- ///
- /// Constructor for IBasicCommunication
- ///
- public SamsungMDC(string key, string name, IBasicCommunication comm, string id)
- : base(key, name)
- {
- Communication = comm;
- Communication.BytesReceived += new EventHandler(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();
- }
-
- ///
- /// Constructor for TCP
- ///
- 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();
- }
-
- ///
- /// Constructor for COM
- ///
- 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(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);
- 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();
- }
-
- ///
- ///
- ///
- ///
- 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 Feedbacks
- {
- get
- {
- var list = base.Feedbacks;
- list.AddRange(new List
- {
- VolumeLevelFeedback,
- MuteFeedback,
- CurrentInputFeedback
- });
- return list;
- }
- }
-
- ///
- /// /
- ///
- ///
- 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);
-
- 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
-
- // 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);
- }
- }
-
- ///
- ///
- ///
- 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();
- }
- }
-
- ///
- /// 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
- ///
- 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);
- }
-
- ///
- ///
- ///
- 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();
- }
- }
-
- ///
- ///
- ///
- void UpdateMuteFb(byte b)
- {
- var newMute = b == 1;
- if (newMute != _IsMuted)
- {
- _IsMuted = newMute;
- MuteFeedback.FireUpdate();
- }
+
+
+ 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 PowerIsOnFeedbackFunc { get { return () => _PowerIsOn; } }
+ protected override Func IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
+ protected override Func IsWarmingUpFeedbackFunc { get { return () => _IsWarmingUp; } }
+ protected override Func CurrentInputFeedbackFunc { get { return () => _CurrentInputPort.Key; } }
+
+ ///
+ /// Constructor for IBasicCommunication
+ ///
+ public SamsungMDC(string key, string name, IBasicCommunication comm, string id)
+ : base(key, name)
+ {
+ Communication = comm;
+ Communication.BytesReceived += new EventHandler(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();
+ }
+
+ ///
+ /// Constructor for TCP
+ ///
+ 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();
+ }
+
+ ///
+ /// Constructor for COM
+ ///
+ 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(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 UpdateInputFb(byte b)
- {
- var newInput = InputPorts.FirstOrDefault(i => i.FeedbackMatchObject.Equals(b));
- if (newInput != null && newInput != _CurrentInputPort)
- {
- _CurrentInputPort = newInput;
+ void Init()
+ {
+ WarmupTime = 10000;
+ CooldownTime = 8000;
+
+ CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 2000, 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), 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();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ 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 Feedbacks
+ {
+ get
+ {
+ var list = base.Feedbacks;
+ list.AddRange(new List
+ {
+ VolumeLevelFeedback,
+ MuteFeedback,
+ CurrentInputFeedback
+ });
+ return list;
+ }
+ }
+
+ ///
+ /// /
+ ///
+ ///
+ 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);
+
+ 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
+
+ // 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);
+ }
+ }
+
+ ///
+ ///
+ ///
+ 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();
+ }
+ }
+
+ ///
+ /// 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
+ ///
+ 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);
+ }
+
+ ///
+ ///
+ ///
+ 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();
+ }
+ }
+
+ ///
+ ///
+ ///
+ void UpdateMuteFb(byte b)
+ {
+ var newMute = b == 1;
+ if (newMute != _IsMuted)
+ {
+ _IsMuted = newMute;
+ MuteFeedback.FireUpdate();
+ }
+ }
+
+
+
+
+ ///
+ ///
+ ///
+ 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));
- }
- }
-
- ///
- /// Formats an outgoing message. Replaces third byte with ID and replaces last byte with checksum
- ///
- ///
- 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(Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1
- Debug.Console(2, this, "Sending:{0}", ComTextHelper.GetEscapedText(b));
-
- if (b[1] == 0x12)
- LastCommandSentWasVolume = true;
- else
- LastCommandSentWasVolume = false;
-
- Communication.SendBytes(b);
- }
-
-
- ///
- ///
- ///
- public void StatusGet()
- {
- SendBytes(new byte[] { 0xAA, 0x00, 0x00, 0x00, 0x00 });
- }
-
- ///
- ///
- ///
- 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);
- }
- }
-
- ///
- ///
- ///
- 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 });
- }
-
-
- ///
- /// Executes a switch, turning on display if necessary.
- ///
- ///
- 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 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();
- }
- }
-
- ///
- /// Scales the level to the range of the display and sends the command
- ///
- ///
- 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; }
-
- ///
- ///
- ///
- public void MuteOff()
- {
- SendBytes(new byte[] { 0xAA, 0x13, 0x00, 0x01, 0x00, 0x00 });
- }
-
- ///
- ///
- ///
- public void MuteOn()
- {
- SendBytes(new byte[] { 0xAA, 0x13, 0x00, 0x01, 0x01, 0x00 });
- }
-
- ///
- ///
- ///
- public void MuteGet()
- {
- SendBytes(new byte[] { 0xAA, 0x13, 0x00, 0x00, 0x00 });
- }
-
- #endregion
-
- #region IBasicVolumeControls Members
-
- ///
- ///
- ///
- public void MuteToggle()
- {
- if (_IsMuted)
- MuteOff();
- else
- MuteOn();
- }
-
- ///
- ///
- ///
- ///
- public void VolumeDown(bool pressRelease)
- {
- if (pressRelease)
- {
- VolumeIncrementer.StartDown();
- VolumeIsRamping = true;
- }
- else
- {
- VolumeIsRamping = false;
- VolumeIncrementer.Stop();
- }
- }
-
- ///
- ///
- ///
- ///
- public void VolumeUp(bool pressRelease)
- {
- if (pressRelease)
- {
- VolumeIncrementer.StartUp();
- VolumeIsRamping = true;
- }
- else
- {
- VolumeIsRamping = false;
- VolumeIncrementer.Stop();
- }
- }
-
- ///
- ///
- ///
- public void VolumeGet()
- {
- SendBytes(new byte[] { 0xAA, 0x12, 0x00, 0x00, 0x00 });
- }
-
- #endregion
- }
-
- public class SamsungMDCFactory : EssentialsDeviceFactory
- {
- public SamsungMDCFactory()
- {
- TypeNames = new List() { "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());
- else
- return null;
- }
- }
-
+ OnSwitchChange(new RoutingNumericEventArgs(null, _CurrentInputPort, eRoutingSignalType.AudioVideo));
+ }
+ }
+
+ ///
+ /// Formats an outgoing message. Replaces third byte with ID and replaces last byte with checksum
+ ///
+ ///
+ 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(Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1
+ Debug.Console(2, this, "Sending:{0}", ComTextHelper.GetEscapedText(b));
+
+ if (b[1] == 0x12)
+ LastCommandSentWasVolume = true;
+ else
+ LastCommandSentWasVolume = false;
+
+ Communication.SendBytes(b);
+ }
+
+
+ ///
+ ///
+ ///
+ public void StatusGet()
+ {
+ SendBytes(new byte[] { 0xAA, 0x00, 0x00, 0x00, 0x00 });
+ }
+
+ ///
+ ///
+ ///
+ 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);
+ }
+ }
+
+ ///
+ ///
+ ///
+ 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 });
+ }
+
+
+ ///
+ /// Executes a switch, turning on display if necessary.
+ ///
+ ///
+ 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 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();
+ }
+ }
+
+ ///
+ /// Scales the level to the range of the display and sends the command
+ ///
+ ///
+ 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; }
+
+ ///
+ ///
+ ///
+ public void MuteOff()
+ {
+ SendBytes(new byte[] { 0xAA, 0x13, 0x00, 0x01, 0x00, 0x00 });
+ }
+
+ ///
+ ///
+ ///
+ public void MuteOn()
+ {
+ SendBytes(new byte[] { 0xAA, 0x13, 0x00, 0x01, 0x01, 0x00 });
+ }
+
+ ///
+ ///
+ ///
+ public void MuteGet()
+ {
+ SendBytes(new byte[] { 0xAA, 0x13, 0x00, 0x00, 0x00 });
+ }
+
+ #endregion
+
+ #region IBasicVolumeControls Members
+
+ ///
+ ///
+ ///
+ public void MuteToggle()
+ {
+ if (_IsMuted)
+ MuteOff();
+ else
+ MuteOn();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void VolumeDown(bool pressRelease)
+ {
+ if (pressRelease)
+ {
+ VolumeIncrementer.StartDown();
+ VolumeIsRamping = true;
+ }
+ else
+ {
+ VolumeIsRamping = false;
+ VolumeIncrementer.Stop();
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void VolumeUp(bool pressRelease)
+ {
+ if (pressRelease)
+ {
+ VolumeIncrementer.StartUp();
+ VolumeIsRamping = true;
+ }
+ else
+ {
+ VolumeIsRamping = false;
+ VolumeIncrementer.Stop();
+ }
+ }
+
+ ///
+ ///
+ ///
+ public void VolumeGet()
+ {
+ SendBytes(new byte[] { 0xAA, 0x12, 0x00, 0x00, 0x00 });
+ }
+
+ #endregion
+ }
+
+ public class SamsungMDCFactory : EssentialsDeviceFactory
+ {
+ public SamsungMDCFactory()
+ {
+ TypeNames = new List() { "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());
+ else
+ return null;
+ }
+ }
+
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs
index 71698529..580d44cc 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs
@@ -56,6 +56,7 @@ namespace PepperDash.Essentials.Devices.Common
eRoutingPortConnectionType.DigitalAudio, null, this);
OutputPorts = new RoutingPortCollection { AnyVideoOut, AnyAudioOut };
+ PowerIsOnFeedback = new BoolFeedback(() => false);
}
public void LoadPresets(string filePath)
@@ -348,27 +349,21 @@ namespace PepperDash.Essentials.Devices.Common
public void PowerOn()
{
- IrPort.PressRelease(IROutputStandardCommands.IROut_POWER_ON, true);
- IrPort.PressRelease(IROutputStandardCommands.IROut_POWER_ON, false);
-
+ IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, 200);
}
public void PowerOff()
{
- IrPort.PressRelease(IROutputStandardCommands.IROut_POWER_OFF, true);
- IrPort.PressRelease(IROutputStandardCommands.IROut_POWER_OFF, false);
-
+ IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, 200);
}
public void PowerToggle()
{
- throw new NotImplementedException();
+ // TODO: Implement power toggle command pulse
+ IrPort.Pulse(IROutputStandardCommands.IROut_POWER, 200);
}
- public BoolFeedback PowerIsOnFeedback
- {
- get { throw new NotImplementedException(); }
- }
+ public BoolFeedback PowerIsOnFeedback { get; private set; }
#endregion
@@ -395,79 +390,98 @@ namespace PepperDash.Essentials.Devices.Common
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = Name;
var stbBase = this as ISetTopBoxControls;
+ if (stbBase != null)
+ {
+ trilist.BooleanInput[joinMap.HasDpad.JoinNumber].BoolValue = stbBase.HasDpad;
+ trilist.BooleanInput[joinMap.HasNumeric.JoinNumber].BoolValue = stbBase.HasNumeric;
+ trilist.BooleanInput[joinMap.HasDvr.JoinNumber].BoolValue = stbBase.HasDvr;
+ trilist.BooleanInput[joinMap.HasPresets.JoinNumber].BoolValue = stbBase.HasPresets;
- trilist.BooleanInput[joinMap.HasDpad.JoinNumber].BoolValue = stbBase.HasDpad;
- trilist.BooleanInput[joinMap.HasNumeric.JoinNumber].BoolValue = stbBase.HasNumeric;
- trilist.BooleanInput[joinMap.HasDvr.JoinNumber].BoolValue = stbBase.HasDvr;
- trilist.BooleanInput[joinMap.HasPresets.JoinNumber].BoolValue = stbBase.HasPresets;
+ trilist.SetBoolSigAction(joinMap.DvrList.JoinNumber, stbBase.DvrList);
+ trilist.SetBoolSigAction(joinMap.Replay.JoinNumber, stbBase.Replay);
- trilist.SetBoolSigAction(joinMap.DvrList.JoinNumber, stbBase.DvrList);
- trilist.SetBoolSigAction(joinMap.Replay.JoinNumber, stbBase.Replay);
-
- trilist.SetStringSigAction(joinMap.LoadPresets.JoinNumber, stbBase.LoadPresets);
+ trilist.SetStringSigAction(joinMap.LoadPresets.JoinNumber, stbBase.LoadPresets);
+ }
var stbPower = this as IPower;
-
- trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, stbPower.PowerOn);
- trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, stbPower.PowerOff);
- trilist.SetSigTrueAction(joinMap.PowerToggle.JoinNumber, stbPower.PowerToggle);
+ if (stbPower != null)
+ {
+ trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, stbPower.PowerOn);
+ trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, stbPower.PowerOff);
+ trilist.SetSigTrueAction(joinMap.PowerToggle.JoinNumber, stbPower.PowerToggle);
+ }
var stbDPad = this as IDPad;
- trilist.SetBoolSigAction(joinMap.Up.JoinNumber, stbDPad.Up);
- trilist.SetBoolSigAction(joinMap.Down.JoinNumber, stbDPad.Down);
- trilist.SetBoolSigAction(joinMap.Left.JoinNumber, stbDPad.Left);
- trilist.SetBoolSigAction(joinMap.Right.JoinNumber, stbDPad.Right);
- trilist.SetBoolSigAction(joinMap.Select.JoinNumber, stbDPad.Select);
- trilist.SetBoolSigAction(joinMap.Menu.JoinNumber, stbDPad.Menu);
- trilist.SetBoolSigAction(joinMap.Exit.JoinNumber, stbDPad.Exit);
+ if (stbDPad != null)
+ {
+ trilist.SetBoolSigAction(joinMap.Up.JoinNumber, stbDPad.Up);
+ trilist.SetBoolSigAction(joinMap.Down.JoinNumber, stbDPad.Down);
+ trilist.SetBoolSigAction(joinMap.Left.JoinNumber, stbDPad.Left);
+ trilist.SetBoolSigAction(joinMap.Right.JoinNumber, stbDPad.Right);
+ trilist.SetBoolSigAction(joinMap.Select.JoinNumber, stbDPad.Select);
+ trilist.SetBoolSigAction(joinMap.Menu.JoinNumber, stbDPad.Menu);
+ trilist.SetBoolSigAction(joinMap.Exit.JoinNumber, stbDPad.Exit);
+ }
var stbChannel = this as IChannel;
- trilist.SetBoolSigAction(joinMap.ChannelUp.JoinNumber, stbChannel.ChannelUp);
- trilist.SetBoolSigAction(joinMap.ChannelDown.JoinNumber, stbChannel.ChannelDown);
- trilist.SetBoolSigAction(joinMap.LastChannel.JoinNumber, stbChannel.LastChannel);
- trilist.SetBoolSigAction(joinMap.Guide.JoinNumber, stbChannel.Guide);
- trilist.SetBoolSigAction(joinMap.Info.JoinNumber, stbChannel.Info);
- trilist.SetBoolSigAction(joinMap.Exit.JoinNumber, stbChannel.Exit);
+ if (stbChannel != null)
+ {
+ trilist.SetBoolSigAction(joinMap.ChannelUp.JoinNumber, stbChannel.ChannelUp);
+ trilist.SetBoolSigAction(joinMap.ChannelDown.JoinNumber, stbChannel.ChannelDown);
+ trilist.SetBoolSigAction(joinMap.LastChannel.JoinNumber, stbChannel.LastChannel);
+ trilist.SetBoolSigAction(joinMap.Guide.JoinNumber, stbChannel.Guide);
+ trilist.SetBoolSigAction(joinMap.Info.JoinNumber, stbChannel.Info);
+ trilist.SetBoolSigAction(joinMap.Exit.JoinNumber, stbChannel.Exit);
+ }
var stbColor = this as IColor;
- trilist.SetBoolSigAction(joinMap.Red.JoinNumber, stbColor.Red);
- trilist.SetBoolSigAction(joinMap.Green.JoinNumber, stbColor.Green);
- trilist.SetBoolSigAction(joinMap.Yellow.JoinNumber, stbColor.Yellow);
- trilist.SetBoolSigAction(joinMap.Blue.JoinNumber, stbColor.Blue);
+ if (stbColor != null)
+ {
+ trilist.SetBoolSigAction(joinMap.Red.JoinNumber, stbColor.Red);
+ trilist.SetBoolSigAction(joinMap.Green.JoinNumber, stbColor.Green);
+ trilist.SetBoolSigAction(joinMap.Yellow.JoinNumber, stbColor.Yellow);
+ trilist.SetBoolSigAction(joinMap.Blue.JoinNumber, stbColor.Blue);
+ }
var stbKeypad = this as ISetTopBoxNumericKeypad;
- trilist.StringInput[joinMap.KeypadAccessoryButton1Label.JoinNumber].StringValue = stbKeypad.KeypadAccessoryButton1Label;
- trilist.StringInput[joinMap.KeypadAccessoryButton2Label.JoinNumber].StringValue = stbKeypad.KeypadAccessoryButton2Label;
+ if (stbKeypad != null)
+ {
+ trilist.StringInput[joinMap.KeypadAccessoryButton1Label.JoinNumber].StringValue = stbKeypad.KeypadAccessoryButton1Label;
+ trilist.StringInput[joinMap.KeypadAccessoryButton2Label.JoinNumber].StringValue = stbKeypad.KeypadAccessoryButton2Label;
- trilist.BooleanInput[joinMap.HasKeypadAccessoryButton1.JoinNumber].BoolValue = stbKeypad.HasKeypadAccessoryButton1;
- trilist.BooleanInput[joinMap.HasKeypadAccessoryButton2.JoinNumber].BoolValue = stbKeypad.HasKeypadAccessoryButton2;
+ trilist.BooleanInput[joinMap.HasKeypadAccessoryButton1.JoinNumber].BoolValue = stbKeypad.HasKeypadAccessoryButton1;
+ trilist.BooleanInput[joinMap.HasKeypadAccessoryButton2.JoinNumber].BoolValue = stbKeypad.HasKeypadAccessoryButton2;
- trilist.SetBoolSigAction(joinMap.Digit0.JoinNumber, stbKeypad.Digit0);
- trilist.SetBoolSigAction(joinMap.Digit1.JoinNumber, stbKeypad.Digit1);
- trilist.SetBoolSigAction(joinMap.Digit2.JoinNumber, stbKeypad.Digit2);
- trilist.SetBoolSigAction(joinMap.Digit3.JoinNumber, stbKeypad.Digit3);
- trilist.SetBoolSigAction(joinMap.Digit4.JoinNumber, stbKeypad.Digit4);
- trilist.SetBoolSigAction(joinMap.Digit5.JoinNumber, stbKeypad.Digit5);
- trilist.SetBoolSigAction(joinMap.Digit6.JoinNumber, stbKeypad.Digit6);
- trilist.SetBoolSigAction(joinMap.Digit7.JoinNumber, stbKeypad.Digit7);
- trilist.SetBoolSigAction(joinMap.Digit8.JoinNumber, stbKeypad.Digit8);
- trilist.SetBoolSigAction(joinMap.Digit9.JoinNumber, stbKeypad.Digit9);
- trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton1Press.JoinNumber, stbKeypad.KeypadAccessoryButton1);
- trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton2Press.JoinNumber, stbKeypad.KeypadAccessoryButton1);
- trilist.SetBoolSigAction(joinMap.Dash.JoinNumber, stbKeypad.Dash);
- trilist.SetBoolSigAction(joinMap.KeypadEnter.JoinNumber, stbKeypad.KeypadEnter);
+ trilist.SetBoolSigAction(joinMap.Digit0.JoinNumber, stbKeypad.Digit0);
+ trilist.SetBoolSigAction(joinMap.Digit1.JoinNumber, stbKeypad.Digit1);
+ trilist.SetBoolSigAction(joinMap.Digit2.JoinNumber, stbKeypad.Digit2);
+ trilist.SetBoolSigAction(joinMap.Digit3.JoinNumber, stbKeypad.Digit3);
+ trilist.SetBoolSigAction(joinMap.Digit4.JoinNumber, stbKeypad.Digit4);
+ trilist.SetBoolSigAction(joinMap.Digit5.JoinNumber, stbKeypad.Digit5);
+ trilist.SetBoolSigAction(joinMap.Digit6.JoinNumber, stbKeypad.Digit6);
+ trilist.SetBoolSigAction(joinMap.Digit7.JoinNumber, stbKeypad.Digit7);
+ trilist.SetBoolSigAction(joinMap.Digit8.JoinNumber, stbKeypad.Digit8);
+ trilist.SetBoolSigAction(joinMap.Digit9.JoinNumber, stbKeypad.Digit9);
+ trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton1Press.JoinNumber, stbKeypad.KeypadAccessoryButton1);
+ trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton2Press.JoinNumber, stbKeypad.KeypadAccessoryButton1);
+ trilist.SetBoolSigAction(joinMap.Dash.JoinNumber, stbKeypad.Dash);
+ trilist.SetBoolSigAction(joinMap.KeypadEnter.JoinNumber, stbKeypad.KeypadEnter);
+ }
var stbTransport = this as ITransport;
- trilist.SetBoolSigAction(joinMap.Play.JoinNumber, stbTransport.Play);
- trilist.SetBoolSigAction(joinMap.Pause.JoinNumber, stbTransport.Pause);
- trilist.SetBoolSigAction(joinMap.Rewind.JoinNumber, stbTransport.Rewind);
- trilist.SetBoolSigAction(joinMap.FFwd.JoinNumber, stbTransport.FFwd);
- trilist.SetBoolSigAction(joinMap.ChapMinus.JoinNumber, stbTransport.ChapMinus);
- trilist.SetBoolSigAction(joinMap.ChapPlus.JoinNumber, stbTransport.ChapPlus);
- trilist.SetBoolSigAction(joinMap.Stop.JoinNumber, stbTransport.Stop);
- trilist.SetBoolSigAction(joinMap.Record.JoinNumber, stbTransport.Record);
+ if (stbTransport != null)
+ {
+ trilist.SetBoolSigAction(joinMap.Play.JoinNumber, stbTransport.Play);
+ trilist.SetBoolSigAction(joinMap.Pause.JoinNumber, stbTransport.Pause);
+ trilist.SetBoolSigAction(joinMap.Rewind.JoinNumber, stbTransport.Rewind);
+ trilist.SetBoolSigAction(joinMap.FFwd.JoinNumber, stbTransport.FFwd);
+ trilist.SetBoolSigAction(joinMap.ChapMinus.JoinNumber, stbTransport.ChapMinus);
+ trilist.SetBoolSigAction(joinMap.ChapPlus.JoinNumber, stbTransport.ChapPlus);
+ trilist.SetBoolSigAction(joinMap.Stop.JoinNumber, stbTransport.Stop);
+ trilist.SetBoolSigAction(joinMap.Record.JoinNumber, stbTransport.Record);
+ }
}
}
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs
index 55e6bf11..ce748699 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs
@@ -1970,6 +1970,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
}
+ ///
+ /// Sets the selected source of the available external sources on teh Touch10 UI
+ ///
+ public void SetSelectedSource(string key)
+ {
+ SendText(string.Format("xCommand UserInterface Presentation ExternalSource Select SourceIdentifier: {0}", key));
+ }
+
///
/// Action that will run when the External Source is selected.
///