From 9e4f34acd5ba966094ccaf1625b4402e4061d260 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 14 Sep 2017 23:05:33 -0600 Subject: [PATCH] Added command for CiscoCodec methods implemented by standard interfaces. Renamed data class files. --- .../Essentials Devices Common.csproj | 5 +- .../VC/CiscoCodec/CiscoCodec.cs | 206 +++++++++++++----- .../{Configuration.cs => xConfiguration.cs} | 0 .../VC/CiscoCodec/xEvent.cs | 138 ++++++++++++ .../VC/CiscoCodec/{Status.cs => xStatus.cs} | 130 ++++++++++- .../VC/VideoCodecBase.cs | 32 +-- 6 files changed, 433 insertions(+), 78 deletions(-) rename Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/{Configuration.cs => xConfiguration.cs} (100%) create mode 100644 Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/xEvent.cs rename Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/{Status.cs => xStatus.cs} (87%) diff --git a/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index ca4e5f5d..fc1c2303 100644 --- a/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -128,10 +128,11 @@ - + + - + diff --git a/Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/CiscoCodec.cs b/Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/CiscoCodec.cs index 048462a6..9e661e88 100644 --- a/Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/CiscoCodec.cs +++ b/Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/CiscoCodec.cs @@ -12,6 +12,7 @@ using Cisco_SX80_Corporate_Phone_Book; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Routing; namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { @@ -33,11 +34,32 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco private CiscoCodecStatus.RootObject CodecStatus; + private CiscoCodecEvents.RootObject CodecEvent; + + /// + /// Gets and returns the scaled volume of the codec + /// protected override Func VolumeLevelFeedbackFunc { get { - return () => CodecStatus.Status.Audio.Volume.IntValue; + return () => CrestronEnvironment.ScaleWithLimits(CodecStatus.Status.Audio.Volume.IntValue, 100, 0, 65535, 0); + } + } + + protected override Func PrivacyModeFeedbackFunc + { + get + { + return () => CodecStatus.Status.Audio.Microphones.Mute.BoolValue; + } + } + + protected Func StandbyStateFeedbackFunc + { + get + { + return () => CodecStatus.Status.Standby.State.BoolValue; } } @@ -63,6 +85,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco string Delimiter = "\r\n"; + int PresentationSource; + // Constructor for IBasicCommunication public CiscoCodec(string key, string name, IBasicCommunication comm, int serverPort) : base(key, name) @@ -71,16 +95,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco SyncState = new CodecSyncState(key + "--sync"); - PortGather = new CommunicationGather(Communication, "\r\n"); - PortGather.IncludeDelimiter = true; + PortGather = new CommunicationGather(Communication, Delimiter); PortGather.LineReceived += this.Port_LineReceived; - //JsonGather = new CommunicationGather(Communication, "}\r\n\r\n"); - //JsonGather.IncludeDelimiter = true; - //JsonGather.LineReceived += new EventHandler(JsonGather_LineReceived); - - Communication.TextReceived += new EventHandler(Communication_TextReceived); - //ServerPort = serverPort; CodecObtp = new CiscoOneButtonToPush(); @@ -91,6 +108,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CodecStatus = new CiscoCodecStatus.RootObject(); + CodecEvent = new CiscoCodecEvents.RootObject(); + CodecStatus.Status.Audio.Volume.ValueChangedAction = VolumeLevelFeedback.FireUpdate; //Client = new HttpsClient(); @@ -112,7 +131,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { socket.ConnectionChange += new EventHandler(socket_ConnectionChange); } - Debug.Console(1, this, "Starting Cisco API Server"); + + InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource(1)), this)); + InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource(2)), this)); + + //Debug.Console(1, this, "Starting Cisco API Server"); //Server.Start(ServerPort); @@ -217,20 +240,20 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco if (!SyncState.InitialSyncComplete) { - switch (args.Text.Trim()) + switch (args.Text.Trim().ToLower()) // remove the whitespace { - case "*r Login successful": + case "*r login successful": { SendText("xPreferences outputmode json"); break; } - case "xPreferences outputmode json": + case "xpreferences outputmode json": { if(!SyncState.InitialStatusMessageWasReceived) SendText("xStatus"); break; } - case "xFeedback register": + case "xfeedback register": { SyncState.FeedbackRegistered(); break; @@ -239,27 +262,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } } - void JsonGather_LineReceived(object sender, GenericCommMethodReceiveTextArgs e) - { - //Debug.Console(1, this, "JSON repsonse length: {0}", e.Text.Length); - - var startPos = e.Text.IndexOf("{"); - var json = e.Text.Substring(startPos, e.Text.Length - startPos); - - //Debug.Console(1, this, "First curly brace found at position {0}. Substring will start at position {1} and continue for {2} characters", startPos, startPos, e.Text.Length - startPos); - - Debug.Console(1, this, "JSON received:\n{0}", json); - - - DeserializeResponse(json); - - - } - public void SendText(string command) { Debug.Console(1, this, "Sending: '{0}'", command); - Communication.SendText(command + "\x0d\x0a"); + Communication.SendText(command + Delimiter); } //private void StartHttpsSession() @@ -458,6 +464,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } } + else if (response.IndexOf("\"Event\":{") > -1) + { + JsonConvert.PopulateObject(response, CodecEvent); + } } catch (Exception ex) @@ -466,14 +476,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } } - void Communication_TextReceived(object sender, GenericCommMethodReceiveTextArgs e) - { - //CodecObtp. - } - public override void ExecuteSwitch(object selector) { - throw new NotImplementedException(); + (selector as Action)(); } protected override Func InCallFeedbackFunc { get { return () => false; } } @@ -486,40 +491,66 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco protected override Func PrivacyModeFeedbackFunc { get { return () => false; } } + /// + /// Gets the first CallId or returns null + /// + /// + private string GetCallId() + { + string callId = null; + + if (CodecStatus.Status.Call.Count > 0) + callId = CodecStatus.Status.Call[0].id; + + return callId; + + } + public override void Dial(string s) { - SendText(string.Format("xCommand Dial Number: {0}", s)); - } + SendText(string.Format("xCommand Dial Number: \"{0}\"", s)); + } + + public void DialBookingId(string s) + { + SendText(string.Format("xCommand Dial BookingId: {0}", s)); + } public override void EndCall() { - //SendText(string.Format("xCommand Accept CallId: {0}", CodecStatus.Status.)); - + SendText(string.Format("xCommand Call Disconnect CallId: {0}", GetCallId())); } public override void AcceptCall() { - + SendText("xCommand Call Accept"); } public override void RejectCall() { - + SendText("xCommand Call Reject"); } public override void SendDtmf(string s) { - + SendText(string.Format("xCommand Call DTMFSend CallId: {0} DTMFString: \"{1}\"", GetCallId(), s)); + } + + public void SelectPresentationSource(int source) + { + PresentationSource = source; + + StartSharing(); } public override void StartSharing() { - + SendText(string.Format("xCommand Presentation Start PresentationSource: {0}", PresentationSource)); } public override void StopSharing() { - + SendText(string.Format("xCommand Presentation Stop PresentationSource: {0}", PresentationSource)); } public override void ReceiveMuteOff() @@ -564,17 +595,92 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public override void PrivacyModeOn() { - + SendText("xCommand Audio Microphones Mute"); } public override void PrivacyModeOff() { - + SendText("xCommand Audio Microphones Unmute"); } public override void PrivacyModeToggle() { - + SendText("xCommand Audio Microphones ToggleMute"); + } + + public override void MuteOff() + { + SendText("xCommand Audio Volume Unmute"); + } + + public override void MuteOn() + { + SendText("xCommand Audio Volume Mute"); + } + + public override void MuteToggle() + { + SendText("xCommand Audio Volume ToggleMute"); + } + + /// + /// Increments the voluem + /// + /// + public override void VolumeUp(bool pressRelease) + { + SendText("xCommand Audio Volume Increase"); + } + + /// + /// Decrements the volume + /// + /// + public override void VolumeDown(bool pressRelease) + { + SendText("xCommand Audio Volume Decrease"); + } + + /// + /// Scales the level and sets the codec to the specified level within its range + /// + /// level from slider (0-65535 range) + public override void SetVolume(ushort level) + { + var scaledLevel = CrestronEnvironment.ScaleWithLimits(level, 65535, 0, 100, 0); + SendText(string.Format("xCommand Audio Volume Set Level: {0}", scaledLevel)); + } + + /// + /// Recalls the default volume on the codec + /// + public void VolumeSetToDefault() + { + SendText("xCommand Audio Volume SetToDefault"); + } + + /// + /// Puts the codec in standby mode + /// + public void StandbyActivate() + { + SendText("xCommand Standby Activate"); + } + + /// + /// Wakes the codec from standby + /// + public void StandbyDeactivate() + { + SendText("xCommand Standby Deactivate"); + } + + /// + /// Reboots the codec + /// + public void Reboot() + { + SendText("xCommand SystemUnit Boot Action: Restart"); } } diff --git a/Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/Configuration.cs b/Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/xConfiguration.cs similarity index 100% rename from Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/Configuration.cs rename to Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/xConfiguration.cs diff --git a/Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/xEvent.cs b/Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/xEvent.cs new file mode 100644 index 00000000..5df6faf8 --- /dev/null +++ b/Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/xEvent.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco +{ + public class CiscoCodecEvents + { + public class CauseValue + { + public string id { get; set; } + public string Value { get; set; } + } + + public class CauseType + { + public string id { get; set; } + public string Value { get; set; } + } + + public class CauseString + { + public string id { get; set; } + public string Value { get; set; } + } + + public class OrigCallDirection + { + public string id { get; set; } + public string Value { get; set; } + } + + public class RemoteURI + { + public string id { get; set; } + public string Value { get; set; } + } + + public class DisplayName + { + public string id { get; set; } + public string Value { get; set; } + } + + public class CallId + { + public string id { get; set; } + public string Value { get; set; } + } + + public class CauseCode + { + public string id { get; set; } + public string Value { get; set; } + } + + public class CauseOrigin + { + public string id { get; set; } + public string Value { get; set; } + } + + public class Protocol + { + public string id { get; set; } + public string Value { get; set; } + } + + public class Duration + { + public string id { get; set; } + public string Value { get; set; } + } + + public class CallType + { + public string id { get; set; } + public string Value { get; set; } + } + + public class CallRate + { + public string id { get; set; } + public string Value { get; set; } + } + + public class Encryption + { + public string id { get; set; } + public string Value { get; set; } + } + + public class RequestedURI + { + public string id { get; set; } + public string Value { get; set; } + } + + public class PeopleCountAverage + { + public string id { get; set; } + public string Value { get; set; } + } + + public class CallDisconnect + { + public string id { get; set; } + public CauseValue CauseValue { get; set; } + public CauseType CauseType { get; set; } + public CauseString CauseString { get; set; } + public OrigCallDirection OrigCallDirection { get; set; } + public RemoteURI RemoteURI { get; set; } + public DisplayName DisplayName { get; set; } + public CallId CallId { get; set; } + public CauseCode CauseCode { get; set; } + public CauseOrigin CauseOrigin { get; set; } + public Protocol Protocol { get; set; } + public Duration Duration { get; set; } + public CallType CallType { get; set; } + public CallRate CallRate { get; set; } + public Encryption Encryption { get; set; } + public RequestedURI RequestedURI { get; set; } + public PeopleCountAverage PeopleCountAverage { get; set; } + } + + public class Event + { + public CallDisconnect CallDisconnect { get; set; } + } + + public class RootObject + { + public Event Event { get; set; } + } + } +} \ No newline at end of file diff --git a/Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/Status.cs b/Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/xStatus.cs similarity index 87% rename from Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/Status.cs rename to Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/xStatus.cs index fb1070b4..44cec29f 100644 --- a/Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/Status.cs +++ b/Essentials Devices Common/Essentials Devices Common/VC/CiscoCodec/xStatus.cs @@ -1072,14 +1072,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public Persistency Persistency { get; set; } } - public class State + public class State : ValueProperty { - public string Value { get; set; } + public bool BoolValue { get; private set; } + + public string Value // Valid values are Standby/EnteringStandby/Halfwake/Off + { + set + { + // If the incoming value is "Of" it sets the BoolValue true, otherwise sets it false + BoolValue = value == "Off"; + OnValueChanged(); + } + } } public class Standby { public State State { get; set; } + + public Standby() + { + State = new State(); + } } public class CompatibilityLevel @@ -1484,10 +1499,118 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public Selfview Selfview { get; set; } } + public class AnswerState + { + public string Value { get; set; } + } + + public class CallType + { + public string Value { get; set; } + } + + public class CallbackNumber + { + public string Value { get; set; } + } + + public class DeviceType + { + public string Value { get; set; } + } + + public class Direction + { + public string Value { get; set; } + } + + public class DisplayName + { + public string Value { get; set; } + } + + public class Duration + { + public string Value { get; set; } + } + + public class Type + { + public string Value { get; set; } + } + + public class Encryption + { + public string id { get; set; } + public Type Type { get; set; } + } + + public class FacilityServiceId + { + public string Value { get; set; } + } + + public class HoldReason + { + public string Value { get; set; } + } + + public class PlacedOnHold + { + public string Value { get; set; } + } + + public class Protocol + { + public string Value { get; set; } + } + + public class ReceiveCallRate + { + public string Value { get; set; } + } + + public class RemoteNumber + { + public string Value { get; set; } + } + + public class Status2 + { + public string Value { get; set; } + } + + public class TransmitCallRate + { + public string Value { get; set; } + } + + public class Call + { + public string id { get; set; } + public AnswerState AnswerState { get; set; } + public CallType CallType { get; set; } + public CallbackNumber CallbackNumber { get; set; } + public DeviceType DeviceType { get; set; } + public Direction Direction { get; set; } + public DisplayName DisplayName { get; set; } + public Duration Duration { get; set; } + public Encryption Encryption { get; set; } + public FacilityServiceId FacilityServiceId { get; set; } + public HoldReason HoldReason { get; set; } + public PlacedOnHold PlacedOnHold { get; set; } + public Protocol Protocol { get; set; } + public ReceiveCallRate ReceiveCallRate { get; set; } + public RemoteNumber RemoteNumber { get; set; } + public Status2 Status { get; set; } + public TransmitCallRate TransmitCallRate { get; set; } + } + public class Status { public Audio Audio { get; set; } public Bookings Bookings { get; set; } + public List Call { get; set; } public Cameras Cameras { get; set; } public Capabilities2 Capabilities { get; set; } public Conference2 Conference { get; set; } @@ -1513,7 +1636,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public Status() { Audio = new Audio(); + Call = new List(); + Standby = new Standby(); } +#warning Figure out how to flag codec as InCall if Call.Count > 0 } public class RootObject diff --git a/Essentials Devices Common/Essentials Devices Common/VC/VideoCodecBase.cs b/Essentials Devices Common/Essentials Devices Common/VC/VideoCodecBase.cs index 68de18e1..8c58105e 100644 --- a/Essentials Devices Common/Essentials Devices Common/VC/VideoCodecBase.cs +++ b/Essentials Devices Common/Essentials Devices Common/VC/VideoCodecBase.cs @@ -123,20 +123,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public BoolFeedback MuteFeedback { get; private set; } - public void MuteOff() - { - - } + public abstract void MuteOff(); - public void MuteOn() - { - - } + public abstract void MuteOn(); - public void SetVolume(ushort level) - { - - } + public abstract void SetVolume(ushort level); public IntFeedback VolumeLevelFeedback { get; private set; } @@ -144,20 +135,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec #region IBasicVolumeControls Members - public void MuteToggle() - { - - } + public abstract void MuteToggle(); - public void VolumeDown(bool pressRelease) - { - - } + public abstract void VolumeDown(bool pressRelease); + + + public abstract void VolumeUp(bool pressRelease); - public void VolumeUp(bool pressRelease) - { - - } #endregion }