diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/DeviceInfo.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/DeviceInfo.cs new file mode 100644 index 00000000..9b03ec11 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/DeviceInfo.cs @@ -0,0 +1,11 @@ +namespace PepperDash.Essentials.Core.DeviceInfo +{ + public class DeviceInfo + { + public string HostName { get; set; } + public string IpAddress { get; set; } + public string MacAddress { get; set; } + public string SerialNumber { get; set; } + public string FirmwareVersion { get; set; } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/DeviceInfoEventArgs.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/DeviceInfoEventArgs.cs new file mode 100644 index 00000000..6727bce6 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/DeviceInfoEventArgs.cs @@ -0,0 +1,19 @@ +using System; + +namespace PepperDash.Essentials.Core.DeviceInfo +{ + public class DeviceInfoEventArgs:EventArgs + { + public DeviceInfo DeviceInfo { get; set; } + + public DeviceInfoEventArgs() + { + + } + + public DeviceInfoEventArgs(DeviceInfo devInfo) + { + DeviceInfo = devInfo; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/IDeviceInfoProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/IDeviceInfoProvider.cs new file mode 100644 index 00000000..ea9c16e6 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/IDeviceInfoProvider.cs @@ -0,0 +1,16 @@ +using System; +using PepperDash.Core; + +namespace PepperDash.Essentials.Core.DeviceInfo +{ + public interface IDeviceInfoProvider:IKeyed + { + DeviceInfo DeviceInfo { get; } + + event DeviceInfoChangeHandler DeviceInfoChanged; + + void UpdateDeviceInfo(); + } + + public delegate void DeviceInfoChangeHandler(IKeyed device, DeviceInfoEventArgs args); +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index e2e6519e..6d4def73 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -183,6 +183,9 @@ + + + diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 428bb8bc..09c7988a 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -774,10 +774,15 @@ namespace PepperDash.Essentials.DM { var portKey = string.Format("{0}--{1}", cardName, portName); Debug.Console(2, this, "Adding output port '{0}'", portKey); - OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this) + + var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this); + + if (portName.IndexOf("Loop", StringComparison.InvariantCultureIgnoreCase) < 0) { - FeedbackMatchObject = Chassis.Outputs[(uint)selector] - }); + outputPort.FeedbackMatchObject = Chassis.Outputs[(uint) selector]; + } + + OutputPorts.Add(outputPort); } /// @@ -786,12 +791,13 @@ namespace PepperDash.Essentials.DM void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector, ICec cecPort) { var portKey = string.Format("{0}--{1}", cardName, portName); - Debug.Console(2, this, "Adding output port '{0}'", portKey); - var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this) + Debug.Console(2, this, "Adding output port '{0}'", portKey); + var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this); + + if (portName.IndexOf("Loop", StringComparison.InvariantCultureIgnoreCase) < 0) { - FeedbackMatchObject = Chassis.Outputs[(uint)selector] - }; ; - + outputPort.FeedbackMatchObject = Chassis.Outputs[(uint)selector]; + } if (cecPort != null) outputPort.Port = cecPort; diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs index dd07f696..d7996554 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; -using System.Linq; +using System.Linq; +using System.Net.Sockets; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; @@ -14,15 +15,19 @@ using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; -using Crestron.SimplSharpPro.DeviceSupport; - +using Crestron.SimplSharpPro.DeviceSupport; +using PepperDash.Essentials.Core.DeviceInfo; + namespace PepperDash.Essentials.DM.Endpoints.DGEs { [Description("Wrapper class for DGE-100")] - public class Dge100Controller : CrestronGenericBaseDevice, IComPorts, IIROutputPorts, IHasBasicTriListWithSmartObject, ICec + public class Dge100Controller : CrestronGenericBaseDevice, IComPorts, IIROutputPorts, IHasBasicTriListWithSmartObject, ICec, IDeviceInfoProvider { + private const int CtpPort = 41795; private readonly Dge100 _dge; + private readonly TsxCcsUcCodec100EthernetReservedSigs _dgeEthernetInfo; + public BasicTriListWithSmartObject Panel { get { return _dge; } } private DeviceConfig _dc; @@ -32,7 +37,14 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs public Dge100Controller(string key, string name, Dge100 device, DeviceConfig dc, CrestronTouchpanelPropertiesConfig props) :base(key, name, device) { - _dge = device; + _dge = device; + _dgeEthernetInfo = _dge.ExtenderEthernetReservedSigs; + _dgeEthernetInfo.DeviceExtenderSigChange += (extender, args) => UpdateDeviceInfo(); + _dgeEthernetInfo.Use(); + + DeviceInfo = new DeviceInfo(); + + _dge.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); }; _dc = dc; @@ -69,8 +81,86 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs #region ICec Members public Cec StreamCec { get { return _dge.HdmiOut.StreamCec; } } - #endregion - + #endregion + + #region Implementation of IDeviceInfoProvider + + public DeviceInfo DeviceInfo { get; private set; } + + public event DeviceInfoChangeHandler DeviceInfoChanged; + + public void UpdateDeviceInfo() + { + DeviceInfo.IpAddress = _dgeEthernetInfo.IpAddressFeedback.StringValue; + DeviceInfo.MacAddress = _dgeEthernetInfo.MacAddressFeedback.StringValue; + + GetFirmwareAndSerialInfo(); + + OnDeviceInfoChange(); + } + + private void GetFirmwareAndSerialInfo() + { + if (String.IsNullOrEmpty(_dgeEthernetInfo.IpAddressFeedback.StringValue)) + { + Debug.Console(1, this, "IP Address information not yet received. No device is online"); + return; + } + + var tcpClient = new GenericTcpIpClient("", _dgeEthernetInfo.IpAddressFeedback.StringValue, CtpPort, 1024){AutoReconnect = false}; + + var gather = new CommunicationGather(tcpClient, "\r\n\r\n"); + + tcpClient.ConnectionChange += (sender, args) => + { + if (!args.Client.IsConnected) + { + return; + } + + args.Client.SendText("ver\r\n"); + }; + + gather.LineReceived += (sender, args) => + { + if (args.Text.ToLower().Contains("host")) + { + DeviceInfo.HostName = args.Text.Split(';')[1].Trim(); + + tcpClient.Disconnect(); + return; + } + + //ignore console prompt + if (args.Text.ToLower().Contains(">")) + { + return; + } + + if (!args.Text.ToLower().Contains("dge")) + { + return; + } + + DeviceInfo.SerialNumber = args.Text.Split('[')[1].Split(' ')[4].Replace("#", ""); + DeviceInfo.FirmwareVersion = args.Text.Split('[')[1].Split(' ')[1]; + + tcpClient.SendText("host\r\n"); + }; + + tcpClient.Connect(); + } + + private void OnDeviceInfoChange() + { + var handler = DeviceInfoChanged; + + if (handler == null) return; + + handler(this, new DeviceInfoEventArgs(DeviceInfo)); + } + + #endregion } public class Dge100ControllerFactory : EssentialsDeviceFactory diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs index 7cc913e2..83c386bc 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs @@ -8,14 +8,16 @@ using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.DeviceInfo; using PepperDash.Essentials.DM.Config; using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.DM { [Description("Wrapper class for all DM-RMC variants")] - public abstract class DmRmcControllerBase : CrestronGenericBridgeableBaseDevice + public abstract class DmRmcControllerBase : CrestronGenericBridgeableBaseDevice, IDeviceInfoProvider { + private const int CtpPort = 41795; private readonly EndpointReceiverBase _rmc; //kept here just in case. Only property or method on this class that's not device-specific is the DMOutput that it's attached to. public StringFeedback VideoOutputResolutionFeedback { get; protected set; } @@ -32,6 +34,10 @@ namespace PepperDash.Essentials.DM PreventRegistration = _rmc.DMOutput != null; AddToFeedbackList(VideoOutputResolutionFeedback, EdidManufacturerFeedback, EdidSerialNumberFeedback, EdidNameFeedback, EdidPreferredTimingFeedback); + + DeviceInfo = new DeviceInfo(); + + _rmc.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); }; } protected void LinkDmRmcToApi(DmRmcControllerBase rmc, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) @@ -79,7 +85,106 @@ namespace PepperDash.Essentials.DM trilist.SetUShortSigAction(joinMap.AudioVideoSource.JoinNumber, a => routing.ExecuteNumericSwitch(a, 1, eRoutingSignalType.AudioVideo)); } - } + + #region Implementation of IDeviceInfoProvider + + public DeviceInfo DeviceInfo { get; private set; } + public event DeviceInfoChangeHandler DeviceInfoChanged; + + public void UpdateDeviceInfo() + { + Debug.Console(1, this, "Updating Device Info"); + + if (_rmc.ConnectedIpList.Count == 0) + { + Debug.Console(1, this, "IP Address information not yet received. No device is online"); + return; + } + + DeviceInfo.IpAddress = _rmc.ConnectedIpList[0].DeviceIpAddress; + + foreach (var ip in _rmc.ConnectedIpList) + { + Debug.Console(0, this, "Connected IP Address: {0}", ip.DeviceIpAddress); + } + + GetFirmwareAndSerialInfo(); + + OnDeviceInfoChange(); + } + + private void GetFirmwareAndSerialInfo() + { + var tcpClient = new GenericTcpIpClient(String.Format("{0}-devInfoSocket", Key), _rmc.ConnectedIpList[0].DeviceIpAddress, CtpPort, 1024) + { + AutoReconnect = false, + }; + + var gather = new CommunicationGather(tcpClient, "\r\n\r\n"); + + tcpClient.ConnectionChange += (sender, args) => + { + if (!args.Client.IsConnected) + { + OnDeviceInfoChange(); + return; + } + + args.Client.SendText("ver\r\n"); + }; + + gather.LineReceived += (sender, args) => + { + //ignore console prompt + if (args.Text.ToLower().Contains(">")) + { + return; + } + + + if (args.Text.ToLower().Contains("host")) + { + DeviceInfo.HostName = args.Text.Split(':')[1].Trim(); + + tcpClient.SendText("maca\r\n"); + + return; + } + + if (args.Text.ToLower().Contains("mac")) + { + DeviceInfo.MacAddress = args.Text.Split(':')[1].Trim().Replace(" ", ":"); + + tcpClient.Disconnect(); + + return; + } + + if (!args.Text.ToLower().Contains("rmc")) + { + return; + } + + DeviceInfo.SerialNumber = args.Text.Split('[')[1].Split(' ')[4].Replace("#", ""); + DeviceInfo.FirmwareVersion = args.Text.Split('[')[1].Split(' ')[1]; + + tcpClient.SendText("host\r\n"); + }; + + tcpClient.Connect(); + } + + private void OnDeviceInfoChange() + { + var handler = DeviceInfoChanged; + + if (handler == null) return; + + handler(this, new DeviceInfoEventArgs(DeviceInfo)); + } + + #endregion + } public abstract class DmHdBaseTControllerBase : CrestronGenericBaseDevice {