diff --git a/.github/scripts/GenerateVersionNumber.ps1 b/.github/scripts/GenerateVersionNumber.ps1 index 467ce883..d9406eea 100644 --- a/.github/scripts/GenerateVersionNumber.ps1 +++ b/.github/scripts/GenerateVersionNumber.ps1 @@ -39,6 +39,10 @@ switch -regex ($Env:GITHUB_REF) { $phase = 'hotfix' $newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER } + '^refs\/heads\/bugfix\/*.' { + $phase = 'hotfix' + $newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER + } } diff --git a/.github/scripts/ZipBuildOutput.ps1 b/.github/scripts/ZipBuildOutput.ps1 index 3f1998bb..ac87aeb7 100644 --- a/.github/scripts/ZipBuildOutput.ps1 +++ b/.github/scripts/ZipBuildOutput.ps1 @@ -26,7 +26,7 @@ Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz } | Copy-Item -Destination ($destination) -Force Write-Host "Getting matching files..." # Get any files from the output folder that match the following extensions -Get-ChildItem -Path $destination | Where-Object {($_.Extension -eq ".clz") -or ($_.Extension -eq ".cpz" -or ($_.Extension -eq ".cplz"))} | ForEach-Object { +Get-ChildItem -Path $destination | Where-Object { ($_.Extension -eq ".clz") -or ($_.Extension -eq ".cpz" -or ($_.Extension -eq ".cplz")) } | ForEach-Object { # Replace the extensions with dll and xml and create an array $filenames = @($($_ -replace "cpz|clz|cplz", "dll"), $($_ -replace "cpz|clz|cplz", "xml")) Write-Host "Filenames:" @@ -36,6 +36,8 @@ Get-ChildItem -Path $destination | Where-Object {($_.Extension -eq ".clz") -or ( Get-ChildItem -Recurse -Path "$($Env:GITHUB_WORKSPACE)" -include $filenames | Copy-Item -Destination ($destination) -Force } } + +Get-ChildItem -Path $destination\*.cpz | Rename-Item -NewName { "$($_.BaseName)-$($Env:VERSION)$($_.Extension)" } Compress-Archive -Path $destination -DestinationPath "$($Env:GITHUB_WORKSPACE)\$($Env:SOLUTION_FILE)-$($Env:VERSION).zip" -Force Write-Host "Output Contents post Zip" Get-ChildItem -Path $destination \ No newline at end of file diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 0dce3868..839ae827 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -5,6 +5,7 @@ on: branches: - feature/* - hotfix/* + - bugfix/* - release/* - development @@ -78,7 +79,8 @@ jobs: # Create the release on the source repo - name: Create Release id: create_release - uses: actions/create-release@v1 + # using contributor's version to allow for pointing at the right commit + uses: fleskesvor/create-release@feature/support-target-commitish with: tag_name: ${{ env.VERSION }} release_name: ${{ env.VERSION }} @@ -143,6 +145,12 @@ jobs: Remove-Item -Path .\*.zip - name: Check directory again run: Get-ChildItem ./ + # Copy Contents of output folder to root directory + - name: Copy Files to root & delete output directory + run: | + Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz") + Get-ChildItem -Path .\output\* | Copy-Item -Destination .\ + Remove-Item -Path .\output -Recurse # Commits the build output to the branch and tags it with the version - name: Commit build output and tag the commit shell: powershell @@ -214,6 +222,12 @@ jobs: Remove-Item -Path .\*.zip - name: Check directory again run: Get-ChildItem ./ + # Copy Contents of output folder to root directory + - name: Copy Files to root & delete output directory + run: | + Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz") + Get-ChildItem -Path .\output\* | Copy-Item -Destination .\ + Remove-Item -Path .\output -Recurse # Commits the build output to the branch and tags it with the version - name: Commit build output and tag the commit shell: powershell diff --git a/PepperDashEssentials/AppServer/Messengers/CameraBaseMessenger.cs b/PepperDashEssentials/AppServer/Messengers/CameraBaseMessenger.cs new file mode 100644 index 00000000..043341a9 --- /dev/null +++ b/PepperDashEssentials/AppServer/Messengers/CameraBaseMessenger.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Devices.Common.Cameras; + +namespace PepperDash.Essentials.AppServer.Messengers +{ + public class CameraBaseMessenger : MessengerBase + { + /// + /// Device being bridged + /// + public CameraBase Camera { get; set; } + + /// + /// Constructor + /// + /// + /// + /// + public CameraBaseMessenger(string key, CameraBase camera, string messagePath) + : base(key, messagePath) + { + if (camera == null) + throw new ArgumentNullException("camera"); + + Camera = camera; + + var presetsCamera = Camera as IHasCameraPresets; + + if (presetsCamera != null) + { + presetsCamera.PresetsListHasChanged += new EventHandler(presetsCamera_PresetsListHasChanged); + } + + } + + void presetsCamera_PresetsListHasChanged(object sender, EventArgs e) + { + var presetsCamera = Camera as IHasCameraPresets; + + var presetList = new List(); + + if (presetsCamera != null) + presetList = presetsCamera.Presets; + + PostStatusMessage(new + { + presets = presetList + }); + } + + protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController) + { + appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendCameraFullMessageObject)); + + var ptzCamera = Camera as IHasCameraPtzControl; + + if (ptzCamera != null) + { + + // Need to evaluate how to pass through these P&H actions. Need a method that takes a bool maybe? + AppServerController.AddAction(MessagePath + "/cameraUp", new PressAndHoldAction((b) => + { + if (b) + ptzCamera.TiltUp(); + else + ptzCamera.TiltStop(); + })); + AppServerController.AddAction(MessagePath + "/cameraDown", new PressAndHoldAction((b) => + { + if (b) + ptzCamera.TiltDown(); + else + ptzCamera.TiltStop(); + })); + AppServerController.AddAction(MessagePath + "/cameraLeft", new PressAndHoldAction((b) => + { + if (b) + ptzCamera.PanLeft(); + else + ptzCamera.PanStop(); + })); + AppServerController.AddAction(MessagePath + "/cameraRight", new PressAndHoldAction((b) => + { + if (b) + ptzCamera.PanRight(); + else + ptzCamera.PanStop(); + })); + AppServerController.AddAction(MessagePath + "/cameraZoomIn", new PressAndHoldAction((b) => + { + if (b) + ptzCamera.ZoomIn(); + else + ptzCamera.ZoomStop(); + })); + AppServerController.AddAction(MessagePath + "/cameraZoomOut", new PressAndHoldAction((b) => + { + if (b) + ptzCamera.ZoomOut(); + else + ptzCamera.ZoomStop(); + })); + } + + if (Camera is IHasCameraAutoMode) + { + appServerController.AddAction(MessagePath + "/cameraModeAuto", new Action((Camera as IHasCameraAutoMode).CameraAutoModeOn)); + appServerController.AddAction(MessagePath + "/cameraModeManual", new Action((Camera as IHasCameraAutoMode).CameraAutoModeOff)); + } + + if (Camera is IPower) + { + appServerController.AddAction(MessagePath + "/cameraModeOff", new Action((Camera as IPower).PowerOff)); + } + + var presetsCamera = Camera as IHasCameraPresets; + + if (presetsCamera != null) + { + for(int i = 1; i <= 6; i++) + { + var preset = i; + appServerController.AddAction(MessagePath + "/cameraPreset" + i, new Action((p) => presetsCamera.PresetSelect(preset))); + } + } + } + + /// + /// Helper method to update the full status of the camera + /// + void SendCameraFullMessageObject() + { + var presetsCamera = Camera as IHasCameraPresets; + + var presetList = new List(); + + if (presetsCamera != null) + presetList = presetsCamera.Presets; + + PostStatusMessage(new + { + cameraMode = GetCameraMode(), + hasPresets = Camera is IHasCameraPresets, + presets = presetList + }); + } + + /// + /// Computes the current camera mode + /// + /// + string GetCameraMode() + { + string m; + if (Camera is IHasCameraAutoMode && (Camera as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.BoolValue) + m = eCameraControlMode.Auto.ToString().ToLower(); + else if (Camera is IPower && !(Camera as IPower).PowerIsOnFeedback.BoolValue) + m = eCameraControlMode.Off.ToString().ToLower(); + else + m = eCameraControlMode.Manual.ToString().ToLower(); + return m; + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/AppServer/Messengers/Ddvc01AtcMessenger.cs b/PepperDashEssentials/AppServer/Messengers/Ddvc01AtcMessenger.cs deleted file mode 100644 index eee94350..00000000 --- a/PepperDashEssentials/AppServer/Messengers/Ddvc01AtcMessenger.cs +++ /dev/null @@ -1,216 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.EthernetCommunication; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Devices.Common.Codec; - -namespace PepperDash.Essentials.AppServer.Messengers -{ - public class Ddvc01AtcMessenger : MessengerBase - { - BasicTriList EISC; - - /// - /// 221 - /// - const uint BDialHangupOnHook = 221; - - /// - /// 251 - /// - const uint BIncomingAnswer = 251; - /// - /// 252 - /// - const uint BIncomingReject = 252; - /// - /// 241 - /// - const uint BSpeedDial1 = 241; - /// - /// 242 - /// - const uint BSpeedDial2 = 242; - /// - /// 243 - /// - const uint BSpeedDial3 = 243; - /// - /// 244 - /// - const uint BSpeedDial4 = 244; - - /// - /// 201 - /// - const uint SCurrentDialString = 201; - /// - /// 211 - /// - const uint SCurrentCallNumber = 211; - /// - /// 212 - /// - const uint SCurrentCallName = 212; - /// - /// 221 - /// - const uint SHookState = 221; - /// - /// 222 - /// - const uint SCallDirection = 222; - - /// - /// 201-212 0-9*# - /// - Dictionary DTMFMap = new Dictionary - { - { "1", 201 }, - { "2", 202 }, - { "3", 203 }, - { "4", 204 }, - { "5", 205 }, - { "6", 206 }, - { "7", 207 }, - { "8", 208 }, - { "9", 209 }, - { "0", 210 }, - { "*", 211 }, - { "#", 212 }, - }; - - /// - /// - /// - CodecActiveCallItem CurrentCallItem; - - - /// - /// - /// - /// - /// - public Ddvc01AtcMessenger(string key, BasicTriList eisc, string messagePath) - : base(key, messagePath) - { - EISC = eisc; - - CurrentCallItem = new CodecActiveCallItem(); - CurrentCallItem.Type = eCodecCallType.Audio; - CurrentCallItem.Id = "-audio-"; - } - - /// - /// - /// - void SendFullStatus() - { - - - this.PostStatusMessage(new - { - calls = GetCurrentCallList(), - currentCallString = EISC.GetString(SCurrentCallNumber), - currentDialString = EISC.GetString(SCurrentDialString), - isInCall = EISC.GetString(SHookState) == "Connected" - }); - } - - /// - /// - /// - /// - protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController) - { - //EISC.SetStringSigAction(SCurrentDialString, s => PostStatusMessage(new { currentDialString = s })); - - EISC.SetStringSigAction(SHookState, s => - { - CurrentCallItem.Status = (eCodecCallStatus)Enum.Parse(typeof(eCodecCallStatus), s, true); - //GetCurrentCallList(); - SendFullStatus(); - }); - - EISC.SetStringSigAction(SCurrentCallNumber, s => - { - CurrentCallItem.Number = s; - SendCallsList(); - }); - - EISC.SetStringSigAction(SCurrentCallName, s => - { - CurrentCallItem.Name = s; - SendCallsList(); - }); - - EISC.SetStringSigAction(SCallDirection, s => - { - CurrentCallItem.Direction = (eCodecCallDirection)Enum.Parse(typeof(eCodecCallDirection), s, true); - SendCallsList(); - }); - - // Add press and holds using helper - Action addPHAction = (s, u) => - AppServerController.AddAction(MessagePath + s, new PressAndHoldAction(b => EISC.SetBool(u, b))); - - // Add straight pulse calls - Action addAction = (s, u) => - AppServerController.AddAction(MessagePath + s, new Action(() => EISC.PulseBool(u, 100))); - addAction("/endCallById", BDialHangupOnHook); - addAction("/endAllCalls", BDialHangupOnHook); - addAction("/acceptById", BIncomingAnswer); - addAction("/rejectById", BIncomingReject); - addAction("/speedDial1", BSpeedDial1); - addAction("/speedDial2", BSpeedDial2); - addAction("/speedDial3", BSpeedDial3); - addAction("/speedDial4", BSpeedDial4); - - // Get status - AppServerController.AddAction(MessagePath + "/fullStatus", new Action(SendFullStatus)); - // Dial on string - AppServerController.AddAction(MessagePath + "/dial", new Action(s => EISC.SetString(SCurrentDialString, s))); - // Pulse DTMF - AppServerController.AddAction(MessagePath + "/dtmf", new Action(s => - { - if (DTMFMap.ContainsKey(s)) - { - EISC.PulseBool(DTMFMap[s], 100); - } - })); - } - - /// - /// - /// - void SendCallsList() - { - PostStatusMessage(new - { - calls = GetCurrentCallList(), - }); - } - - /// - /// Turns the - /// - /// - List GetCurrentCallList() - { - if (CurrentCallItem.Status == eCodecCallStatus.Disconnected) - { - return new List(); - } - else - { - return new List() { CurrentCallItem }; - } - } - } -} \ No newline at end of file diff --git a/PepperDashEssentials/AppServer/Messengers/Ddvc01VtcMessenger.cs b/PepperDashEssentials/AppServer/Messengers/Ddvc01VtcMessenger.cs deleted file mode 100644 index e3de11d0..00000000 --- a/PepperDashEssentials/AppServer/Messengers/Ddvc01VtcMessenger.cs +++ /dev/null @@ -1,648 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.EthernetCommunication; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Devices.Common.Codec; - -namespace PepperDash.Essentials.AppServer.Messengers -{ - public class Ddvc01VtcMessenger : MessengerBase - { - BasicTriList EISC; - - /********* Bools *********/ - /// - /// 724 - /// - const uint BDialHangup = 724; - /// - /// 750 - /// - const uint BCallIncoming = 750; - /// - /// 751 - /// - const uint BIncomingAnswer = 751; - /// - /// 752 - /// - const uint BIncomingReject = 752; - /// - /// 741 - /// - const uint BSpeedDial1 = 741; - /// - /// 742 - /// - const uint BSpeedDial2 = 742; - /// - /// 743 - /// - const uint BSpeedDial3 = 743; - /// - /// 744 - /// - const uint BSpeedDial4 = 744; - /// - /// 800 - /// - const uint BDirectorySearchBusy = 800; - /// - /// 801 - /// - const uint BDirectoryLineSelected = 801; - /// - /// 801 when selected entry is a contact - /// - const uint BDirectoryEntryIsContact = 801; - /// - /// 802 To show/hide back button - /// - const uint BDirectoryIsRoot = 802; - /// - /// 803 Pulse from system to inform us when directory is ready - /// - const uint DDirectoryHasChanged = 803; - /// - /// 804 - /// - const uint BDirectoryRoot = 804; - /// - /// 805 - /// - const uint BDirectoryFolderBack = 805; - /// - /// 806 - /// - const uint BDirectoryDialSelectedLine = 806; - /// - /// 811 - /// - const uint BCameraControlUp = 811; - /// - /// 812 - /// - const uint BCameraControlDown = 812; - /// - /// 813 - /// - const uint BCameraControlLeft = 813; - /// - /// 814 - /// - const uint BCameraControlRight = 814; - /// - /// 815 - /// - const uint BCameraControlZoomIn = 815; - /// - /// 816 - /// - const uint BCameraControlZoomOut = 816; - /// - /// 821 - 826 - /// - const uint BCameraPresetStart = 821; - - /// - /// 831 - /// - const uint BCameraModeAuto = 831; - /// - /// 832 - /// - const uint BCameraModeManual = 832; - /// - /// 833 - /// - const uint BCameraModeOff = 833; - - /// - /// 841 - /// - const uint BCameraSelfView = 841; - - /// - /// 842 - /// - const uint BCameraLayout = 842; - /// - /// 843 - /// - const uint BCameraSupportsAutoMode = 843; - /// - /// 844 - /// - const uint BCameraSupportsOffMode = 844; - - - /********* Ushorts *********/ - /// - /// 760 - /// - const uint UCameraNumberSelect = 760; - /// - /// 801 - /// - const uint UDirectorySelectRow = 801; - /// - /// 801 - /// - const uint UDirectoryRowCount = 801; - - - - /********* Strings *********/ - /// - /// 701 - /// - const uint SCurrentDialString = 701; - /// - /// 702 - /// - const uint SCurrentCallName = 702; - /// - /// 703 - /// - const uint SCurrentCallNumber = 703; - /// - /// 731 - /// - const uint SHookState = 731; - /// - /// 722 - /// - const uint SCallDirection = 722; - /// - /// 751 - /// - const uint SIncomingCallName = 751; - /// - /// 752 - /// - const uint SIncomingCallNumber = 752; - - /// - /// 800 - /// - const uint SDirectorySearchString = 800; - /// - /// 801-1055 - /// - const uint SDirectoryEntriesStart = 801; - /// - /// 1056 - /// - const uint SDirectoryEntrySelectedName = 1056; - /// - /// 1057 - /// - const uint SDirectoryEntrySelectedNumber = 1057; - /// - /// 1058 - /// - const uint SDirectorySelectedFolderName = 1058; - - - /// - /// 701-712 0-9*# - /// - Dictionary DTMFMap = new Dictionary - { - { "1", 701 }, - { "2", 702 }, - { "3", 703 }, - { "4", 704 }, - { "5", 705 }, - { "6", 706 }, - { "7", 707 }, - { "8", 708 }, - { "9", 709 }, - { "0", 710 }, - { "*", 711 }, - { "#", 712 }, - }; - - CodecActiveCallItem CurrentCallItem; - CodecActiveCallItem IncomingCallItem; - - ushort PreviousDirectoryLength = 0; - - /// - /// - /// - /// - /// - public Ddvc01VtcMessenger(string key, BasicTriList eisc, string messagePath) - : base(key, messagePath) - { - EISC = eisc; - - CurrentCallItem = new CodecActiveCallItem(); - CurrentCallItem.Type = eCodecCallType.Video; - CurrentCallItem.Id = "-video-"; - } - - /// - /// - /// - /// - protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController) - { - var asc = appServerController; - EISC.SetStringSigAction(SHookState, s => - { - CurrentCallItem.Status = (eCodecCallStatus)Enum.Parse(typeof(eCodecCallStatus), s, true); - PostFullStatus(); // SendCallsList(); - }); - - EISC.SetStringSigAction(SCurrentCallNumber, s => - { - CurrentCallItem.Number = s; - PostCallsList(); - }); - - EISC.SetStringSigAction(SCurrentCallName, s => - { - CurrentCallItem.Name = s; - PostCallsList(); - }); - - EISC.SetStringSigAction(SCallDirection, s => - { - CurrentCallItem.Direction = (eCodecCallDirection)Enum.Parse(typeof(eCodecCallDirection), s, true); - PostCallsList(); - }); - - EISC.SetBoolSigAction(BCallIncoming, b => - { - if (b) - { - var ica = new CodecActiveCallItem() - { - Direction = eCodecCallDirection.Incoming, - Id = "-video-incoming", - Name = EISC.GetString(SIncomingCallName), - Number = EISC.GetString(SIncomingCallNumber), - Status = eCodecCallStatus.Ringing, - Type = eCodecCallType.Video - }; - IncomingCallItem = ica; - } - else - { - IncomingCallItem = null; - } - PostCallsList(); - }); - - EISC.SetBoolSigAction(BCameraSupportsAutoMode, b => - { - PostStatusMessage(new - { - cameraSupportsAutoMode = b - }); - }); - EISC.SetBoolSigAction(BCameraSupportsOffMode, b => - { - PostStatusMessage(new - { - cameraSupportsOffMode = b - }); - }); - - // Directory insanity - EISC.SetUShortSigAction(UDirectoryRowCount, u => - { - // The length of the list comes in before the list does. - // Splice the sig change operation onto the last string sig that will be changing - // when the directory entries make it through. - if (PreviousDirectoryLength > 0) - { - EISC.ClearStringSigAction(SDirectoryEntriesStart + PreviousDirectoryLength - 1); - } - EISC.SetStringSigAction(SDirectoryEntriesStart + u - 1, s => PostDirectory()); - PreviousDirectoryLength = u; - }); - - EISC.SetStringSigAction(SDirectoryEntrySelectedName, s => - { - PostStatusMessage(new - { - directoryContactSelected = new - { - name = EISC.GetString(SDirectoryEntrySelectedName), - } - }); - }); - - EISC.SetStringSigAction(SDirectoryEntrySelectedNumber, s => - { - PostStatusMessage(new - { - directoryContactSelected = new - { - number = EISC.GetString(SDirectoryEntrySelectedNumber), - } - }); - }); - - EISC.SetStringSigAction(SDirectorySelectedFolderName, s => PostStatusMessage(new - { - directorySelectedFolderName = EISC.GetString(SDirectorySelectedFolderName) - })); - - EISC.SetSigTrueAction(BCameraModeAuto, () => PostCameraMode()); - EISC.SetSigTrueAction(BCameraModeManual, () => PostCameraMode()); - EISC.SetSigTrueAction(BCameraModeOff, () => PostCameraMode()); - - EISC.SetBoolSigAction(BCameraSelfView, b => PostStatusMessage(new - { - cameraSelfView = b - })); - - EISC.SetUShortSigAction(UCameraNumberSelect, (u) => PostSelectedCamera()); - - - // Add press and holds using helper action - Action addPHAction = (s, u) => - AppServerController.AddAction(MessagePath + s, new PressAndHoldAction(b => EISC.SetBool(u, b))); - addPHAction("/cameraUp", BCameraControlUp); - addPHAction("/cameraDown", BCameraControlDown); - addPHAction("/cameraLeft", BCameraControlLeft); - addPHAction("/cameraRight", BCameraControlRight); - addPHAction("/cameraZoomIn", BCameraControlZoomIn); - addPHAction("/cameraZoomOut", BCameraControlZoomOut); - - // Add straight pulse calls using helper action - Action addAction = (s, u) => - AppServerController.AddAction(MessagePath + s, new Action(() => EISC.PulseBool(u, 100))); - addAction("/endCallById", BDialHangup); - addAction("/endAllCalls", BDialHangup); - addAction("/acceptById", BIncomingAnswer); - addAction("/rejectById", BIncomingReject); - addAction("/speedDial1", BSpeedDial1); - addAction("/speedDial2", BSpeedDial2); - addAction("/speedDial3", BSpeedDial3); - addAction("/speedDial4", BSpeedDial4); - addAction("/cameraModeAuto", BCameraModeAuto); - addAction("/cameraModeManual", BCameraModeManual); - addAction("/cameraModeOff", BCameraModeOff); - addAction("/cameraSelfView", BCameraSelfView); - addAction("/cameraLayout", BCameraLayout); - - asc.AddAction("/cameraSelect", new Action(SelectCamera)); - - // camera presets - for(uint i = 0; i < 6; i++) - { - addAction("/cameraPreset" + (i + 1), BCameraPresetStart + i); - } - - asc.AddAction(MessagePath + "/isReady", new Action(PostIsReady)); - // Get status - asc.AddAction(MessagePath + "/fullStatus", new Action(PostFullStatus)); - // Dial on string - asc.AddAction(MessagePath + "/dial", new Action(s => - EISC.SetString(SCurrentDialString, s))); - // Pulse DTMF - asc.AddAction(MessagePath + "/dtmf", new Action(s => - { - if (DTMFMap.ContainsKey(s)) - { - EISC.PulseBool(DTMFMap[s], 100); - } - })); - - // Directory madness - asc.AddAction(MessagePath + "/directoryRoot", new Action(() => EISC.PulseBool(BDirectoryRoot))); - asc.AddAction(MessagePath + "/directoryBack", new Action(() => EISC.PulseBool(BDirectoryFolderBack))); - asc.AddAction(MessagePath + "/directoryById", new Action(s => - { - // the id should contain the line number to forward to simpl - try - { - var u = ushort.Parse(s); - EISC.SetUshort(UDirectorySelectRow, u); - EISC.PulseBool(BDirectoryLineSelected); - } - catch (Exception) - { - Debug.Console(1, this, Debug.ErrorLogLevel.Warning, - "/directoryById request contains non-numeric ID incompatible with DDVC bridge"); - } - - })); - asc.AddAction(MessagePath + "/directorySelectContact", new Action(s => - { - try - { - var u = ushort.Parse(s); - EISC.SetUshort(UDirectorySelectRow, u); - EISC.PulseBool(BDirectoryLineSelected); - } - catch - { - - } - })); - asc.AddAction(MessagePath + "/directoryDialContact", new Action(() => { - EISC.PulseBool(BDirectoryDialSelectedLine); - })); - asc.AddAction(MessagePath + "/getDirectory", new Action(() => - { - if (EISC.GetUshort(UDirectoryRowCount) > 0) - { - PostDirectory(); - } - else - { - EISC.PulseBool(BDirectoryRoot); - } - })); - } - - /// - /// - /// - void PostFullStatus() - { - this.PostStatusMessage(new - { - calls = GetCurrentCallList(), - cameraMode = GetCameraMode(), - cameraSelfView = EISC.GetBool(BCameraSelfView), - cameraSupportsAutoMode = EISC.GetBool(BCameraSupportsAutoMode), - cameraSupportsOffMode = EISC.GetBool(BCameraSupportsOffMode), - currentCallString = EISC.GetString(SCurrentCallNumber), - currentDialString = EISC.GetString(SCurrentDialString), - directoryContactSelected = new - { - name = EISC.GetString(SDirectoryEntrySelectedName), - number = EISC.GetString(SDirectoryEntrySelectedNumber) - }, - directorySelectedFolderName = EISC.GetString(SDirectorySelectedFolderName), - isInCall = EISC.GetString(SHookState) == "Connected", - hasDirectory = true, - hasDirectorySearch = false, - hasRecents = !EISC.BooleanOutput[502].BoolValue, - hasCameras = true, - showCamerasWhenNotInCall = EISC.BooleanOutput[503].BoolValue, - selectedCamera = GetSelectedCamera(), - }); - } - - /// - /// - /// - void PostDirectory() - { - var u = EISC.GetUshort(UDirectoryRowCount); - var items = new List(); - for (uint i = 0; i < u; i++) - { - var name = EISC.GetString(SDirectoryEntriesStart + i); - var id = (i + 1).ToString(); - // is folder or contact? - if (name.StartsWith("[+]")) - { - items.Add(new - { - folderId = id, - name = name - }); - } - else - { - items.Add(new - { - contactId = id, - name = name - }); - } - } - - var directoryMessage = new - { - currentDirectory = new - { - isRootDirectory = EISC.GetBool(BDirectoryIsRoot), - directoryResults = items - } - }; - PostStatusMessage(directoryMessage); - } - - /// - /// - /// - void PostCameraMode() - { - PostStatusMessage(new - { - cameraMode = GetCameraMode() - }); - } - - /// - /// - /// - /// - string GetCameraMode() - { - string m; - if (EISC.GetBool(BCameraModeAuto)) m = "auto"; - else if (EISC.GetBool(BCameraModeManual)) m = "manual"; - else m = "off"; - return m; - } - - void PostSelectedCamera() - { - PostStatusMessage(new - { - selectedCamera = GetSelectedCamera() - }); - } - - /// - /// - /// - string GetSelectedCamera() - { - var num = EISC.GetUshort(UCameraNumberSelect); - string m; - if (num == 100) - { - m = "cameraFar"; - } - else - { - m = "camera" + num; - } - return m; - } - - /// - /// - /// - void PostIsReady() - { - PostStatusMessage(new - { - isReady = true - }); - } - - /// - /// - /// - void PostCallsList() - { - PostStatusMessage(new - { - calls = GetCurrentCallList(), - }); - } - - /// - /// - /// - /// - void SelectCamera(string s) - { - var cam = s.Substring(6); - if (cam.ToLower() == "far") - { - EISC.SetUshort(UCameraNumberSelect, 100); - } - else - { - EISC.SetUshort(UCameraNumberSelect, UInt16.Parse(cam)); - } - } - - /// - /// Turns the - /// - /// - List GetCurrentCallList() - { - var list = new List(); - if (CurrentCallItem.Status != eCodecCallStatus.Disconnected) - { - list.Add(CurrentCallItem); - } - if (EISC.GetBool(BCallIncoming)) { - - } - return list; - } - } -} \ No newline at end of file diff --git a/PepperDashEssentials/AppServer/Messengers/IRunRouteActionMessenger.cs b/PepperDashEssentials/AppServer/Messengers/IRunRouteActionMessenger.cs new file mode 100644 index 00000000..c39d1dfb --- /dev/null +++ b/PepperDashEssentials/AppServer/Messengers/IRunRouteActionMessenger.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Core; +using PepperDash.Essentials.Core; + + +namespace PepperDash.Essentials.AppServer.Messengers +{ + public class IRunRouteActionMessenger : MessengerBase + { + /// + /// Device being bridged + /// + public IRunRouteAction RoutingDevice {get; private set;} + + public IRunRouteActionMessenger(string key, IRunRouteAction routingDevice, string messagePath) + : base(key, messagePath) + { + if (routingDevice == null) + throw new ArgumentNullException("routingDevice"); + + RoutingDevice = routingDevice; + + var routingSink = RoutingDevice as IRoutingSinkNoSwitching; + + if (routingSink != null) + { + routingSink.CurrentSourceChange += new SourceInfoChangeHandler(routingSink_CurrentSourceChange); + } + } + + void routingSink_CurrentSourceChange(SourceListItem info, ChangeType type) + { + SendRoutingFullMessageObject(); + } + + protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController) + { + appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendRoutingFullMessageObject)); + + appServerController.AddAction(MessagePath + "/source", new Action(c => + { + RoutingDevice.RunRouteAction(c.SourceListItem, c.SourceListKey); + })); + + var sinkDevice = RoutingDevice as IRoutingSinkNoSwitching; + if(sinkDevice != null) + { + sinkDevice.CurrentSourceChange += new SourceInfoChangeHandler((o, a) => + { + SendRoutingFullMessageObject(); + }); + } + } + + /// + /// Helper method to update full status of the routing device + /// + void SendRoutingFullMessageObject() + { + var sinkDevice = RoutingDevice as IRoutingSinkNoSwitching; + + if(sinkDevice != null) + { + var sourceKey = sinkDevice.CurrentSourceInfoKey; + + if (string.IsNullOrEmpty(sourceKey)) + sourceKey = "none"; + + PostStatusMessage(new + { + selectedSourceKey = sourceKey + }); + } + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/AppServer/Messengers/SIMPLAtcMessenger.cs b/PepperDashEssentials/AppServer/Messengers/SIMPLAtcMessenger.cs new file mode 100644 index 00000000..5bf042b9 --- /dev/null +++ b/PepperDashEssentials/AppServer/Messengers/SIMPLAtcMessenger.cs @@ -0,0 +1,230 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.EthernetCommunication; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Devices.Common.Codec; + +namespace PepperDash.Essentials.AppServer.Messengers +{ + public class SIMPLAtcMessenger : MessengerBase + { + BasicTriList EISC; + + public SIMPLAtcJoinMap JoinMap {get; private set;} + + ///// + ///// 221 + ///// + //const uint BDialHangupOnHook = 221; + + ///// + ///// 251 + ///// + //const uint BIncomingAnswer = 251; + ///// + ///// 252 + ///// + //const uint BIncomingReject = 252; + ///// + ///// 241 + ///// + //const uint BSpeedDial1 = 241; + ///// + ///// 242 + ///// + //const uint BSpeedDial2 = 242; + ///// + ///// 243 + ///// + //const uint BSpeedDial3 = 243; + ///// + ///// 244 + ///// + //const uint BSpeedDial4 = 244; + + ///// + ///// 201 + ///// + //const uint SCurrentDialString = 201; + ///// + ///// 211 + ///// + //const uint SCurrentCallNumber = 211; + ///// + ///// 212 + ///// + //const uint SCurrentCallName = 212; + ///// + ///// 221 + ///// + //const uint SHookState = 221; + ///// + ///// 222 + ///// + //const uint SCallDirection = 222; + + ///// + ///// 201-212 0-9*# + ///// + //Dictionary DTMFMap = new Dictionary + //{ + // { "1", 201 }, + // { "2", 202 }, + // { "3", 203 }, + // { "4", 204 }, + // { "5", 205 }, + // { "6", 206 }, + // { "7", 207 }, + // { "8", 208 }, + // { "9", 209 }, + // { "0", 210 }, + // { "*", 211 }, + // { "#", 212 }, + //}; + + /// + /// + /// + CodecActiveCallItem CurrentCallItem; + + + /// + /// + /// + /// + /// + public SIMPLAtcMessenger(string key, BasicTriList eisc, string messagePath) + : base(key, messagePath) + { + EISC = eisc; + + JoinMap = new SIMPLAtcJoinMap(201); + + CurrentCallItem = new CodecActiveCallItem(); + CurrentCallItem.Type = eCodecCallType.Audio; + CurrentCallItem.Id = "-audio-"; + } + + /// + /// + /// + void SendFullStatus() + { + + + this.PostStatusMessage(new + { + calls = GetCurrentCallList(), + currentCallString = EISC.GetString(JoinMap.CurrentCallName.JoinNumber), + currentDialString = EISC.GetString(JoinMap.CurrentDialString.JoinNumber), + isInCall = EISC.GetString(JoinMap.HookState.JoinNumber) == "Connected" + }); + } + + /// + /// + /// + /// + protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController) + { + //EISC.SetStringSigAction(SCurrentDialString, s => PostStatusMessage(new { currentDialString = s })); + + EISC.SetStringSigAction(JoinMap.HookState.JoinNumber, s => + { + CurrentCallItem.Status = (eCodecCallStatus)Enum.Parse(typeof(eCodecCallStatus), s, true); + //GetCurrentCallList(); + SendFullStatus(); + }); + + EISC.SetStringSigAction(JoinMap.CurrentCallNumber.JoinNumber, s => + { + CurrentCallItem.Number = s; + SendCallsList(); + }); + + EISC.SetStringSigAction(JoinMap.CurrentCallName.JoinNumber, s => + { + CurrentCallItem.Name = s; + SendCallsList(); + }); + + EISC.SetStringSigAction(JoinMap.CallDirection.JoinNumber, s => + { + CurrentCallItem.Direction = (eCodecCallDirection)Enum.Parse(typeof(eCodecCallDirection), s, true); + SendCallsList(); + }); + + // Add press and holds using helper + Action addPHAction = (s, u) => + AppServerController.AddAction(MessagePath + s, new PressAndHoldAction(b => EISC.SetBool(u, b))); + + // Add straight pulse calls + Action addAction = (s, u) => + AppServerController.AddAction(MessagePath + s, new Action(() => EISC.PulseBool(u, 100))); + addAction("/endCallById", JoinMap.EndCall.JoinNumber); + addAction("/endAllCalls", JoinMap.EndCall.JoinNumber); + addAction("/acceptById", JoinMap.IncomingAnswer.JoinNumber); + addAction("/rejectById", JoinMap.IncomingReject.JoinNumber); + + var speeddialStart = JoinMap.SpeedDialStart.JoinNumber; + var speeddialEnd = JoinMap.SpeedDialStart.JoinNumber + JoinMap.SpeedDialStart.JoinSpan; + + var speedDialIndex = 1; + for (uint i = speeddialStart; i < speeddialEnd; i++) + { + addAction(string.Format("/speedDial{0}", speedDialIndex), i); + speedDialIndex++; + } + + // Get status + AppServerController.AddAction(MessagePath + "/fullStatus", new Action(SendFullStatus)); + // Dial on string + AppServerController.AddAction(MessagePath + "/dial", new Action(s => EISC.SetString(JoinMap.CurrentDialString.JoinNumber, s))); + // Pulse DTMF + AppServerController.AddAction(MessagePath + "/dtmf", new Action(s => + { + var join = JoinMap.Joins[s]; + if (join != null) + { + if (join.JoinNumber > 0) + { + EISC.PulseBool(join.JoinNumber, 100); + } + } + })); + } + + /// + /// + /// + void SendCallsList() + { + PostStatusMessage(new + { + calls = GetCurrentCallList(), + }); + } + + /// + /// Turns the + /// + /// + List GetCurrentCallList() + { + if (CurrentCallItem.Status == eCodecCallStatus.Disconnected) + { + return new List(); + } + else + { + return new List() { CurrentCallItem }; + } + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/AppServer/Messengers/SIMPLCameraMessenger.cs b/PepperDashEssentials/AppServer/Messengers/SIMPLCameraMessenger.cs new file mode 100644 index 00000000..9cf6456f --- /dev/null +++ b/PepperDashEssentials/AppServer/Messengers/SIMPLCameraMessenger.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.EthernetCommunication; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Bridges; +using PepperDash.Essentials.Devices.Common.Cameras; + +namespace PepperDash.Essentials.AppServer.Messengers +{ + public class SIMPLCameraMessenger : MessengerBase + { + BasicTriList EISC; + + CameraControllerJoinMap JoinMap; + + + public SIMPLCameraMessenger(string key, BasicTriList eisc, string messagePath, uint joinStart) + : base(key, messagePath) + { + EISC = eisc; + + JoinMap = new CameraControllerJoinMap(joinStart); + + EISC.SetUShortSigAction(JoinMap.NumberOfPresets.JoinNumber, (u) => SendCameraFullMessageObject()); + + EISC.SetBoolSigAction(JoinMap.CameraModeAuto.JoinNumber, (b) => PostCameraMode()); + EISC.SetBoolSigAction(JoinMap.CameraModeManual.JoinNumber, (b) => PostCameraMode()); + EISC.SetBoolSigAction(JoinMap.CameraModeOff.JoinNumber, (b) => PostCameraMode()); + } + + + protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController) + { + var asc = appServerController; + + asc.AddAction(MessagePath + "/fullStatus", new Action(SendCameraFullMessageObject)); + + // Add press and holds using helper action + Action addPHAction = (s, u) => + asc.AddAction(MessagePath + s, new PressAndHoldAction(b => EISC.SetBool(u, b))); + addPHAction("/cameraUp", JoinMap.TiltUp.JoinNumber); + addPHAction("/cameraDown", JoinMap.TiltDown.JoinNumber); + addPHAction("/cameraLeft", JoinMap.PanLeft.JoinNumber); + addPHAction("/cameraRight", JoinMap.PanRight.JoinNumber); + addPHAction("/cameraZoomIn", JoinMap.ZoomIn.JoinNumber); + addPHAction("/cameraZoomOut", JoinMap.ZoomOut.JoinNumber); + + Action addAction = (s, u) => + asc.AddAction(MessagePath + s, new Action(() => EISC.PulseBool(u, 100))); + + addAction("/cameraModeAuto", JoinMap.CameraModeAuto.JoinNumber); + addAction("/cameraModeManual", JoinMap.CameraModeManual.JoinNumber); + addAction("/cameraModeOff", JoinMap.CameraModeOff.JoinNumber); + + var presetStart = JoinMap.PresetRecallStart.JoinNumber; + var presetEnd = JoinMap.PresetRecallStart.JoinNumber + JoinMap.PresetRecallStart.JoinSpan; + + int presetId = 1; + // camera presets + for (uint i = presetStart; i <= presetEnd; i++) + { + addAction("/cameraPreset" + (presetId), i); + presetId++; + } + } + + public void CustomUnregsiterWithAppServer(MobileControlSystemController appServerController) + { + appServerController.RemoveAction(MessagePath + "/fullStatus"); + + appServerController.RemoveAction(MessagePath + "/cameraUp"); + appServerController.RemoveAction(MessagePath + "/cameraDown"); + appServerController.RemoveAction(MessagePath + "/cameraLeft"); + appServerController.RemoveAction(MessagePath + "/cameraRight"); + appServerController.RemoveAction(MessagePath + "/cameraZoomIn"); + appServerController.RemoveAction(MessagePath + "/cameraZoomOut"); + appServerController.RemoveAction(MessagePath + "/cameraModeAuto"); + appServerController.RemoveAction(MessagePath + "/cameraModeManual"); + appServerController.RemoveAction(MessagePath + "/cameraModeOff"); + + EISC.SetUShortSigAction(JoinMap.NumberOfPresets.JoinNumber, null); + + EISC.SetBoolSigAction(JoinMap.CameraModeAuto.JoinNumber, null); + EISC.SetBoolSigAction(JoinMap.CameraModeManual.JoinNumber, null); + EISC.SetBoolSigAction(JoinMap.CameraModeOff.JoinNumber, null); + } + + /// + /// Helper method to update the full status of the camera + /// + void SendCameraFullMessageObject() + { + var presetList = new List(); + + // Build a list of camera presets based on the names and count + if (EISC.GetBool(JoinMap.SupportsPresets.JoinNumber)) + { + var presetStart = JoinMap.PresetLabelStart.JoinNumber; + var presetEnd = JoinMap.PresetLabelStart.JoinNumber + JoinMap.NumberOfPresets.JoinNumber; + + var presetId = 1; + for (uint i = presetStart; i < presetEnd; i++) + { + var presetName = EISC.GetString(i); + var preset = new CameraPreset(presetId, presetName, string.IsNullOrEmpty(presetName), true); + presetList.Add(preset); + presetId++; + } + } + + PostStatusMessage(new + { + cameraMode = GetCameraMode(), + hasPresets = EISC.GetBool(JoinMap.SupportsPresets.JoinNumber), + presets = presetList + }); + } + + /// + /// + /// + void PostCameraMode() + { + PostStatusMessage(new + { + cameraMode = GetCameraMode() + }); + } + + /// + /// Computes the current camera mode + /// + /// + string GetCameraMode() + { + string m; + if (EISC.GetBool(JoinMap.CameraModeAuto.JoinNumber)) m = eCameraControlMode.Auto.ToString().ToLower(); + else if (EISC.GetBool(JoinMap.CameraModeManual.JoinNumber)) m = eCameraControlMode.Manual.ToString().ToLower(); + else m = eCameraControlMode.Off.ToString().ToLower(); + return m; + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/AppServer/Messengers/SIMPLRouteMessenger.cs b/PepperDashEssentials/AppServer/Messengers/SIMPLRouteMessenger.cs new file mode 100644 index 00000000..7b8c26d4 --- /dev/null +++ b/PepperDashEssentials/AppServer/Messengers/SIMPLRouteMessenger.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; + +using PepperDash.Core; +using PepperDash.Essentials.Core; + + +namespace PepperDash.Essentials.AppServer.Messengers +{ + public class SIMPLRouteMessenger : MessengerBase + { + BasicTriList EISC; + + uint JoinStart; + + public class StringJoin + { + /// + /// 1 + /// + public const uint CurrentSource = 1; + } + + public SIMPLRouteMessenger(string key, BasicTriList eisc, string messagePath, uint joinStart) + : base(key, messagePath) + { + EISC = eisc; + JoinStart = joinStart - 1; + + EISC.SetStringSigAction(JoinStart + StringJoin.CurrentSource, (s) => SendRoutingFullMessageObject(s)); + } + + protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController) + { + appServerController.AddAction(MessagePath + "/fullStatus", new Action(() => + { + SendRoutingFullMessageObject(EISC.GetString(JoinStart + StringJoin.CurrentSource)); + })); + + appServerController.AddAction(MessagePath +"/source", new Action(c => + { + EISC.SetString(JoinStart + StringJoin.CurrentSource, c.SourceListItem); + })); + + } + + public void CustomUnregsiterWithAppServer(MobileControlSystemController appServerController) + { + appServerController.RemoveAction(MessagePath + "/fullStatus"); + appServerController.RemoveAction(MessagePath + "/source"); + + EISC.SetStringSigAction(JoinStart + StringJoin.CurrentSource, null); + } + + /// + /// Helper method to update full status of the routing device + /// + void SendRoutingFullMessageObject(string sourceKey) + { + if (string.IsNullOrEmpty(sourceKey)) + sourceKey = "none"; + + PostStatusMessage(new + { + selectedSourceKey = sourceKey + }); + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/AppServer/Messengers/SIMPLVtcMessenger.cs b/PepperDashEssentials/AppServer/Messengers/SIMPLVtcMessenger.cs new file mode 100644 index 00000000..c67e335e --- /dev/null +++ b/PepperDashEssentials/AppServer/Messengers/SIMPLVtcMessenger.cs @@ -0,0 +1,665 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.EthernetCommunication; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Devices.Common.Codec; +using PepperDash.Essentials.Devices.Common.Cameras; + +namespace PepperDash.Essentials.AppServer.Messengers +{ + public class SIMPLVtcMessenger : MessengerBase + { + BasicTriList EISC; + + public SIMPLVtcJoinMap JoinMap { get; private set; } + + ///********* Bools *********/ + ///// + ///// 724 + ///// + //const uint BDialHangup = 724; + ///// + ///// 750 + ///// + //const uint BCallIncoming = 750; + ///// + ///// 751 + ///// + //const uint BIncomingAnswer = 751; + ///// + ///// 752 + ///// + //const uint BIncomingReject = 752; + ///// + ///// 741 + ///// + //const uint BSpeedDial1 = 741; + ///// + ///// 742 + ///// + //const uint BSpeedDial2 = 742; + ///// + ///// 743 + ///// + //const uint BSpeedDial3 = 743; + ///// + ///// 744 + ///// + //const uint BSpeedDial4 = 744; + ///// + ///// 800 + ///// + //const uint BDirectorySearchBusy = 800; + ///// + ///// 801 + ///// + //const uint BDirectoryLineSelected = 801; + ///// + ///// 801 when selected entry is a contact + ///// + //const uint BDirectoryEntryIsContact = 801; + ///// + ///// 802 To show/hide back button + ///// + //const uint BDirectoryIsRoot = 802; + ///// + ///// 803 Pulse from system to inform us when directory is ready + ///// + //const uint BDirectoryHasChanged = 803; + ///// + ///// 804 + ///// + //const uint BDirectoryRoot = 804; + ///// + ///// 805 + ///// + //const uint BDirectoryFolderBack = 805; + ///// + ///// 806 + ///// + //const uint BDirectoryDialSelectedLine = 806; + ///// + ///// 811 + ///// + //const uint BCameraControlUp = 811; + ///// + ///// 812 + ///// + //const uint BCameraControlDown = 812; + ///// + ///// 813 + ///// + //const uint BCameraControlLeft = 813; + ///// + ///// 814 + ///// + //const uint BCameraControlRight = 814; + ///// + ///// 815 + ///// + //const uint BCameraControlZoomIn = 815; + ///// + ///// 816 + ///// + //const uint BCameraControlZoomOut = 816; + ///// + ///// 821 - 826 + ///// + //const uint BCameraPresetStart = 821; + + ///// + ///// 831 + ///// + //const uint BCameraModeAuto = 831; + ///// + ///// 832 + ///// + //const uint BCameraModeManual = 832; + ///// + ///// 833 + ///// + //const uint BCameraModeOff = 833; + + ///// + ///// 841 + ///// + //const uint BCameraSelfView = 841; + + ///// + ///// 842 + ///// + //const uint BCameraLayout = 842; + ///// + ///// 843 + ///// + //const uint BCameraSupportsAutoMode = 843; + ///// + ///// 844 + ///// + //const uint BCameraSupportsOffMode = 844; + + + ///********* Ushorts *********/ + ///// + ///// 760 + ///// + //const uint UCameraNumberSelect = 760; + ///// + ///// 801 + ///// + //const uint UDirectorySelectRow = 801; + ///// + ///// 801 + ///// + //const uint UDirectoryRowCount = 801; + + + + ///********* Strings *********/ + ///// + ///// 701 + ///// + //const uint SCurrentDialString = 701; + ///// + ///// 702 + ///// + //const uint SCurrentCallName = 702; + ///// + ///// 703 + ///// + //const uint SCurrentCallNumber = 703; + ///// + ///// 731 + ///// + //const uint SHookState = 731; + ///// + ///// 722 + ///// + //const uint SCallDirection = 722; + ///// + ///// 751 + ///// + //const uint SIncomingCallName = 751; + ///// + ///// 752 + ///// + //const uint SIncomingCallNumber = 752; + + ///// + ///// 800 + ///// + //const uint SDirectorySearchString = 800; + ///// + ///// 801-1055 + ///// + //const uint SDirectoryEntriesStart = 801; + ///// + ///// 1056 + ///// + //const uint SDirectoryEntrySelectedName = 1056; + ///// + ///// 1057 + ///// + //const uint SDirectoryEntrySelectedNumber = 1057; + ///// + ///// 1058 + ///// + //const uint SDirectorySelectedFolderName = 1058; + + + ///// + ///// 701-712 0-9*# + ///// + //Dictionary DTMFMap = new Dictionary + //{ + // { "1", 701 }, + // { "2", 702 }, + // { "3", 703 }, + // { "4", 704 }, + // { "5", 705 }, + // { "6", 706 }, + // { "7", 707 }, + // { "8", 708 }, + // { "9", 709 }, + // { "0", 710 }, + // { "*", 711 }, + // { "#", 712 }, + //}; + + CodecActiveCallItem CurrentCallItem; + CodecActiveCallItem IncomingCallItem; + + ushort PreviousDirectoryLength = 701; + + /// + /// + /// + /// + /// + public SIMPLVtcMessenger(string key, BasicTriList eisc, string messagePath) + : base(key, messagePath) + { + EISC = eisc; + + JoinMap = new SIMPLVtcJoinMap(701); + + CurrentCallItem = new CodecActiveCallItem(); + CurrentCallItem.Type = eCodecCallType.Video; + CurrentCallItem.Id = "-video-"; + } + + /// + /// + /// + /// + protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController) + { + var asc = appServerController; + EISC.SetStringSigAction(JoinMap.HookState.JoinNumber, s => + { + CurrentCallItem.Status = (eCodecCallStatus)Enum.Parse(typeof(eCodecCallStatus), s, true); + PostFullStatus(); // SendCallsList(); + }); + + EISC.SetStringSigAction(JoinMap.CurrentCallNumber.JoinNumber, s => + { + CurrentCallItem.Number = s; + PostCallsList(); + }); + + EISC.SetStringSigAction(JoinMap.CurrentCallName.JoinNumber, s => + { + CurrentCallItem.Name = s; + PostCallsList(); + }); + + EISC.SetStringSigAction(JoinMap.CallDirection.JoinNumber, s => + { + CurrentCallItem.Direction = (eCodecCallDirection)Enum.Parse(typeof(eCodecCallDirection), s, true); + PostCallsList(); + }); + + EISC.SetBoolSigAction(JoinMap.IncomingCall.JoinNumber, b => + { + if (b) + { + var ica = new CodecActiveCallItem() + { + Direction = eCodecCallDirection.Incoming, + Id = "-video-incoming", + Name = EISC.GetString(JoinMap.IncomingCallName.JoinNumber), + Number = EISC.GetString(JoinMap.IncomingCallNumber.JoinNumber), + Status = eCodecCallStatus.Ringing, + Type = eCodecCallType.Video + }; + IncomingCallItem = ica; + } + else + { + IncomingCallItem = null; + } + PostCallsList(); + }); + + EISC.SetBoolSigAction(JoinMap.CameraSupportsAutoMode.JoinNumber, b => + { + PostStatusMessage(new + { + cameraSupportsAutoMode = b + }); + }); + EISC.SetBoolSigAction(JoinMap.CameraSupportsOffMode.JoinNumber, b => + { + PostStatusMessage(new + { + cameraSupportsOffMode = b + }); + }); + + // Directory insanity + EISC.SetUShortSigAction(JoinMap.DirectoryRowCount.JoinNumber, u => + { + // The length of the list comes in before the list does. + // Splice the sig change operation onto the last string sig that will be changing + // when the directory entries make it through. + if (PreviousDirectoryLength > 0) + { + EISC.ClearStringSigAction(JoinMap.DirectoryEntriesStart.JoinNumber + PreviousDirectoryLength - 1); + } + EISC.SetStringSigAction(JoinMap.DirectoryEntriesStart.JoinNumber + u - 1, s => PostDirectory()); + PreviousDirectoryLength = u; + }); + + EISC.SetStringSigAction(JoinMap.DirectoryEntrySelectedName.JoinNumber, s => + { + PostStatusMessage(new + { + directoryContactSelected = new + { + name = EISC.GetString(JoinMap.DirectoryEntrySelectedName.JoinNumber), + } + }); + }); + + EISC.SetStringSigAction(JoinMap.DirectoryEntrySelectedNumber.JoinNumber, s => + { + PostStatusMessage(new + { + directoryContactSelected = new + { + number = EISC.GetString(JoinMap.DirectoryEntrySelectedNumber.JoinNumber), + } + }); + }); + + EISC.SetStringSigAction(JoinMap.DirectorySelectedFolderName.JoinNumber, s => PostStatusMessage(new + { + directorySelectedFolderName = EISC.GetString(JoinMap.DirectorySelectedFolderName.JoinNumber) + })); + + EISC.SetSigTrueAction(JoinMap.CameraModeAuto.JoinNumber, () => PostCameraMode()); + EISC.SetSigTrueAction(JoinMap.CameraModeManual.JoinNumber, () => PostCameraMode()); + EISC.SetSigTrueAction(JoinMap.CameraModeOff.JoinNumber, () => PostCameraMode()); + + EISC.SetBoolSigAction(JoinMap.CameraSelfView.JoinNumber, b => PostStatusMessage(new + { + cameraSelfView = b + })); + + EISC.SetUShortSigAction(JoinMap.CameraNumberSelect.JoinNumber, (u) => PostSelectedCamera()); + + + // Add press and holds using helper action + Action addPHAction = (s, u) => + AppServerController.AddAction(MessagePath + s, new PressAndHoldAction(b => EISC.SetBool(u, b))); + addPHAction("/cameraUp", JoinMap.CameraTiltUp.JoinNumber); + addPHAction("/cameraDown", JoinMap.CameraTiltDown.JoinNumber); + addPHAction("/cameraLeft", JoinMap.CameraPanLeft.JoinNumber); + addPHAction("/cameraRight", JoinMap.CameraPanRight.JoinNumber); + addPHAction("/cameraZoomIn", JoinMap.CameraZoomIn.JoinNumber); + addPHAction("/cameraZoomOut", JoinMap.CameraZoomOut.JoinNumber); + + // Add straight pulse calls using helper action + Action addAction = (s, u) => + AppServerController.AddAction(MessagePath + s, new Action(() => EISC.PulseBool(u, 100))); + addAction("/endCallById", JoinMap.EndCall.JoinNumber); + addAction("/endAllCalls", JoinMap.EndCall.JoinNumber); + addAction("/acceptById", JoinMap.IncomingAnswer.JoinNumber); + addAction("/rejectById", JoinMap.IncomingReject.JoinNumber); + + var speeddialStart = JoinMap.SpeedDialStart.JoinNumber; + var speeddialEnd = JoinMap.SpeedDialStart.JoinNumber + JoinMap.SpeedDialStart.JoinSpan; + + var speedDialIndex = 1; + for (uint i = speeddialStart; i < speeddialEnd; i++) + { + addAction(string.Format("/speedDial{0}", speedDialIndex), i); + speedDialIndex++; + } + + addAction("/cameraModeAuto", JoinMap.CameraModeAuto.JoinNumber); + addAction("/cameraModeManual", JoinMap.CameraModeManual.JoinNumber); + addAction("/cameraModeOff", JoinMap.CameraModeOff.JoinNumber); + addAction("/cameraSelfView", JoinMap.CameraSelfView.JoinNumber); + addAction("/cameraLayout", JoinMap.CameraLayout.JoinNumber); + + asc.AddAction("/cameraSelect", new Action(SelectCamera)); + + // camera presets + for(uint i = 0; i < 6; i++) + { + addAction("/cameraPreset" + (i + 1), JoinMap.CameraPresetStart.JoinNumber + i); + } + + asc.AddAction(MessagePath + "/isReady", new Action(PostIsReady)); + // Get status + asc.AddAction(MessagePath + "/fullStatus", new Action(PostFullStatus)); + // Dial on string + asc.AddAction(MessagePath + "/dial", new Action(s => + EISC.SetString(JoinMap.CurrentDialString.JoinNumber, s))); + // Pulse DTMF + AppServerController.AddAction(MessagePath + "/dtmf", new Action(s => + { + var join = JoinMap.Joins[s]; + if (join != null) + { + if (join.JoinNumber > 0) + { + EISC.PulseBool(join.JoinNumber, 100); + } + } + })); + + // Directory madness + asc.AddAction(MessagePath + "/directoryRoot", new Action(() => EISC.PulseBool(JoinMap.DirectoryRoot.JoinNumber))); + asc.AddAction(MessagePath + "/directoryBack", new Action(() => EISC.PulseBool(JoinMap.DirectoryFolderBack.JoinNumber))); + asc.AddAction(MessagePath + "/directoryById", new Action(s => + { + // the id should contain the line number to forward to simpl + try + { + var u = ushort.Parse(s); + EISC.SetUshort(JoinMap.DirectorySelectRow.JoinNumber, u); + EISC.PulseBool(JoinMap.DirectoryLineSelected.JoinNumber); + } + catch (Exception) + { + Debug.Console(1, this, Debug.ErrorLogLevel.Warning, + "/directoryById request contains non-numeric ID incompatible with DDVC bridge"); + } + + })); + asc.AddAction(MessagePath + "/directorySelectContact", new Action(s => + { + try + { + var u = ushort.Parse(s); + EISC.SetUshort(JoinMap.DirectorySelectRow.JoinNumber, u); + EISC.PulseBool(JoinMap.DirectoryLineSelected.JoinNumber); + } + catch + { + + } + })); + asc.AddAction(MessagePath + "/directoryDialContact", new Action(() => { + EISC.PulseBool(JoinMap.DirectoryDialSelectedLine.JoinNumber); + })); + asc.AddAction(MessagePath + "/getDirectory", new Action(() => + { + if (EISC.GetUshort(JoinMap.DirectoryRowCount.JoinNumber) > 0) + { + PostDirectory(); + } + else + { + EISC.PulseBool(JoinMap.DirectoryRoot.JoinNumber); + } + })); + } + + /// + /// + /// + void PostFullStatus() + { + this.PostStatusMessage(new + { + calls = GetCurrentCallList(), + cameraMode = GetCameraMode(), + cameraSelfView = EISC.GetBool(JoinMap.CameraSelfView.JoinNumber), + cameraSupportsAutoMode = EISC.GetBool(JoinMap.CameraSupportsAutoMode.JoinNumber), + cameraSupportsOffMode = EISC.GetBool(JoinMap.CameraSupportsOffMode.JoinNumber), + currentCallString = EISC.GetString(JoinMap.CurrentCallNumber.JoinNumber), + currentDialString = EISC.GetString(JoinMap.CurrentDialString.JoinNumber), + directoryContactSelected = new + { + name = EISC.GetString(JoinMap.DirectoryEntrySelectedName.JoinNumber), + number = EISC.GetString(JoinMap.DirectoryEntrySelectedNumber.JoinNumber) + }, + directorySelectedFolderName = EISC.GetString(JoinMap.DirectorySelectedFolderName.JoinNumber), + isInCall = EISC.GetString(JoinMap.HookState.JoinNumber) == "Connected", + hasDirectory = true, + hasDirectorySearch = false, + hasRecents = !EISC.BooleanOutput[502].BoolValue, + hasCameras = true, + showCamerasWhenNotInCall = EISC.BooleanOutput[503].BoolValue, + selectedCamera = GetSelectedCamera(), + }); + } + + /// + /// + /// + void PostDirectory() + { + var u = EISC.GetUshort(JoinMap.DirectoryRowCount.JoinNumber); + var items = new List(); + for (uint i = 0; i < u; i++) + { + var name = EISC.GetString(JoinMap.DirectoryEntriesStart.JoinNumber + i); + var id = (i + 1).ToString(); + // is folder or contact? + if (name.StartsWith("[+]")) + { + items.Add(new + { + folderId = id, + name = name + }); + } + else + { + items.Add(new + { + contactId = id, + name = name + }); + } + } + + var directoryMessage = new + { + currentDirectory = new + { + isRootDirectory = EISC.GetBool(JoinMap.DirectoryIsRoot.JoinNumber), + directoryResults = items + } + }; + PostStatusMessage(directoryMessage); + } + + /// + /// + /// + void PostCameraMode() + { + PostStatusMessage(new + { + cameraMode = GetCameraMode() + }); + } + + /// + /// + /// + /// + string GetCameraMode() + { + string m; + if (EISC.GetBool(JoinMap.CameraModeAuto.JoinNumber)) m = eCameraControlMode.Auto.ToString().ToLower(); + else if (EISC.GetBool(JoinMap.CameraModeManual.JoinNumber)) m = eCameraControlMode.Manual.ToString().ToLower(); + else m = eCameraControlMode.Off.ToString().ToLower(); + return m; + } + + void PostSelectedCamera() + { + PostStatusMessage(new + { + selectedCamera = GetSelectedCamera() + }); + } + + /// + /// + /// + string GetSelectedCamera() + { + var num = EISC.GetUshort(JoinMap.CameraNumberSelect.JoinNumber); + string m; + if (num == 100) + { + m = "cameraFar"; + } + else + { + m = "camera" + num; + } + return m; + } + + /// + /// + /// + void PostIsReady() + { + PostStatusMessage(new + { + isReady = true + }); + } + + /// + /// + /// + void PostCallsList() + { + PostStatusMessage(new + { + calls = GetCurrentCallList(), + }); + } + + /// + /// + /// + /// + void SelectCamera(string s) + { + var cam = s.Substring(6); + if (cam.ToLower() == "far") + { + EISC.SetUshort(JoinMap.CameraNumberSelect.JoinNumber, 100); + } + else + { + EISC.SetUshort(JoinMap.CameraNumberSelect.JoinNumber, UInt16.Parse(cam)); + } + } + + /// + /// Turns the + /// + /// + List GetCurrentCallList() + { + var list = new List(); + if (CurrentCallItem.Status != eCodecCallStatus.Disconnected) + { + list.Add(CurrentCallItem); + } + if (EISC.GetBool(JoinMap.IncomingCall.JoinNumber)) + { + + } + return list; + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/AppServer/Messengers/SimplMessengerPropertiesConfig.cs b/PepperDashEssentials/AppServer/Messengers/SimplMessengerPropertiesConfig.cs new file mode 100644 index 00000000..4438c457 --- /dev/null +++ b/PepperDashEssentials/AppServer/Messengers/SimplMessengerPropertiesConfig.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Essentials.Bridges; +using PepperDash.Essentials.Core.Bridges; + +namespace PepperDash.Essentials.AppServer.Messengers +{ + /// + /// Properties to configure a SIMPL Messenger + /// + public class SimplMessengerPropertiesConfig : EiscApiPropertiesConfig.ApiDevicePropertiesConfig + { + } +} \ No newline at end of file diff --git a/PepperDashEssentials/AppServer/Messengers/SystemMonitorMessenger.cs b/PepperDashEssentials/AppServer/Messengers/SystemMonitorMessenger.cs index 080fbd78..9e41722e 100644 --- a/PepperDashEssentials/AppServer/Messengers/SystemMonitorMessenger.cs +++ b/PepperDashEssentials/AppServer/Messengers/SystemMonitorMessenger.cs @@ -1,11 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using Crestron.SimplSharp; - -using Newtonsoft.Json; - using PepperDash.Core; using PepperDash.Essentials.Core.Monitoring; @@ -23,11 +17,11 @@ namespace PepperDash.Essentials.AppServer.Messengers SysMon = sysMon; - SysMon.SystemMonitorPropertiesChanged += new EventHandler(SysMon_SystemMonitorPropertiesChanged); + SysMon.SystemMonitorPropertiesChanged += SysMon_SystemMonitorPropertiesChanged; foreach (var p in SysMon.ProgramStatusFeedbackCollection) { - p.Value.ProgramInfoChanged += new EventHandler(ProgramInfoChanged); + p.Value.ProgramInfoChanged += ProgramInfoChanged; } CrestronConsole.AddNewConsoleCommand(s => SendFullStatusMessage(), "SendFullSysMonStatus", "Sends the full System Monitor Status", ConsoleAccessLevelEnum.AccessOperator); @@ -72,18 +66,15 @@ namespace PepperDash.Essentials.AppServer.Messengers Debug.Console(1, "Posting System Monitor Status Message."); // This takes a while, launch a new thread - CrestronInvoke.BeginInvoke((o) => + CrestronInvoke.BeginInvoke(o => PostStatusMessage(new { - PostStatusMessage(new - { - timeZone = SysMon.TimeZoneFeedback.IntValue, - timeZoneName = SysMon.TimeZoneTextFeedback.StringValue, - ioControllerVersion = SysMon.IOControllerVersionFeedback.StringValue, - snmpVersion = SysMon.SnmpVersionFeedback.StringValue, - bacnetVersion = SysMon.BACnetAppVersionFeedback.StringValue, - controllerVersion = SysMon.ControllerVersionFeedback.StringValue - }); - }); + timeZone = SysMon.TimeZoneFeedback.IntValue, + timeZoneName = SysMon.TimeZoneTextFeedback.StringValue, + ioControllerVersion = SysMon.IoControllerVersionFeedback.StringValue, + snmpVersion = SysMon.SnmpVersionFeedback.StringValue, + bacnetVersion = SysMon.BaCnetAppVersionFeedback.StringValue, + controllerVersion = SysMon.ControllerVersionFeedback.StringValue + })); } protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController) diff --git a/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs b/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs index 29c80085..0ee943c9 100644 --- a/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs +++ b/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs @@ -7,6 +7,8 @@ using Crestron.SimplSharp; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using PepperDash.Core; + using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.Cameras; using PepperDash.Essentials.Devices.Common.VideoCodec; @@ -202,6 +204,59 @@ namespace PepperDash.Essentials.AppServer.Messengers { appServerController.AddAction(MessagePath + "/getCallHistory", new Action(GetCallHistory)); } + var cameraCodec = Codec as IHasCodecCameras; + if (cameraCodec != null) + { + Debug.Console(2, this, "Adding IHasCodecCameras Actions"); + + cameraCodec.CameraSelected += new EventHandler(cameraCodec_CameraSelected); + + appServerController.AddAction(MessagePath + "/cameraSelect", new Action(s => cameraCodec.SelectCamera(s))); + + MapCameraActions(); + + var presetsCodec = Codec as IHasCodecRoomPresets; + if (presetsCodec != null) + { + Debug.Console(2, this, "Adding IHasCodecRoomPresets Actions"); + + presetsCodec.CodecRoomPresetsListHasChanged += new EventHandler(presetsCodec_CameraPresetsListHasChanged); + + appServerController.AddAction(MessagePath + "/cameraPreset", new Action(u => presetsCodec.CodecRoomPresetSelect(u))); + appServerController.AddAction(MessagePath + "/cameraPresetStore", new Action(p => presetsCodec.CodecRoomPresetStore(p.ID, p.Description))); + } + + var speakerTrackCodec = Codec as IHasCameraAutoMode; + if (speakerTrackCodec != null) + { + Debug.Console(2, this, "Adding IHasCameraAutoMode Actions"); + + speakerTrackCodec.CameraAutoModeIsOnFeedback.OutputChange += new EventHandler(CameraAutoModeIsOnFeedback_OutputChange); + + appServerController.AddAction(MessagePath + "/cameraAuto", new Action(speakerTrackCodec.CameraAutoModeOn)); + appServerController.AddAction(MessagePath + "/cameraManual", new Action(speakerTrackCodec.CameraAutoModeOff)); + } + } + + var selfViewCodec = Codec as IHasCodecSelfView; + + if (selfViewCodec != null) + { + Debug.Console(2, this, "Adding IHasCodecSelfView Actions"); + + appServerController.AddAction(MessagePath + "/cameraSelfView", new Action(selfViewCodec.SelfViewModeToggle)); + } + + var layoutsCodec = Codec as IHasCodecLayouts; + + if (layoutsCodec != null) + { + Debug.Console(2, this, "Adding IHasCodecLayouts Actions"); + + appServerController.AddAction(MessagePath + "/cameraRemoteView", new Action(layoutsCodec.LocalLayoutToggle)); + } + + Debug.Console(2, this, "Adding Privacy & Standby Actions"); appServerController.AddAction(MessagePath + "/privacyModeOn", new Action(Codec.PrivacyModeOn)); appServerController.AddAction(MessagePath + "/privacyModeOff", new Action(Codec.PrivacyModeOff)); @@ -212,6 +267,89 @@ namespace PepperDash.Essentials.AppServer.Messengers appServerController.AddAction(MessagePath + "/standbyOff", new Action(Codec.StandbyDeactivate)); } + void presetsCodec_CameraPresetsListHasChanged(object sender, EventArgs e) + { + PostCameraPresets(); + } + + void CameraAutoModeIsOnFeedback_OutputChange(object sender, PepperDash.Essentials.Core.FeedbackEventArgs e) + { + PostCameraMode(); + } + + + void cameraCodec_CameraSelected(object sender, CameraSelectedEventArgs e) + { + MapCameraActions(); + PostSelectedCamera(); + } + + /// + /// Maps the camera control actions to the current selected camera on the codec + /// + void MapCameraActions() + { + var cameraCodec = Codec as IHasCameras; + + if (cameraCodec != null && cameraCodec.SelectedCamera != null) + { + + AppServerController.RemoveAction(MessagePath + "/cameraUp"); + AppServerController.RemoveAction(MessagePath + "/cameraDown"); + AppServerController.RemoveAction(MessagePath + "/cameraLeft"); + AppServerController.RemoveAction(MessagePath + "/cameraRight"); + AppServerController.RemoveAction(MessagePath + "/cameraZoomIn"); + AppServerController.RemoveAction(MessagePath + "/cameraZoomOut"); + AppServerController.RemoveAction(MessagePath + "/cameraHome"); + + var camera = cameraCodec.SelectedCamera as IHasCameraPtzControl; + if (camera != null) + { + AppServerController.AddAction(MessagePath + "/cameraUp", new PressAndHoldAction(new Action(b => { if (b)camera.TiltUp(); else camera.TiltStop(); }))); + AppServerController.AddAction(MessagePath + "/cameraDown", new PressAndHoldAction(new Action(b => { if (b)camera.TiltDown(); else camera.TiltStop(); }))); + AppServerController.AddAction(MessagePath + "/cameraLeft", new PressAndHoldAction(new Action(b => { if (b)camera.PanLeft(); else camera.PanStop(); }))); + AppServerController.AddAction(MessagePath + "/cameraRight", new PressAndHoldAction(new Action(b => { if (b)camera.PanRight(); else camera.PanStop(); }))); + AppServerController.AddAction(MessagePath + "/cameraZoomIn", new PressAndHoldAction(new Action(b => { if (b)camera.ZoomIn(); else camera.ZoomStop(); }))); + AppServerController.AddAction(MessagePath + "/cameraZoomOut", new PressAndHoldAction(new Action(b => { if (b)camera.ZoomOut(); else camera.ZoomStop(); }))); + AppServerController.AddAction(MessagePath + "/cameraHome", new Action(camera.PositionHome)); + + var focusCamera = cameraCodec as IHasCameraFocusControl; + + AppServerController.RemoveAction(MessagePath + "/cameraAutoFocus"); + AppServerController.RemoveAction(MessagePath + "/cameraFocusNear"); + AppServerController.RemoveAction(MessagePath + "/cameraFocusFar"); + + if (focusCamera != null) + { + AppServerController.AddAction(MessagePath + "/cameraAutoFocus", new Action(focusCamera.TriggerAutoFocus)); + AppServerController.AddAction(MessagePath + "/cameraFocusNear", new PressAndHoldAction(new Action(b => { if (b)focusCamera.FocusNear(); else focusCamera.FocusStop(); }))); + AppServerController.AddAction(MessagePath + "/cameraFocusFar", new PressAndHoldAction(new Action(b => { if (b)focusCamera.FocusFar(); else focusCamera.FocusStop(); }))); + } + } + } + } + + string GetCameraMode() + { + string m = ""; + + var speakerTrackCodec = Codec as IHasCameraAutoMode; + if (speakerTrackCodec != null) + { + if (speakerTrackCodec.CameraAutoModeIsOnFeedback.BoolValue) m = eCameraControlMode.Auto.ToString(); + else m = eCameraControlMode.Manual.ToString(); + } + + var cameraOffCodec = Codec as IHasCameraOff; + if (cameraOffCodec != null) + { + if (cameraOffCodec.CameraIsOffFeedback.BoolValue) + m = eCameraControlMode.Off.ToString(); + } + + return m; + } + void GetCallHistory() { var codec = (Codec as IHasCallHistory); @@ -344,6 +482,22 @@ namespace PepperDash.Essentials.AppServer.Messengers return; } + object cameraInfo = null; + + var camerasCodec = Codec as IHasCodecCameras; + if (camerasCodec != null) + { + cameraInfo = new + { + cameraManualSupported = true, // For now, we assume manual mode is supported and selectively hide controls based on camera selection + cameraAutoSupported = Codec is IHasCameraAutoMode, + cameraOffSupported = Codec is IHasCameraOff, + cameraMode = GetCameraMode(), + cameraList = camerasCodec.Cameras, + selectedCamera = GetSelectedCamera(camerasCodec) + }; + } + var info = Codec.CodecInfo; PostStatusMessage(new { @@ -366,8 +520,77 @@ namespace PepperDash.Essentials.AppServer.Messengers hasDirectory = Codec is IHasDirectory, hasDirectorySearch = true, hasRecents = Codec is IHasCallHistory, - hasCameras = Codec is IHasCodecCameras + hasCameras = Codec is IHasCameras, + cameras = cameraInfo, + presets = GetCurrentPresets() }); } + + /// + /// + /// + void PostCameraMode() + { + PostStatusMessage(new + { + cameras = new + { + cameraMode = GetCameraMode() + } + }); + } + + void PostSelectedCamera() + { + var camerasCodec = Codec as IHasCodecCameras; + + PostStatusMessage(new + { + cameras = new + { + selectedCamera = GetSelectedCamera(camerasCodec) + }, + presets = GetCurrentPresets() + }); + } + + void PostCameraPresets() + { + + PostStatusMessage(new + { + presets = GetCurrentPresets() + }); + } + + object GetSelectedCamera(IHasCodecCameras camerasCodec) + { + return new + { + key = camerasCodec.SelectedCameraFeedback.StringValue, + isFarEnd = camerasCodec.ControllingFarEndCameraFeedback.BoolValue, + capabilites = new + { + canPan = camerasCodec.SelectedCamera.CanPan, + canTilt = camerasCodec.SelectedCamera.CanTilt, + canZoom = camerasCodec.SelectedCamera.CanZoom, + canFocus = camerasCodec.SelectedCamera.CanFocus + } + }; + } + + List GetCurrentPresets() + { + var presetsCodec = Codec as IHasCodecRoomPresets; + + List currentPresets = null; + + if (presetsCodec != null && Codec is IHasFarEndCameraControl && (Codec as IHasFarEndCameraControl).ControllingFarEndCameraFeedback.BoolValue) + currentPresets = presetsCodec.FarEndRoomPresets; + else + currentPresets = presetsCodec.NearEndPresets; + + return currentPresets; + } } } \ No newline at end of file diff --git a/PepperDashEssentials/AppServer/MobileControlSystemController.cs b/PepperDashEssentials/AppServer/MobileControlSystemController.cs index 08afb464..cc18ba55 100644 --- a/PepperDashEssentials/AppServer/MobileControlSystemController.cs +++ b/PepperDashEssentials/AppServer/MobileControlSystemController.cs @@ -21,7 +21,7 @@ using PepperDash.Essentials.AppServer.Messengers; namespace PepperDash.Essentials { - public class MobileControlSystemController : Device + public class MobileControlSystemController : EssentialsDevice { WebSocketClient WSClient; @@ -290,6 +290,10 @@ namespace PepperDash.Essentials SystemUuid); } } + else + { + Debug.Console(0, "Authorization failed, code {0}: {1}", r.Code, r.ContentString); + } } else Debug.Console(0, this, "Error {0} in authorizing system", e); @@ -861,4 +865,20 @@ namespace PepperDash.Essentials CrestronConsole.ConsoleCommandResponse("Usage: mobilehttprequest:N get/post url\r"); } } + + public class MobileControlSystemControllerFactory : EssentialsDeviceFactory + { + public MobileControlSystemControllerFactory() + { + TypeNames = new List() { "appserver" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new MobileControlSystemController Device"); + var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); + return new MobileControlSystemController(dc.Key, dc.Name, props); + } + } + } \ No newline at end of file diff --git a/PepperDashEssentials/AppServer/RoomBridges/MobileControlBridgeBase.cs b/PepperDashEssentials/AppServer/RoomBridges/MobileControlBridgeBase.cs index d7258070..fa5cb93d 100644 --- a/PepperDashEssentials/AppServer/RoomBridges/MobileControlBridgeBase.cs +++ b/PepperDashEssentials/AppServer/RoomBridges/MobileControlBridgeBase.cs @@ -12,7 +12,7 @@ namespace PepperDash.Essentials /// /// /// - public abstract class MobileControlBridgeBase: Device + public abstract class MobileControlBridgeBase: EssentialsDevice { public MobileControlSystemController Parent { get; private set; } diff --git a/PepperDashEssentials/AppServer/RoomBridges/MobileControlEssentialsHuddleSpaceRoomBridge.cs b/PepperDashEssentials/AppServer/RoomBridges/MobileControlEssentialsHuddleSpaceRoomBridge.cs index fd36389a..8a67ba14 100644 --- a/PepperDashEssentials/AppServer/RoomBridges/MobileControlEssentialsHuddleSpaceRoomBridge.cs +++ b/PepperDashEssentials/AppServer/RoomBridges/MobileControlEssentialsHuddleSpaceRoomBridge.cs @@ -25,6 +25,8 @@ namespace PepperDash.Essentials public AudioCodecBaseMessenger ACMessenger { get; private set; } + public Dictionary DeviceMessengers { get; private set; } + /// /// @@ -67,7 +69,15 @@ namespace PepperDash.Essentials var routeRoom = Room as IRunRouteAction; if(routeRoom != null) Parent.AddAction(string.Format(@"/room/{0}/source", Room.Key), new Action(c => - routeRoom.RunRouteAction(c.SourceListItem))); + { + if(string.IsNullOrEmpty(c.SourceListKey)) + routeRoom.RunRouteAction(c.SourceListItem, Room.SourceListKey); + else + { + routeRoom.RunRouteAction(c.SourceListItem, c.SourceListKey); + } + })); + var defaultRoom = Room as IRunDefaultPresentRoute; if(defaultRoom != null) @@ -115,6 +125,8 @@ namespace PepperDash.Essentials ACMessenger.RegisterWithAppServer(Parent); } + SetupDeviceMessengers(); + var defCallRm = Room as IRunDefaultCallRoute; if (defCallRm != null) { @@ -134,6 +146,36 @@ namespace PepperDash.Essentials Room.ShutdownPromptTimer.WasCancelled += ShutdownPromptTimer_WasCancelled; } + /// + /// Set up the messengers for each device type + /// + void SetupDeviceMessengers() + { + DeviceMessengers = new Dictionary(); + + foreach (var device in DeviceManager.AllDevices) + { + Debug.Console(2, this, "Attempting to set up device messenger for device: {0}", device.Key); + + if (device is Essentials.Devices.Common.Cameras.CameraBase) + { + var camDevice = device as Essentials.Devices.Common.Cameras.CameraBase; + Debug.Console(2, this, "Adding CameraBaseMessenger for device: {0}", device.Key); + var cameraMessenger = new CameraBaseMessenger(device.Key + "-" + Parent.Key, camDevice, "/device/" + device.Key); + DeviceMessengers.Add(device.Key, cameraMessenger); + cameraMessenger.RegisterWithAppServer(Parent); + } + if (device is Essentials.Devices.Common.SoftCodec.BlueJeansPc) + { + var softCodecDevice = device as Essentials.Devices.Common.SoftCodec.BlueJeansPc; + Debug.Console(2, this, "Adding IRunRouteActionMessnger for device: {0}", device.Key); + var routeMessenger = new IRunRouteActionMessenger(device.Key + "-" + Parent.Key, softCodecDevice, "/device/" + device.Key); + DeviceMessengers.Add(device.Key, routeMessenger); + routeMessenger.RegisterWithAppServer(Parent); + } + } + } + /// /// /// @@ -430,6 +472,7 @@ namespace PepperDash.Essentials public class SourceSelectMessageContent { public string SourceListItem { get; set; } + public string SourceListKey { get; set; } } /// diff --git a/PepperDashEssentials/AppServer/RoomBridges/MobileControlDdvc01RoomBridge.cs b/PepperDashEssentials/AppServer/RoomBridges/MobileControlSIMPLRoomBridge.cs similarity index 58% rename from PepperDashEssentials/AppServer/RoomBridges/MobileControlDdvc01RoomBridge.cs rename to PepperDashEssentials/AppServer/RoomBridges/MobileControlSIMPLRoomBridge.cs index eefd8fbc..25eebf42 100644 --- a/PepperDashEssentials/AppServer/RoomBridges/MobileControlDdvc01RoomBridge.cs +++ b/PepperDashEssentials/AppServer/RoomBridges/MobileControlSIMPLRoomBridge.cs @@ -10,6 +10,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PepperDash.Core; +using PepperDash.Essentials.AppServer; using PepperDash.Essentials.AppServer.Messengers; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; @@ -18,204 +19,8 @@ using PepperDash.Essentials.Room.Config; namespace PepperDash.Essentials.Room.MobileControl { - public class MobileControlDdvc01RoomBridge : MobileControlBridgeBase, IDelayedConfiguration + public class MobileControlSIMPLRoomBridge : MobileControlBridgeBase, IDelayedConfiguration { - public class BoolJoin - { - /// - /// 301 - /// - public const uint RoomIsOn = 301; - - /// - /// 12 - /// - public const uint PrivacyMute = 12; - - /// - /// 41 - /// - public const uint PromptForCode = 41; - /// - /// 42 - /// - public const uint ClientJoined = 42; - /// - /// 51 - /// - public const uint ActivityShare = 51; - /// - /// 52 - /// - public const uint ActivityPhoneCall = 52; - /// - /// 53 - /// - public const uint ActivityVideoCall = 53; - - /// - /// 1 - /// - public const uint MasterVolumeIsMuted = 1; - /// - /// 1 - /// - public const uint MasterVolumeMuteToggle = 1; - /// - /// 1 - /// - public const uint VolumeMutesJoinStart = 1; - /// - /// 61 - /// - public const uint ShutdownCancel = 61; - /// - /// 62 - /// - public const uint ShutdownEnd = 62; - /// - /// 63 - /// - public const uint ShutdownStart = 63; - /// - /// 72 - /// - public const uint SourceHasChanged = 71; - - /// - /// 261 - The start of the range of speed dial visibles - /// - public const uint SpeedDialVisibleStartJoin = 261; - /// - /// 501 - /// - public const uint ConfigIsReady = 501; - /// - /// 502 - /// - public const uint HideVideoConfRecents = 502; - /// - /// 503 - /// - public const uint ShowCameraWhenNotInCall = 503; - /// - /// 504 - /// - public const uint UseSourceEnabled = 504; - /// - /// 601 - /// - public const uint SourceShareDisableJoinStart = 601; - /// - /// 621 - /// - public const uint SourceIsEnabledJoinStart = 621; - - } - - public class UshortJoin - { - /// - /// 1 - /// - public const uint MasterVolumeLevel = 1; - /// - /// 1 - /// - public const uint VolumeSlidersJoinStart = 1; - /// - /// 61 - /// - public const uint ShutdownPromptDuration = 61; - /// - /// 101 - /// - public const uint NumberOfAuxFaders = 101; - } - - public class StringJoin - { - /// - /// 1 - /// - public const uint VolumeSliderNamesJoinStart = 1; - /// - /// 71 - /// - public const uint SelectedSourceKey = 71; - - /// - /// 241 - /// - public const uint SpeedDialNameStartJoin = 241; - - /// - /// 251 - /// - public const uint SpeedDialNumberStartJoin = 251; - - /// - /// 501 - /// - public const uint ConfigRoomName = 501; - /// - /// 502 - /// - public const uint ConfigHelpMessage = 502; - /// - /// 503 - /// - public const uint ConfigHelpNumber = 503; - /// - /// 504 - /// - public const uint ConfigRoomPhoneNumber = 504; - /// - /// 505 - /// - public const uint ConfigRoomURI = 505; - /// - /// 401 - /// - public const uint UserCodeToSystem = 401; - /// - /// 402 - /// - public const uint ServerUrl = 402; - /// - /// 512 - /// - public const uint RoomSpeedDialNamesJoinStart = 512; - /// - /// 516 - /// - public const uint RoomSpeedDialNumberssJoinStart = 516; - /// - /// 601 - /// - public const uint SourceNameJoinStart = 601; - /// - /// 621 - /// - public const uint SourceIconJoinStart = 621; - /// - /// 641 - /// - public const uint SourceKeyJoinStart = 641; - /// - /// 661 - /// - public const uint SourceTypeJoinStart = 661; - /// - /// 761 - /// - public const uint CameraNearNameStart = 761; - /// - /// 770 - presence of this name on the input will cause the camera to be added - /// - public const uint CameraFarName = 770; - } - /// /// Fires when config is ready to go /// @@ -223,6 +28,8 @@ namespace PepperDash.Essentials.Room.MobileControl public ThreeSeriesTcpIpEthernetIntersystemCommunications EISC { get; private set; } + public MobileControlSIMPLRoomJoinMap JoinMap { get; private set; } + /// /// /// @@ -231,15 +38,15 @@ namespace PepperDash.Essentials.Room.MobileControl public override string RoomName { get { - var name = EISC.StringOutput[StringJoin.ConfigRoomName].StringValue; + var name = EISC.StringOutput[JoinMap.ConfigRoomName.JoinNumber].StringValue; return string.IsNullOrEmpty(name) ? "Not Loaded" : name; } } MobileControlDdvc01DeviceBridge SourceBridge; - Ddvc01AtcMessenger AtcMessenger; - Ddvc01VtcMessenger VtcMessenger; + SIMPLAtcMessenger AtcMessenger; + SIMPLVtcMessenger VtcMessenger; /// @@ -248,7 +55,7 @@ namespace PepperDash.Essentials.Room.MobileControl /// /// /// - public MobileControlDdvc01RoomBridge(string key, string name, uint ipId) + public MobileControlSIMPLRoomBridge(string key, string name, uint ipId) : base(key, name) { try @@ -258,8 +65,13 @@ namespace PepperDash.Essentials.Room.MobileControl if (reg != Crestron.SimplSharpPro.eDeviceRegistrationUnRegistrationResponse.Success) Debug.Console(0, this, "Cannot connect EISC at IPID {0}: \r{1}", ipId, reg); + JoinMap = new MobileControlSIMPLRoomJoinMap(1); + SourceBridge = new MobileControlDdvc01DeviceBridge(key + "-sourceBridge", "DDVC01 source bridge", EISC); DeviceManager.AddDevice(SourceBridge); + + + } catch (Exception) { @@ -279,24 +91,33 @@ namespace PepperDash.Essentials.Room.MobileControl SetupFeedbacks(); var atcKey = string.Format("atc-{0}-{1}", this.Key, Parent.Key); - AtcMessenger = new Ddvc01AtcMessenger(atcKey, EISC, "/device/audioCodec"); + AtcMessenger = new SIMPLAtcMessenger(atcKey, EISC, "/device/audioCodec"); AtcMessenger.RegisterWithAppServer(Parent); var vtcKey = string.Format("atc-{0}-{1}", this.Key, Parent.Key); - VtcMessenger = new Ddvc01VtcMessenger(vtcKey, EISC, "/device/videoCodec"); + VtcMessenger = new SIMPLVtcMessenger(vtcKey, EISC, "/device/videoCodec"); VtcMessenger.RegisterWithAppServer(Parent); EISC.SigChange += EISC_SigChange; EISC.OnlineStatusChange += (o, a) => { - Debug.Console(1, this, "DDVC EISC online={0}. Config is ready={1}", a.DeviceOnLine, EISC.BooleanOutput[BoolJoin.ConfigIsReady].BoolValue); - if (a.DeviceOnLine && EISC.BooleanOutput[BoolJoin.ConfigIsReady].BoolValue) + Debug.Console(1, this, "DDVC EISC online={0}. Config is ready={1}. Use Essentials Config={2}", + a.DeviceOnLine, EISC.BooleanOutput[JoinMap.ConfigIsReady.JoinNumber].BoolValue, EISC.BooleanOutput[JoinMap.ConfigIsLocal.JoinNumber].BoolValue); + + if (a.DeviceOnLine && EISC.BooleanOutput[JoinMap.ConfigIsReady.JoinNumber].BoolValue) LoadConfigValues(); + + if (a.DeviceOnLine && EISC.BooleanOutput[JoinMap.ConfigIsLocal.JoinNumber].BoolValue) + UseEssentialsConfig(); }; // load config if it's already there - if (EISC.IsOnline && EISC.BooleanOutput[BoolJoin.ConfigIsReady].BoolValue) // || EISC.BooleanInput[BoolJoin.ConfigIsReady].BoolValue) + if (EISC.IsOnline && EISC.BooleanOutput[JoinMap.ConfigIsReady.JoinNumber].BoolValue) // || EISC.BooleanInput[JoinMap.ConfigIsReady].BoolValue) LoadConfigValues(); + if (EISC.IsOnline && EISC.BooleanOutput[JoinMap.ConfigIsLocal.JoinNumber].BoolValue) + { + UseEssentialsConfig(); + } CrestronConsole.AddNewConsoleCommand(s => { @@ -323,41 +144,60 @@ namespace PepperDash.Essentials.Room.MobileControl return base.CustomActivate(); } + void UseEssentialsConfig() + { + ConfigIsLoaded = false; + + SetupDeviceMessengers(); + + Debug.Console(0, this, "******* ESSENTIALS CONFIG: \r{0}", JsonConvert.SerializeObject(ConfigReader.ConfigObject, Formatting.Indented)); + + var handler = ConfigurationIsReady; + if (handler != null) + { + handler(this, new EventArgs()); + } + + ConfigIsLoaded = true; + } /// /// Setup the actions to take place on various incoming API calls /// void SetupFunctions() { - Parent.AddAction(@"/room/room1/promptForCode", new Action(() => EISC.PulseBool(BoolJoin.PromptForCode))); - Parent.AddAction(@"/room/room1/clientJoined", new Action(() => EISC.PulseBool(BoolJoin.ClientJoined))); + Parent.AddAction(@"/room/room1/promptForCode", new Action(() => EISC.PulseBool(JoinMap.PromptForCode.JoinNumber))); + Parent.AddAction(@"/room/room1/clientJoined", new Action(() => EISC.PulseBool(JoinMap.ClientJoined.JoinNumber))); Parent.AddAction(@"/room/room1/status", new Action(SendFullStatus)); Parent.AddAction(@"/room/room1/source", new Action(c => { - EISC.SetString(StringJoin.SelectedSourceKey, c.SourceListItem); - EISC.PulseBool(BoolJoin.SourceHasChanged); + EISC.SetString(JoinMap.CurrentSourceKey.JoinNumber, c.SourceListItem); + EISC.PulseBool(JoinMap.SourceHasChanged.JoinNumber); })); Parent.AddAction(@"/room/room1/defaultsource", new Action(() => - EISC.PulseBool(BoolJoin.ActivityShare))); + EISC.PulseBool(JoinMap.ActivityShare.JoinNumber))); Parent.AddAction(@"/room/room1/activityPhone", new Action(() => - EISC.PulseBool(BoolJoin.ActivityPhoneCall))); + EISC.PulseBool(JoinMap.ActivityPhoneCall.JoinNumber))); Parent.AddAction(@"/room/room1/activityVideo", new Action(() => - EISC.PulseBool(BoolJoin.ActivityVideoCall))); + EISC.PulseBool(JoinMap.ActivityVideoCall.JoinNumber))); Parent.AddAction(@"/room/room1/volumes/master/level", new Action(u => - EISC.SetUshort(UshortJoin.MasterVolumeLevel, u))); + EISC.SetUshort(JoinMap.MasterVolume.JoinNumber, u))); Parent.AddAction(@"/room/room1/volumes/master/muteToggle", new Action(() => - EISC.PulseBool(BoolJoin.MasterVolumeIsMuted))); + EISC.PulseBool(JoinMap.MasterVolume.JoinNumber))); Parent.AddAction(@"/room/room1/volumes/master/privacyMuteToggle", new Action(() => - EISC.PulseBool(BoolJoin.PrivacyMute))); + EISC.PulseBool(JoinMap.PrivacyMute.JoinNumber))); // /xyzxyz/volumes/master/muteToggle ---> BoolInput[1] - for (uint i = 2; i <= 7; i++) + var volumeStart = JoinMap.VolumeJoinStart.JoinNumber; + var volumeEnd = JoinMap.VolumeJoinStart.JoinNumber + JoinMap.VolumeJoinStart.JoinSpan; + + for (uint i = volumeStart; i <= volumeEnd; i++) { var index = i; Parent.AddAction(string.Format(@"/room/room1/volumes/level-{0}/level", index), new Action(u => @@ -367,13 +207,16 @@ namespace PepperDash.Essentials.Room.MobileControl } Parent.AddAction(@"/room/room1/shutdownStart", new Action(() => - EISC.PulseBool(BoolJoin.ShutdownStart))); + EISC.PulseBool(JoinMap.ShutdownStart.JoinNumber))); Parent.AddAction(@"/room/room1/shutdownEnd", new Action(() => - EISC.PulseBool(BoolJoin.ShutdownEnd))); + EISC.PulseBool(JoinMap.ShutdownEnd.JoinNumber))); Parent.AddAction(@"/room/room1/shutdownCancel", new Action(() => - EISC.PulseBool(BoolJoin.ShutdownCancel))); + EISC.PulseBool(JoinMap.ShutdownCancel.JoinNumber))); } + + + /// /// /// @@ -398,21 +241,21 @@ namespace PepperDash.Essentials.Room.MobileControl void SetupFeedbacks() { // Power - EISC.SetBoolSigAction(BoolJoin.RoomIsOn, b => + EISC.SetBoolSigAction(JoinMap.RoomIsOn.JoinNumber, b => PostStatusMessage(new { isOn = b })); // Source change things - EISC.SetSigTrueAction(BoolJoin.SourceHasChanged, () => + EISC.SetSigTrueAction(JoinMap.SourceHasChanged.JoinNumber, () => PostStatusMessage(new { - selectedSourceKey = EISC.StringOutput[StringJoin.SelectedSourceKey].StringValue + selectedSourceKey = EISC.StringOutput[JoinMap.CurrentSourceKey.JoinNumber].StringValue })); // Volume things - EISC.SetUShortSigAction(UshortJoin.MasterVolumeLevel, u => + EISC.SetUShortSigAction(JoinMap.MasterVolume.JoinNumber, u => PostStatusMessage(new { volumes = new @@ -427,7 +270,7 @@ namespace PepperDash.Essentials.Room.MobileControl // map MasterVolumeIsMuted join -> status/volumes/master/muted // - EISC.SetBoolSigAction(BoolJoin.MasterVolumeIsMuted, b => + EISC.SetBoolSigAction(JoinMap.MasterVolume.JoinNumber, b => PostStatusMessage(new { volumes = new @@ -438,7 +281,7 @@ namespace PepperDash.Essentials.Room.MobileControl } } })); - EISC.SetBoolSigAction(BoolJoin.PrivacyMute, b => + EISC.SetBoolSigAction(JoinMap.PrivacyMute.JoinNumber, b => PostStatusMessage(new { volumes = new @@ -450,7 +293,10 @@ namespace PepperDash.Essentials.Room.MobileControl } })); - for (uint i = 2; i <= 7; i++) + var volumeStart = JoinMap.VolumeJoinStart.JoinNumber; + var volumeEnd = JoinMap.VolumeJoinStart.JoinNumber + JoinMap.VolumeJoinStart.JoinSpan; + + for (uint i = volumeStart; i <= volumeEnd; i++) { var index = i; // local scope for lambdas EISC.SetUShortSigAction(index, u => // start at join 2 @@ -481,7 +327,7 @@ namespace PepperDash.Essentials.Room.MobileControl }); } - EISC.SetUShortSigAction(UshortJoin.NumberOfAuxFaders, u => + EISC.SetUShortSigAction(JoinMap.NumberOfAuxFaders.JoinNumber, u => PostStatusMessage(new { volumes = new { numberOfAuxFaders = u, @@ -489,30 +335,30 @@ namespace PepperDash.Essentials.Room.MobileControl })); // shutdown things - EISC.SetSigTrueAction(BoolJoin.ShutdownCancel, new Action(() => + EISC.SetSigTrueAction(JoinMap.ShutdownCancel.JoinNumber, new Action(() => PostMessage("/room/shutdown/", new { state = "wasCancelled" }))); - EISC.SetSigTrueAction(BoolJoin.ShutdownEnd, new Action(() => + EISC.SetSigTrueAction(JoinMap.ShutdownEnd.JoinNumber, new Action(() => PostMessage("/room/shutdown/", new { state = "hasFinished" }))); - EISC.SetSigTrueAction(BoolJoin.ShutdownStart, new Action(() => + EISC.SetSigTrueAction(JoinMap.ShutdownStart.JoinNumber, new Action(() => PostMessage("/room/shutdown/", new { state = "hasStarted", - duration = EISC.UShortOutput[UshortJoin.ShutdownPromptDuration].UShortValue + duration = EISC.UShortOutput[JoinMap.ShutdownPromptDuration.JoinNumber].UShortValue }))); // Config things - EISC.SetSigTrueAction(BoolJoin.ConfigIsReady, LoadConfigValues); + EISC.SetSigTrueAction(JoinMap.ConfigIsReady.JoinNumber, LoadConfigValues); // Activity modes - EISC.SetSigTrueAction(BoolJoin.ActivityShare, () => UpdateActivity(1)); - EISC.SetSigTrueAction(BoolJoin.ActivityPhoneCall, () => UpdateActivity(2)); - EISC.SetSigTrueAction(BoolJoin.ActivityVideoCall, () => UpdateActivity(3)); + EISC.SetSigTrueAction(JoinMap.ActivityShare.JoinNumber, () => UpdateActivity(1)); + EISC.SetSigTrueAction(JoinMap.ActivityPhoneCall.JoinNumber, () => UpdateActivity(2)); + EISC.SetSigTrueAction(JoinMap.ActivityVideoCall.JoinNumber, () => UpdateActivity(3)); } @@ -556,7 +402,7 @@ namespace PepperDash.Essentials.Room.MobileControl Debug.Console(0, this, "Replacing Room[0] in config"); co.Rooms[0] = rm; } - rm.Name = EISC.StringOutput[StringJoin.ConfigRoomName].StringValue; + rm.Name = EISC.StringOutput[JoinMap.ConfigRoomName.JoinNumber].StringValue; rm.Key = "room1"; rm.Type = "ddvc01"; @@ -567,13 +413,13 @@ namespace PepperDash.Essentials.Room.MobileControl rmProps = JsonConvert.DeserializeObject(rm.Properties.ToString()); rmProps.Help = new EssentialsHelpPropertiesConfig(); - rmProps.Help.CallButtonText = EISC.StringOutput[StringJoin.ConfigHelpNumber].StringValue; - rmProps.Help.Message = EISC.StringOutput[StringJoin.ConfigHelpMessage].StringValue; + rmProps.Help.CallButtonText = EISC.StringOutput[JoinMap.ConfigHelpNumber.JoinNumber].StringValue; + rmProps.Help.Message = EISC.StringOutput[JoinMap.ConfigHelpMessage.JoinNumber].StringValue; rmProps.Environment = new EssentialsEnvironmentPropertiesConfig(); // enabled defaults to false - rmProps.RoomPhoneNumber = EISC.StringOutput[StringJoin.ConfigRoomPhoneNumber].StringValue; - rmProps.RoomURI = EISC.StringOutput[StringJoin.ConfigRoomURI].StringValue; + rmProps.RoomPhoneNumber = EISC.StringOutput[JoinMap.ConfigRoomPhoneNumber.JoinNumber].StringValue; + rmProps.RoomURI = EISC.StringOutput[JoinMap.ConfigRoomURI.JoinNumber].StringValue; rmProps.SpeedDials = new List(); // This MAY need a check @@ -581,7 +427,7 @@ namespace PepperDash.Essentials.Room.MobileControl rmProps.VideoCodecKey = "videoCodec"; // volume control names - var volCount = EISC.UShortOutput[UshortJoin.NumberOfAuxFaders].UShortValue; + var volCount = EISC.UShortOutput[JoinMap.NumberOfAuxFaders.JoinNumber].UShortValue; //// use Volumes object or? //rmProps.VolumeSliderNames = new List(); @@ -626,18 +472,18 @@ namespace PepperDash.Essentials.Room.MobileControl // add sources... for (uint i = 0; i <= 19; i++) { - var name = EISC.StringOutput[StringJoin.SourceNameJoinStart + i].StringValue; - if (EISC.BooleanOutput[BoolJoin.UseSourceEnabled].BoolValue - && !EISC.BooleanOutput[BoolJoin.SourceIsEnabledJoinStart + i].BoolValue) + var name = EISC.StringOutput[JoinMap.SourceNameJoinStart.JoinNumber + i].StringValue; + if (EISC.BooleanOutput[JoinMap.UseSourceEnabled.JoinNumber].BoolValue + && !EISC.BooleanOutput[JoinMap.SourceIsEnabledJoinStart.JoinNumber + i].BoolValue) { continue; } - else if(!EISC.BooleanOutput[BoolJoin.UseSourceEnabled].BoolValue && string.IsNullOrEmpty(name)) + else if(!EISC.BooleanOutput[JoinMap.UseSourceEnabled.JoinNumber].BoolValue && string.IsNullOrEmpty(name)) break; - var icon = EISC.StringOutput[StringJoin.SourceIconJoinStart + i].StringValue; - var key = EISC.StringOutput[StringJoin.SourceKeyJoinStart + i].StringValue; - var type = EISC.StringOutput[StringJoin.SourceTypeJoinStart + i].StringValue; - var disableShare = EISC.BooleanOutput[BoolJoin.SourceShareDisableJoinStart + i].BoolValue; + var icon = EISC.StringOutput[JoinMap.SourceIconJoinStart.JoinNumber + i].StringValue; + var key = EISC.StringOutput[JoinMap.SourceKeyJoinStart.JoinNumber + i].StringValue; + var type = EISC.StringOutput[JoinMap.SourceTypeJoinStart.JoinNumber + i].StringValue; + var disableShare = EISC.BooleanOutput[JoinMap.SourceShareDisableJoinStart.JoinNumber + i].BoolValue; Debug.Console(0, this, "Adding source {0} '{1}'", key, name); var newSLI = new SourceListItem{ @@ -679,14 +525,14 @@ namespace PepperDash.Essentials.Room.MobileControl var acFavs = new List(); for (uint i = 0; i < 4; i++) { - if (!EISC.GetBool(BoolJoin.SpeedDialVisibleStartJoin + i)) + if (!EISC.GetBool(JoinMap.SpeedDialVisibleStartJoin.JoinNumber + i)) { break; } acFavs.Add(new PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem() { - Name = EISC.GetString(StringJoin.SpeedDialNameStartJoin + i), - Number = EISC.GetString(StringJoin.SpeedDialNumberStartJoin + i), + Name = EISC.GetString(JoinMap.SpeedDialNameStartJoin.JoinNumber + i), + Number = EISC.GetString(JoinMap.SpeedDialNumberStartJoin.JoinNumber + i), Type = PepperDash.Essentials.Devices.Common.Codec.eCodecCallType.Audio }); } @@ -718,7 +564,7 @@ namespace PepperDash.Essentials.Room.MobileControl var camsProps = new List(); for (uint i = 0; i < 9; i++) { - var name = EISC.GetString(i + StringJoin.CameraNearNameStart); + var name = EISC.GetString(i + JoinMap.CameraNearNameStart.JoinNumber); if (!string.IsNullOrEmpty(name)) { camsProps.Add(new @@ -728,7 +574,7 @@ namespace PepperDash.Essentials.Room.MobileControl }); } } - var farName = EISC.GetString(StringJoin.CameraFarName); + var farName = EISC.GetString(JoinMap.CameraFarName.JoinNumber); if (!string.IsNullOrEmpty(farName)) { camsProps.Add(new @@ -755,6 +601,8 @@ namespace PepperDash.Essentials.Room.MobileControl co.Devices.Add(conf); } + SetupDeviceMessengers(); + Debug.Console(0, this, "******* CONFIG FROM DDVC: \r{0}", JsonConvert.SerializeObject(ConfigReader.ConfigObject, Formatting.Indented)); var handler = ConfigurationIsReady; @@ -766,6 +614,67 @@ namespace PepperDash.Essentials.Room.MobileControl ConfigIsLoaded = true; } + /// + /// Iterates device config and adds messengers as neede for each device type + /// + void SetupDeviceMessengers() + { + try + { + foreach (var device in ConfigReader.ConfigObject.Devices) + { + if (device.Group.Equals("simplmessenger")) + { + var props = JsonConvert.DeserializeObject(device.Properties.ToString()); + + var messengerKey = string.Format("device-{0}-{1}", this.Key, Parent.Key); + + if (DeviceManager.GetDeviceForKey(messengerKey) != null) + { + Debug.Console(2, this, "Messenger with key: {0} already exists. Skipping...", messengerKey); + continue; + } + + var dev = ConfigReader.ConfigObject.GetDeviceForKey(props.DeviceKey); + + if (dev == null) + { + Debug.Console(1, this, "Unable to find device config for key: '{0}'", props.DeviceKey); + continue; + } + + var type = device.Type.ToLower(); + MessengerBase messenger = null; + + if (type.Equals("simplcameramessenger")) + { + Debug.Console(2, this, "Adding SIMPLCameraMessenger for: '{0}'", props.DeviceKey); + messenger = new SIMPLCameraMessenger(messengerKey, EISC, "/device/" + props.DeviceKey, props.JoinStart); + } + else if (type.Equals("simplroutemessenger")) + { + Debug.Console(2, this, "Adding SIMPLRouteMessenger for: '{0}'", props.DeviceKey); + messenger = new SIMPLRouteMessenger(messengerKey, EISC, "/device/" + props.DeviceKey, props.JoinStart); + } + + if (messenger != null) + { + DeviceManager.AddDevice(messenger); + messenger.RegisterWithAppServer(Parent); + } + else + { + Debug.Console(2, this, "Unable to add messenger for device: '{0}' of type: '{1}'", props.DeviceKey, type); + } + } + } + } + catch (Exception e) + { + Debug.Console(2, this, "Error Setting up Device Managers: {0}", e); + } + } + /// /// /// @@ -773,7 +682,7 @@ namespace PepperDash.Essentials.Room.MobileControl { if (ConfigIsLoaded) { - var count = EISC.UShortOutput[UshortJoin.NumberOfAuxFaders].UShortValue; + var count = EISC.UShortOutput[JoinMap.NumberOfAuxFaders.JoinNumber].UShortValue; Debug.Console(1, this, "The Fader Count is : {0}", count); @@ -781,7 +690,11 @@ namespace PepperDash.Essentials.Room.MobileControl // Create auxFaders var auxFaderDict = new Dictionary(); - for (uint i = 2; i <= count; i++) + + var volumeStart = JoinMap.VolumeJoinStart.JoinNumber; + var volumeEnd = JoinMap.VolumeJoinStart.JoinNumber + JoinMap.VolumeJoinStart.JoinSpan; + + for (uint i = volumeStart; i <= count; i++) { auxFaderDict.Add("level-" + i, new Volume("level-" + i, @@ -795,22 +708,22 @@ namespace PepperDash.Essentials.Room.MobileControl var volumes = new Volumes(); volumes.Master = new Volume("master", - EISC.UShortOutput[UshortJoin.MasterVolumeLevel].UShortValue, - EISC.BooleanOutput[BoolJoin.MasterVolumeIsMuted].BoolValue, - EISC.StringOutput[1].StringValue, + EISC.UShortOutput[JoinMap.MasterVolume.JoinNumber].UShortValue, + EISC.BooleanOutput[JoinMap.MasterVolume.JoinNumber].BoolValue, + EISC.StringOutput[JoinMap.MasterVolume.JoinNumber].StringValue, true, "something.png"); volumes.Master.HasPrivacyMute = true; - volumes.Master.PrivacyMuted = EISC.BooleanOutput[BoolJoin.PrivacyMute].BoolValue; + volumes.Master.PrivacyMuted = EISC.BooleanOutput[JoinMap.PrivacyMute.JoinNumber].BoolValue; volumes.AuxFaders = auxFaderDict; - volumes.NumberOfAuxFaders = EISC.UShortInput[UshortJoin.NumberOfAuxFaders].UShortValue; + volumes.NumberOfAuxFaders = EISC.UShortInput[JoinMap.NumberOfAuxFaders.JoinNumber].UShortValue; PostStatusMessage(new { activityMode = GetActivityMode(), - isOn = EISC.BooleanOutput[BoolJoin.RoomIsOn].BoolValue, - selectedSourceKey = EISC.StringOutput[StringJoin.SelectedSourceKey].StringValue, + isOn = EISC.BooleanOutput[JoinMap.RoomIsOn.JoinNumber].BoolValue, + selectedSourceKey = EISC.StringOutput[JoinMap.CurrentSourceKey.JoinNumber].StringValue, volumes = volumes }); } @@ -829,9 +742,9 @@ namespace PepperDash.Essentials.Room.MobileControl /// int GetActivityMode() { - if (EISC.BooleanOutput[BoolJoin.ActivityPhoneCall].BoolValue) return 2; - else if (EISC.BooleanOutput[BoolJoin.ActivityShare].BoolValue) return 1; - else if (EISC.BooleanOutput[BoolJoin.ActivityVideoCall].BoolValue) return 3; + if (EISC.BooleanOutput[JoinMap.ActivityPhoneCall.JoinNumber].BoolValue) return 2; + else if (EISC.BooleanOutput[JoinMap.ActivityShare.JoinNumber].BoolValue) return 1; + else if (EISC.BooleanOutput[JoinMap.ActivityVideoCall.JoinNumber].BoolValue) return 3; return 0; } @@ -873,12 +786,15 @@ namespace PepperDash.Essentials.Room.MobileControl if (Debug.Level >= 1) Debug.Console(1, this, "DDVC EISC change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue); var uo = args.Sig.UserObject; - if (uo is Action) - (uo as Action)(args.Sig.BoolValue); - else if (uo is Action) - (uo as Action)(args.Sig.UShortValue); - else if (uo is Action) - (uo as Action)(args.Sig.StringValue); + if (uo != null) + { + if (uo is Action) + (uo as Action)(args.Sig.BoolValue); + else if (uo is Action) + (uo as Action)(args.Sig.UShortValue); + else if (uo is Action) + (uo as Action)(args.Sig.StringValue); + } } /// @@ -905,8 +821,39 @@ namespace PepperDash.Essentials.Room.MobileControl protected override void UserCodeChange() { Debug.Console(1, this, "Server user code changed: {0}", UserCode); - EISC.StringInput[StringJoin.UserCodeToSystem].StringValue = UserCode; - EISC.StringInput[StringJoin.ServerUrl].StringValue = Parent.Config.ClientAppUrl; + EISC.StringInput[JoinMap.UserCodeToSystem.JoinNumber].StringValue = UserCode; + EISC.StringInput[JoinMap.ServerUrl.JoinNumber].StringValue = Parent.Config.ClientAppUrl; } } + + public class MobileControlSIMPLRoomBridgeFactory : EssentialsDeviceFactory + { + public MobileControlSIMPLRoomBridgeFactory() + { + TypeNames = new List() { "mobilecontrolbridge-ddvc01", "mobilecontrolbridge-simpl" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new MobileControlSIMPLRoomBridge Device"); + + var comm = CommFactory.GetControlPropertiesConfig(dc); + + var bridge = new PepperDash.Essentials.Room.MobileControl.MobileControlSIMPLRoomBridge(dc.Key, dc.Name, comm.IpIdInt); + bridge.AddPreActivationAction(() => + { + var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as MobileControlSystemController; + if (parent == null) + { + Debug.Console(0, bridge, "ERROR: Cannot connect bridge. System controller not present"); + } + Debug.Console(0, bridge, "Linking to parent controller"); + bridge.AddParent(parent); + parent.AddBridge(bridge); + }); + + return bridge; + } + } + } \ No newline at end of file diff --git a/PepperDashEssentials/AppServer/SIMPLJoinMaps/MobileControlSIMPLRoomJoinMap.cs b/PepperDashEssentials/AppServer/SIMPLJoinMaps/MobileControlSIMPLRoomJoinMap.cs new file mode 100644 index 00000000..286fe28e --- /dev/null +++ b/PepperDashEssentials/AppServer/SIMPLJoinMaps/MobileControlSIMPLRoomJoinMap.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Essentials.Core; + + +namespace PepperDash.Essentials.AppServer +{ + public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced + { + [JoinName("MasterVolume")] + public JoinDataComplete MasterVolume = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata() {Label = "Master Volume Mute Toggle/FB/Level/Label", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.DigitalAnalogSerial }); + [JoinName("VolumeJoinStart")] + public JoinDataComplete VolumeJoinStart = new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 8 }, new JoinMetadata() {Label = "Volume Mute Toggle/FB/Level/Label", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.DigitalAnalogSerial }); + + [JoinName("PrivacyMute")] + public JoinDataComplete PrivacyMute = new JoinDataComplete(new JoinData() { JoinNumber = 12, JoinSpan = 1 }, new JoinMetadata() { Label = "Privacy Mute Toggle/FB", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("PromptForCode")] + public JoinDataComplete PromptForCode = new JoinDataComplete(new JoinData() { JoinNumber = 41, JoinSpan = 1 }, new JoinMetadata() {Label = "Prompt User for Code", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("ClientJoined")] + public JoinDataComplete ClientJoined = new JoinDataComplete(new JoinData() { JoinNumber = 42, JoinSpan = 1 }, new JoinMetadata() { Label = "Client Joined", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("ActivityShare")] + public JoinDataComplete ActivityShare = new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 }, new JoinMetadata() {Label = "Activity Share", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("ActivityPhoneCall")] + public JoinDataComplete ActivityPhoneCall = new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 }, new JoinMetadata() { Label = "Activity Phone Call", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("ActivityVideoCall")] + public JoinDataComplete ActivityVideoCall = new JoinDataComplete(new JoinData() { JoinNumber = 53, JoinSpan = 1 }, new JoinMetadata() { Label = "Activity Video Call", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("ShutdownPromptDuration")] + public JoinDataComplete ShutdownPromptDuration = new JoinDataComplete(new JoinData() { JoinNumber = 61, JoinSpan = 1 }, new JoinMetadata() { Label ="Shutdown Cancel", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("ShutdownCancel")] + public JoinDataComplete ShutdownCancel = new JoinDataComplete(new JoinData() { JoinNumber = 61, JoinSpan = 1 }, new JoinMetadata() { Label ="Shutdown Cancel", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("ShutdownEnd")] + public JoinDataComplete ShutdownEnd = new JoinDataComplete(new JoinData() { JoinNumber = 62, JoinSpan = 1 }, new JoinMetadata() { Label = "Shutdown End", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("ShutdownStart")] + public JoinDataComplete ShutdownStart = new JoinDataComplete(new JoinData() { JoinNumber = 63, JoinSpan = 1 }, new JoinMetadata() { Label = "Shutdown Start", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("SourceHasChanged")] + public JoinDataComplete SourceHasChanged = new JoinDataComplete(new JoinData() { JoinNumber = 71, JoinSpan = 1 }, new JoinMetadata() { Label = "Source Changed", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CurrentSourceKey")] + public JoinDataComplete CurrentSourceKey = new JoinDataComplete(new JoinData() { JoinNumber = 71, JoinSpan = 1 }, new JoinMetadata() { Label = "Key of selected source", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Serial }); + + + [JoinName("ConfigIsLocal")] + public JoinDataComplete ConfigIsLocal = new JoinDataComplete(new JoinData() { JoinNumber = 100, JoinSpan = 1 }, new JoinMetadata() { Label = "Config is local to Essentials", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("NumberOfAuxFaders")] + public JoinDataComplete NumberOfAuxFaders = new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 }, new JoinMetadata() { Label = "Number of Auxilliary Faders", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog }); + + [JoinName("SpeedDialNameStartJoin")] + public JoinDataComplete SpeedDialNameStartJoin = new JoinDataComplete(new JoinData() { JoinNumber = 241, JoinSpan = 10 }, new JoinMetadata() { Label = "Speed Dial names", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("SpeedDialNumberStartJoin")] + public JoinDataComplete SpeedDialNumberStartJoin = new JoinDataComplete(new JoinData() { JoinNumber = 251, JoinSpan = 10 }, new JoinMetadata() { Label = "Speed Dial numbers", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + + [JoinName("SpeedDialVisibleStartJoin")] + public JoinDataComplete SpeedDialVisibleStartJoin = new JoinDataComplete(new JoinData() { JoinNumber = 261, JoinSpan = 10 }, new JoinMetadata() { Label = "Speed Dial Visible", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("RoomIsOn")] + public JoinDataComplete RoomIsOn = new JoinDataComplete(new JoinData() { JoinNumber = 301, JoinSpan = 1 }, new JoinMetadata() { Label = "Room Is On", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("UserCodeToSystem")] + public JoinDataComplete UserCodeToSystem = new JoinDataComplete(new JoinData() { JoinNumber = 401, JoinSpan = 1 }, new JoinMetadata() { Label = "User Ccde", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); + [JoinName("ServerUrl")] + public JoinDataComplete ServerUrl = new JoinDataComplete(new JoinData() { JoinNumber = 402, JoinSpan = 1 }, new JoinMetadata() { Label ="Server URL", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); + + [JoinName("ConfigRoomName")] + public JoinDataComplete ConfigRoomName = new JoinDataComplete(new JoinData() { JoinNumber = 501, JoinSpan = 1 }, new JoinMetadata() {Label = "Room Nnme", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("ConfigHelpMessage")] + public JoinDataComplete ConfigHelpMessage = new JoinDataComplete(new JoinData() { JoinNumber = 502, JoinSpan = 1 }, new JoinMetadata() { Label = "Room help message", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("ConfigHelpNumber")] + public JoinDataComplete ConfigHelpNumber = new JoinDataComplete(new JoinData() { JoinNumber = 503, JoinSpan = 1 }, new JoinMetadata() { Label = "Room help number", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("ConfigRoomPhoneNumber")] + public JoinDataComplete ConfigRoomPhoneNumber = new JoinDataComplete(new JoinData() { JoinNumber = 504, JoinSpan = 1 }, new JoinMetadata() { Label = "Room phone number", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("ConfigRoomURI")] + public JoinDataComplete ConfigRoomURI = new JoinDataComplete(new JoinData() { JoinNumber = 505, JoinSpan = 1 }, new JoinMetadata() { Label = "Room URI", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + + [JoinName("ConfigIsReady")] + public JoinDataComplete ConfigIsReady = new JoinDataComplete(new JoinData() { JoinNumber = 501, JoinSpan = 1 }, new JoinMetadata() { Label = "Config info from SIMPL is ready", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("HideVideoConfRecents")] + public JoinDataComplete HideVideoConfRecents = new JoinDataComplete(new JoinData() { JoinNumber = 502, JoinSpan = 1 }, new JoinMetadata() { Label = "Hide Video Conference Recents", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("ShowCameraWhenNotInCall")] + public JoinDataComplete ShowCameraWhenNotInCall = new JoinDataComplete(new JoinData() { JoinNumber = 503, JoinSpan = 1 }, new JoinMetadata() { Label = "Show camera when not in call", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("UseSourceEnabled")] + public JoinDataComplete UseSourceEnabled = new JoinDataComplete(new JoinData() { JoinNumber = 504, JoinSpan = 1 }, new JoinMetadata() { Label = "Use Source Enabled Joins", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + + [JoinName("SourceShareDisableJoinStart")] + public JoinDataComplete SourceShareDisableJoinStart = new JoinDataComplete(new JoinData() { JoinNumber = 601, JoinSpan = 20 }, new JoinMetadata() { Label = "Source is not sharable", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("SourceIsEnabledJoinStart")] + public JoinDataComplete SourceIsEnabledJoinStart = new JoinDataComplete(new JoinData() { JoinNumber = 621, JoinSpan = 20 }, new JoinMetadata() { Label = "Source is enabled", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("SourceNameJoinStart")] + public JoinDataComplete SourceNameJoinStart = new JoinDataComplete(new JoinData() { JoinNumber = 601, JoinSpan = 20 }, new JoinMetadata() { Label = "Source Names", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("SourceIconJoinStart")] + public JoinDataComplete SourceIconJoinStart = new JoinDataComplete(new JoinData() { JoinNumber = 621, JoinSpan = 20 }, new JoinMetadata() { Label = "Source Icons", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("SourceKeyJoinStart")] + public JoinDataComplete SourceKeyJoinStart = new JoinDataComplete(new JoinData() { JoinNumber = 641, JoinSpan = 20 }, new JoinMetadata() { Label = "Source Keys", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("SourceTypeJoinStart")] + public JoinDataComplete SourceTypeJoinStart = new JoinDataComplete(new JoinData() { JoinNumber = 661, JoinSpan = 20 }, new JoinMetadata() { Label = "Source Types", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + + [JoinName("CameraNearNameStart")] + public JoinDataComplete CameraNearNameStart = new JoinDataComplete(new JoinData() { JoinNumber = 761, JoinSpan = 10 }, new JoinMetadata() { Label = "Near End Camera Names", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("CameraFarName")] + public JoinDataComplete CameraFarName = new JoinDataComplete(new JoinData() { JoinNumber = 770, JoinSpan = 1 }, new JoinMetadata() { Label = "Far End Camera Name", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + + public MobileControlSIMPLRoomJoinMap(uint joinStart) + :base(joinStart) + { + + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/AppServer/SIMPLJoinMaps/SIMPLAtcJoinMap.cs b/PepperDashEssentials/AppServer/SIMPLJoinMaps/SIMPLAtcJoinMap.cs new file mode 100644 index 00000000..20abb31e --- /dev/null +++ b/PepperDashEssentials/AppServer/SIMPLJoinMaps/SIMPLAtcJoinMap.cs @@ -0,0 +1,69 @@ +using System.Linq; +using Crestron.SimplSharp.Reflection; + +using PepperDash.Essentials.Core; + + +namespace PepperDash.Essentials.AppServer +{ + public class SIMPLAtcJoinMap : JoinMapBaseAdvanced + { + [JoinName("EndCall")] + public JoinDataComplete EndCall = new JoinDataComplete(new JoinData() { JoinNumber = 21, JoinSpan = 1 }, new JoinMetadata() { Label = "Hang Up", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("IncomingAnswer")] + public JoinDataComplete IncomingAnswer = new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 }, new JoinMetadata() { Label = "Answer Incoming Call", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("IncomingReject")] + public JoinDataComplete IncomingReject = new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 }, new JoinMetadata() { Label = "Reject Incoming Call", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("SpeedDialStart")] + public JoinDataComplete SpeedDialStart = new JoinDataComplete(new JoinData() { JoinNumber = 41, JoinSpan = 4 }, new JoinMetadata() { Label = "Speed Dial", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CurrentDialString")] + public JoinDataComplete CurrentDialString = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Dial String", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("CurrentCallNumber")] + public JoinDataComplete CurrentCallNumber = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Call Number", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("CurrentCallName")] + public JoinDataComplete CurrentCallName = new JoinDataComplete(new JoinData() { JoinNumber = 12, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Call Name", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("HookState")] + public JoinDataComplete HookState = new JoinDataComplete(new JoinData() { JoinNumber = 21, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Hook State", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("CallDirection")] + public JoinDataComplete CallDirection = new JoinDataComplete(new JoinData() { JoinNumber = 22, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Call Direction", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("IncomingCallName")] + public JoinDataComplete IncomingCallName = new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 }, new JoinMetadata() { Label = "Incoming Call Name", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("IncomingCallNumber")] + public JoinDataComplete IncomingCallNumber = new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 }, new JoinMetadata() { Label = "Incoming Call Number", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + + [JoinName("0")] + public JoinDataComplete Dtmf0 = new JoinDataComplete(new JoinData() { JoinNumber = 10, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 0", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("1")] + public JoinDataComplete Dtmf1 = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 1", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("2")] + public JoinDataComplete Dtmf2 = new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 2", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("3")] + public JoinDataComplete Dtmf3 = new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 3", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("4")] + public JoinDataComplete Dtmf4 = new JoinDataComplete(new JoinData() { JoinNumber = 4, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 4", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("5")] + public JoinDataComplete Dtmf5 = new JoinDataComplete(new JoinData() { JoinNumber = 5, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 5", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("6")] + public JoinDataComplete Dtmf6 = new JoinDataComplete(new JoinData() { JoinNumber = 6, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 6", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("7")] + public JoinDataComplete Dtmf7 = new JoinDataComplete(new JoinData() { JoinNumber = 7, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 7", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("8")] + public JoinDataComplete Dtmf8 = new JoinDataComplete(new JoinData() { JoinNumber = 8, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 8", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("9")] + public JoinDataComplete Dtmf9 = new JoinDataComplete(new JoinData() { JoinNumber = 9, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 9", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("*")] + public JoinDataComplete DtmfStar = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF *", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("#")] + public JoinDataComplete DtmfPound = new JoinDataComplete(new JoinData() { JoinNumber = 12, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF #", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + + /// + /// Constructor that passes the joinStart to the base class + /// + /// + public SIMPLAtcJoinMap(uint joinStart) + : base(joinStart) + { + + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/AppServer/SIMPLJoinMaps/SIMPLVtcJoinMap.cs b/PepperDashEssentials/AppServer/SIMPLJoinMaps/SIMPLVtcJoinMap.cs new file mode 100644 index 00000000..1ce3c5aa --- /dev/null +++ b/PepperDashEssentials/AppServer/SIMPLJoinMaps/SIMPLVtcJoinMap.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Essentials.Core; + + +namespace PepperDash.Essentials.AppServer +{ + public class SIMPLVtcJoinMap : JoinMapBaseAdvanced + { + [JoinName("EndCall")] + public JoinDataComplete EndCall = new JoinDataComplete(new JoinData() { JoinNumber = 24, JoinSpan = 1 }, new JoinMetadata() { Label = "Hang Up", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("IncomingCall")] + public JoinDataComplete IncomingCall = new JoinDataComplete(new JoinData() { JoinNumber = 50, JoinSpan = 1 }, new JoinMetadata() { Label = "Incoming Call", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("IncomingAnswer")] + public JoinDataComplete IncomingAnswer = new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 }, new JoinMetadata() { Label = "Answer Incoming Call", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("IncomingReject")] + public JoinDataComplete IncomingReject = new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 }, new JoinMetadata() { Label = "Reject Incoming Call", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("SpeedDialStart")] + public JoinDataComplete SpeedDialStart = new JoinDataComplete(new JoinData() { JoinNumber = 41, JoinSpan = 4 }, new JoinMetadata() { Label = "Speed Dial", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("DirectorySearchBusy")] + public JoinDataComplete DirectorySearchBusy = new JoinDataComplete(new JoinData() { JoinNumber = 100, JoinSpan = 1 }, new JoinMetadata() { Label = "Directory Search Busy FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("DirectoryLineSelected")] + public JoinDataComplete DirectoryLineSelected = new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 }, new JoinMetadata() { Label = "Directory Line Selected FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("DirectoryEntryIsContact")] + public JoinDataComplete DirectoryEntryIsContact = new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 }, new JoinMetadata() { Label = "Directory Selected Entry Is Contact FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("DirectoryIsRoot")] + public JoinDataComplete DirectoryIsRoot = new JoinDataComplete(new JoinData() { JoinNumber = 102, JoinSpan = 1 }, new JoinMetadata() { Label = "Directory is on Root FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("DDirectoryHasChanged")] + public JoinDataComplete DDirectoryHasChanged = new JoinDataComplete(new JoinData() { JoinNumber = 103, JoinSpan = 1 }, new JoinMetadata() {Label = "Directory has changed FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("DirectoryRoot")] + public JoinDataComplete DirectoryRoot = new JoinDataComplete(new JoinData() { JoinNumber = 104, JoinSpan = 1 }, new JoinMetadata() { Label = "Go to Directory Root", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("DirectoryFolderBack")] + public JoinDataComplete DirectoryFolderBack = new JoinDataComplete(new JoinData() { JoinNumber = 105, JoinSpan = 1 }, new JoinMetadata() { Label = "Go back one directory level", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("DirectoryDialSelectedLine")] + public JoinDataComplete DirectoryDialSelectedLine = new JoinDataComplete(new JoinData() { JoinNumber = 106, JoinSpan = 1 }, new JoinMetadata() { Label = "Dial selected directory line", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("CameraTiltUp")] + public JoinDataComplete CameraTiltUp = new JoinDataComplete(new JoinData() { JoinNumber = 111, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Tilt Up", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CameraTiltDown")] + public JoinDataComplete CameraTiltDown = new JoinDataComplete(new JoinData() { JoinNumber = 112, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Tilt Down", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CameraPanLeft")] + public JoinDataComplete CameraPanLeft = new JoinDataComplete(new JoinData() { JoinNumber = 113, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Pan Left", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CameraPanRight")] + public JoinDataComplete CameraPanRight = new JoinDataComplete(new JoinData() { JoinNumber = 114, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Pan Right", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CameraZoomIn")] + public JoinDataComplete CameraZoomIn = new JoinDataComplete(new JoinData() { JoinNumber = 115, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Zoom In", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CameraZoomOut")] + public JoinDataComplete CameraZoomOut = new JoinDataComplete(new JoinData() { JoinNumber = 116, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Zoom Out", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("CameraPresetStart")] + public JoinDataComplete CameraPresetStart = new JoinDataComplete(new JoinData() { JoinNumber = 121, JoinSpan = 5 }, new JoinMetadata() { Label = "Camera Presets", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("CameraModeAuto")] + public JoinDataComplete CameraModeAuto = new JoinDataComplete(new JoinData() { JoinNumber = 131, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Auto", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CameraModeManual")] + public JoinDataComplete CameraModeManual = new JoinDataComplete(new JoinData() { JoinNumber = 132, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Manual", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CameraModeOff")] + public JoinDataComplete CameraModeOff = new JoinDataComplete(new JoinData() { JoinNumber = 133, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Off", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("CameraSelfView")] + public JoinDataComplete CameraSelfView = new JoinDataComplete(new JoinData() { JoinNumber = 141, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Self View Toggle/FB", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CameraLayout")] + public JoinDataComplete CameraLayout = new JoinDataComplete(new JoinData() { JoinNumber = 142, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Layout Toggle", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("CameraSupportsAutoMode")] + public JoinDataComplete CameraSupportsAutoMode = new JoinDataComplete(new JoinData() { JoinNumber = 143, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Supports Auto Mode FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CameraSupportsOffMode")] + public JoinDataComplete CameraSupportsOffMode = new JoinDataComplete(new JoinData() { JoinNumber = 144, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Supports Off Mode FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("CameraNumberSelect")] + public JoinDataComplete CameraNumberSelect = new JoinDataComplete(new JoinData() { JoinNumber = 60, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Number Select/FB", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("DirectorySelectRow")] + public JoinDataComplete DirectorySelectRow = new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 }, new JoinMetadata() { Label = "Directory Select Row", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("DirectoryRowCount")] + public JoinDataComplete DirectoryRowCount = new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 }, new JoinMetadata() { Label = "Directory Row Count FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("CurrentDialString")] + public JoinDataComplete CurrentDialString = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Dial String", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("CurrentCallName")] + public JoinDataComplete CurrentCallName = new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Call Name", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("CurrentCallNumber")] + public JoinDataComplete CurrentCallNumber = new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Call Number", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("HookState")] + public JoinDataComplete HookState = new JoinDataComplete(new JoinData() { JoinNumber = 31, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Hook State", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("CallDirection")] + public JoinDataComplete CallDirection = new JoinDataComplete(new JoinData() { JoinNumber = 22, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Call Direction", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + + [JoinName("IncomingCallName")] + public JoinDataComplete IncomingCallName = new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 }, new JoinMetadata() { Label = "Incoming Call Name", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("IncomingCallNumber")] + public JoinDataComplete IncomingCallNumber = new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 }, new JoinMetadata() { Label = "Incoming Call Number", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + + [JoinName("DirectorySearchString")] + public JoinDataComplete DirectorySearchString = new JoinDataComplete(new JoinData() { JoinNumber = 100, JoinSpan = 1 }, new JoinMetadata() { Label = "Directory Search String", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); + [JoinName("DirectoryEntriesStart")] + public JoinDataComplete DirectoryEntriesStart = new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 255 }, new JoinMetadata() { Label = "Directory Entries", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + + [JoinName("DirectoryEntrySelectedName")] + public JoinDataComplete DirectoryEntrySelectedName = new JoinDataComplete(new JoinData() { JoinNumber = 356, JoinSpan = 1 }, new JoinMetadata() { Label = "Selected Directory Entry Name", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("DirectoryEntrySelectedNumber")] + public JoinDataComplete DirectoryEntrySelectedNumber = new JoinDataComplete(new JoinData() { JoinNumber = 357, JoinSpan = 1 }, new JoinMetadata() { Label = "Selected Directory Entry Number", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("DirectorySelectedFolderName")] + public JoinDataComplete DirectorySelectedFolderName = new JoinDataComplete(new JoinData() { JoinNumber = 358, JoinSpan = 1 }, new JoinMetadata() { Label = "Selected Directory Folder Name", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + + [JoinName("1")] + public JoinDataComplete Dtmf1 = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 1", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("2")] + public JoinDataComplete Dtmf2 = new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 2", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("3")] + public JoinDataComplete Dtmf3 = new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 3", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("4")] + public JoinDataComplete Dtmf4 = new JoinDataComplete(new JoinData() { JoinNumber = 4, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 4", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("5")] + public JoinDataComplete Dtmf5 = new JoinDataComplete(new JoinData() { JoinNumber = 5, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 5", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("6")] + public JoinDataComplete Dtmf6 = new JoinDataComplete(new JoinData() { JoinNumber = 6, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 6", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("7")] + public JoinDataComplete Dtmf7 = new JoinDataComplete(new JoinData() { JoinNumber = 7, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 7", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("8")] + public JoinDataComplete Dtmf8 = new JoinDataComplete(new JoinData() { JoinNumber = 8, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 8", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("9")] + public JoinDataComplete Dtmf9 = new JoinDataComplete(new JoinData() { JoinNumber = 9, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 9", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("0")] + public JoinDataComplete Dtmf0 = new JoinDataComplete(new JoinData() { JoinNumber = 10, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 0", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("*")] + public JoinDataComplete DtmfStar = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF *", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("#")] + public JoinDataComplete DtmfPound = new JoinDataComplete(new JoinData() { JoinNumber = 12, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF #", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + + public SIMPLVtcJoinMap(uint joinStart) + :base(joinStart) + { + } + + } +} \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/AirMediaControllerBridge.cs b/PepperDashEssentials/Bridges/AirMediaControllerBridge.cs index 1f1b64dc..869c5614 100644 --- a/PepperDashEssentials/Bridges/AirMediaControllerBridge.cs +++ b/PepperDashEssentials/Bridges/AirMediaControllerBridge.cs @@ -11,7 +11,7 @@ using PepperDash.Essentials.DM.AirMedia; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class AirMediaControllerApiExtensions { @@ -19,7 +19,7 @@ namespace PepperDash.Essentials.Bridges { AirMediaControllerJoinMap joinMap = new AirMediaControllerJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/AppleTvBridge.cs b/PepperDashEssentials/Bridges/AppleTvBridge.cs index 6169a712..3c2bb0af 100644 --- a/PepperDashEssentials/Bridges/AppleTvBridge.cs +++ b/PepperDashEssentials/Bridges/AppleTvBridge.cs @@ -11,7 +11,7 @@ using PepperDash.Essentials.Devices.Common; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class AppleTvApiExtensions { @@ -19,7 +19,7 @@ namespace PepperDash.Essentials.Bridges { AppleTvJoinMap joinMap = new AppleTvJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if(!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/BridgeBase.cs b/PepperDashEssentials/Bridges/BridgeBase.cs deleted file mode 100644 index 73ede03c..00000000 --- a/PepperDashEssentials/Bridges/BridgeBase.cs +++ /dev/null @@ -1,305 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.EthernetCommunication; - -using Newtonsoft.Json; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Lighting; -using PepperDash.Essentials.Core.Devices; -using PepperDash.Essentials.Devices.Common; -using PepperDash.Essentials.Devices.Common.Cameras; -using PepperDash.Essentials.Core.Config; -using PepperDash.Essentials.Core.CrestronIO; -using PepperDash.Essentials.DM; -//using PepperDash.Essentials.Devices.Common.Cameras; - -namespace PepperDash.Essentials.Bridges -{ - /// - /// Base class for all bridge class variants - /// - public class BridgeBase : Device - { - public BridgeApi Api { get; private set; } - - public BridgeBase(string key) : - base(key) - { - - } - - } - - /// - /// Base class for bridge API variants - /// - public abstract class BridgeApi : Device - { - public BridgeApi(string key) : - base(key) - { - - } - - } - - /// - /// Bridge API using EISC - /// - public class EiscApi : BridgeApi - { - public EiscApiPropertiesConfig PropertiesConfig { get; private set; } - - public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc { get; private set; } - - public EiscApi(DeviceConfig dc) : - base(dc.Key) - { - PropertiesConfig = JsonConvert.DeserializeObject(dc.Properties.ToString()); - - Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(PropertiesConfig.Control.IpIdInt, PropertiesConfig.Control.TcpSshProperties.Address, Global.ControlSystem); - - Eisc.SigChange += new Crestron.SimplSharpPro.DeviceSupport.SigEventHandler(Eisc_SigChange); - - Eisc.Register(); - - AddPostActivationAction( () => - { - Debug.Console(1, this, "Linking Devices..."); - - foreach (var d in PropertiesConfig.Devices) - { - var device = DeviceManager.GetDeviceForKey(d.DeviceKey); - - if (device != null) - { - if (device is IBridge) // Check for this first to allow bridges in plugins to override existing bridges that apply to the same type. - { - (device as IBridge).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is PepperDash.Essentials.Core.Monitoring.SystemMonitorController) - { - (device as PepperDash.Essentials.Core.Monitoring.SystemMonitorController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is GenericComm) - { - (device as GenericComm).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is CameraBase) - { - (device as CameraBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is PepperDash.Essentials.Core.DisplayBase) - { - (device as DisplayBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is DmChassisController) { - (device as DmChassisController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is DmBladeChassisController) { - (device as DmBladeChassisController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is DmpsRoutingController) - { - (device as DmpsRoutingController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is DmpsAudioOutputController) - { - (device as DmpsAudioOutputController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is DmTxControllerBase) - { - (device as DmTxControllerBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is DmRmcControllerBase) - { - (device as DmRmcControllerBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is GenericRelayDevice) - { - (device as GenericRelayDevice).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is IRSetTopBoxBase) - { - (device as IRSetTopBoxBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is IDigitalInput) - { - (device as IDigitalInput).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is AppleTV) - { - (device as AppleTV).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is HdMdxxxCEController) - { - (device as HdMdxxxCEController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is LightingBase) - { - (device as LightingBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is DigitalLogger) - { - (device as DigitalLogger).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is PepperDash.Essentials.Devices.Common.Occupancy.GlsOccupancySensorBaseController) - { - (device as PepperDash.Essentials.Devices.Common.Occupancy.GlsOccupancySensorBaseController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is StatusSignController) - { - (device as StatusSignController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - else if (device is C2nRthsController) - { - (device as C2nRthsController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); - continue; - } - } - } - - Debug.Console(1, this, "Devices Linked."); - }); - } - - /// - /// Used for debugging to trigger an action based on a join number and type - /// - /// - /// - public void ExecuteJoinAction(uint join, string type, object state) - { - try - { - switch (type.ToLower()) - { - case "digital": - { - var uo = Eisc.BooleanOutput[join].UserObject as Action; - if (uo != null) - { - Debug.Console(1, this, "Executing Action: {0}", uo.ToString()); - uo(Convert.ToBoolean(state)); - } - else - Debug.Console(1, this, "User Action is null. Nothing to Execute"); - break; - } - case "analog": - { - var uo = Eisc.BooleanOutput[join].UserObject as Action; - if (uo != null) - { - Debug.Console(1, this, "Executing Action: {0}", uo.ToString()); - uo(Convert.ToUInt16(state)); - } - else - Debug.Console(1, this, "User Action is null. Nothing to Execute"); break; - } - case "serial": - { - var uo = Eisc.BooleanOutput[join].UserObject as Action; - if (uo != null) - { - Debug.Console(1, this, "Executing Action: {0}", uo.ToString()); - uo(Convert.ToString(state)); - } - else - Debug.Console(1, this, "User Action is null. Nothing to Execute"); - break; - } - default: - { - Debug.Console(1, "Unknown join type. Use digital/serial/analog"); - break; - } - } - } - catch (Exception e) - { - Debug.Console(1, this, "Error: {0}", e); - } - - } - - /// - /// Handles incoming sig changes - /// - /// - /// - void Eisc_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args) - { - try - { - if (Debug.Level >= 1) - Debug.Console(1, this, "EiscApi change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue); - var uo = args.Sig.UserObject; - if (uo != null) - { - Debug.Console(1, this, "Executing Action: {0}", uo.ToString()); - if (uo is Action) - (uo as Action)(args.Sig.BoolValue); - else if (uo is Action) - (uo as Action)(args.Sig.UShortValue); - else if (uo is Action) - (uo as Action)(args.Sig.StringValue); - } - } - catch (Exception e) - { - Debug.Console(2, this, "Error in Eisc_SigChange handler: {0}", e); - } - } - } - - public class EiscApiPropertiesConfig - { - [JsonProperty("control")] - public EssentialsControlPropertiesConfig Control { get; set; } - - [JsonProperty("devices")] - public List Devices { get; set; } - - - public class ApiDevice - { - [JsonProperty("deviceKey")] - public string DeviceKey { get; set; } - - [JsonProperty("joinStart")] - public uint JoinStart { get; set; } - - [JsonProperty("joinMapKey")] - public string JoinMapKey { get; set; } - } - - } - - -} \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/BridgeFactory.cs b/PepperDashEssentials/Bridges/BridgeFactory.cs index 38cd117e..c17d4642 100644 --- a/PepperDashEssentials/Bridges/BridgeFactory.cs +++ b/PepperDashEssentials/Bridges/BridgeFactory.cs @@ -6,6 +6,7 @@ using Crestron.SimplSharp; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; using PepperDash.Core; using PepperDash.Essentials.Core.Routing; @@ -15,32 +16,21 @@ using Crestron.SimplSharpPro.EthernetCommunication; namespace PepperDash.Essentials { + /// + /// Responsible for loading all of the device types for this library + /// public class BridgeFactory { - public static IKeyed GetDevice(DeviceConfig dc) + public BridgeFactory() { - // ? why is this static JTA 2018-06-13? + var eiscApiAdvancedFactory = new EiscApiAdvancedFactory() as IDeviceFactory; + eiscApiAdvancedFactory.LoadTypeFactories(); - var key = dc.Key; - var name = dc.Name; - var type = dc.Type; - var properties = dc.Properties; - var propAnon = new { }; - - var typeName = dc.Type.ToLower(); - var groupName = dc.Group.ToLower(); - - //Debug.Console(2, "Name {0}, Key {1}, Type {2}, Properties {3}", name, key, type, properties.ToString()); - - if (typeName == "eiscapi") - { - return new EiscApi(dc); - } - - return null; + var eiscApiFactory = new EiscApiFactory() as IDeviceFactory; + eiscApiFactory.LoadTypeFactories(); } - } + } public class CommBridge : Device { diff --git a/PepperDashEssentials/Bridges/C2nRthsControllerBridge.cs b/PepperDashEssentials/Bridges/C2nRthsControllerBridge.cs index 58f4600d..931ee231 100644 --- a/PepperDashEssentials/Bridges/C2nRthsControllerBridge.cs +++ b/PepperDashEssentials/Bridges/C2nRthsControllerBridge.cs @@ -4,7 +4,7 @@ using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.CrestronIO; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class C2nRthsControllerApiExtensions { @@ -13,7 +13,7 @@ namespace PepperDash.Essentials.Bridges { var joinMap = new C2nRthsControllerJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/CameraControllerBridge.cs b/PepperDashEssentials/Bridges/CameraControllerBridge.cs index badf9ea0..6a3771d3 100644 --- a/PepperDashEssentials/Bridges/CameraControllerBridge.cs +++ b/PepperDashEssentials/Bridges/CameraControllerBridge.cs @@ -11,33 +11,35 @@ using PepperDash.Essentials.Devices.Common.Cameras; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class CameraControllerApiExtensions { - - public static void LinkToApi(this PepperDash.Essentials.Devices.Common.Cameras.CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey) + public static void LinkToApi(this PepperDash.Essentials.Devices.Common.Cameras.CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApi bridge) { - CameraControllerJoinMap joinMap = new CameraControllerJoinMap(); + CameraControllerJoinMap joinMap = new CameraControllerJoinMap(joinStart); + + // Adds the join map to the bridge + bridge.AddJoinMap(cameraDevice.Key, joinMap); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); - if (!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - - joinMap.OffsetJoinNumbers(joinStart); + if (customJoins != null) + { + joinMap.SetCustomJoinData(customJoins); + } Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); Debug.Console(0, "Linking to Bridge Type {0}", cameraDevice.GetType().Name.ToString()); var commMonitor = cameraDevice as ICommunicationMonitor; - commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); var ptzCamera = cameraDevice as IHasCameraPtzControl; if (ptzCamera != null) { - trilist.SetBoolSigAction(joinMap.Left, (b) => + trilist.SetBoolSigAction(joinMap.PanLeft.JoinNumber, (b) => { if (b) { @@ -48,7 +50,7 @@ namespace PepperDash.Essentials.Bridges ptzCamera.PanStop(); } }); - trilist.SetBoolSigAction(joinMap.Right, (b) => + trilist.SetBoolSigAction(joinMap.PanRight.JoinNumber, (b) => { if (b) { @@ -60,7 +62,7 @@ namespace PepperDash.Essentials.Bridges } }); - trilist.SetBoolSigAction(joinMap.Up, (b) => + trilist.SetBoolSigAction(joinMap.TiltUp.JoinNumber, (b) => { if (b) { @@ -71,7 +73,7 @@ namespace PepperDash.Essentials.Bridges ptzCamera.TiltStop(); } }); - trilist.SetBoolSigAction(joinMap.Down, (b) => + trilist.SetBoolSigAction(joinMap.TiltDown.JoinNumber, (b) => { if (b) { @@ -83,7 +85,7 @@ namespace PepperDash.Essentials.Bridges } }); - trilist.SetBoolSigAction(joinMap.ZoomIn, (b) => + trilist.SetBoolSigAction(joinMap.ZoomIn.JoinNumber, (b) => { if (b) { @@ -95,7 +97,7 @@ namespace PepperDash.Essentials.Bridges } }); - trilist.SetBoolSigAction(joinMap.ZoomOut, (b) => + trilist.SetBoolSigAction(joinMap.ZoomOut.JoinNumber, (b) => { if (b) { @@ -108,27 +110,57 @@ namespace PepperDash.Essentials.Bridges }); } - if (cameraDevice.GetType().Name.ToString().ToLower() == "cameravisca") + if (cameraDevice is IPower) { - var viscaCamera = cameraDevice as PepperDash.Essentials.Devices.Common.Cameras.CameraVisca; - trilist.SetSigTrueAction(joinMap.PowerOn, () => viscaCamera.PowerOn()); - trilist.SetSigTrueAction(joinMap.PowerOff, () => viscaCamera.PowerOff()); + 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]); + } - viscaCamera.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn]); - viscaCamera.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff]); + if (cameraDevice is ICommunicationMonitor) + { + var monitoredCamera = cameraDevice as ICommunicationMonitor; + monitoredCamera.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); + } - viscaCamera.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); - for (int i = 0; i < joinMap.NumberOfPresets; i++) + if (cameraDevice is IHasCameraPresets) + { + // Set the preset lables when they change + var presetsCamera = cameraDevice as IHasCameraPresets; + presetsCamera.PresetsListHasChanged += new EventHandler((o, a) => + { + for (int i = 1; i <= joinMap.NumberOfPresets.JoinNumber; i++) + { + int tempNum = i - 1; + + string label = "" ; + + var preset = presetsCamera.Presets.FirstOrDefault(p => p.ID.Equals(i)); + + if (preset != null) + label = preset.Description; + + trilist.SetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum), label); + } + }); + + for (int i = 0; i < joinMap.NumberOfPresets.JoinNumber; i++) { int tempNum = i; - trilist.SetSigTrueAction((ushort)(joinMap.PresetRecallOffset + tempNum), () => + + trilist.SetSigTrueAction((ushort)(joinMap.PresetRecallStart.JoinNumber + tempNum), () => { - viscaCamera.RecallPreset(tempNum); + presetsCamera.PresetSelect(tempNum); + }); + trilist.SetSigTrueAction((ushort)(joinMap.PresetSaveStart.JoinNumber + tempNum), () => + { + var label = trilist.GetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum)); + + presetsCamera.PresetStore(tempNum, label); }); - trilist.SetSigTrueAction((ushort)(joinMap.PresetSaveOffset + tempNum), () => - { - viscaCamera.SavePreset(tempNum); - }); } } } diff --git a/PepperDashEssentials/Bridges/DigitalLoggerBridge.cs b/PepperDashEssentials/Bridges/DigitalLoggerBridge.cs deleted file mode 100644 index 2c857da2..00000000 --- a/PepperDashEssentials/Bridges/DigitalLoggerBridge.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.DeviceSupport; -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Devices.Common; - -using Newtonsoft.Json; - -namespace PepperDash.Essentials.Bridges -{ - public static class DigitalLoggerApiExtensions - { - public static void LinkToApi(this DigitalLogger DigitalLogger, BasicTriList trilist, uint joinStart, string joinMapKey) - { - DigitalLoggerJoinMap joinMap = new DigitalLoggerJoinMap(); - - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); - - if (!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - - joinMap.OffsetJoinNumbers(joinStart); - - Debug.Console(1, DigitalLogger, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - for (uint i = 1; i <= DigitalLogger.CircuitCount; i++) - { - var circuit = i; - DigitalLogger.CircuitNameFeedbacks[circuit - 1].LinkInputSig(trilist.StringInput[joinMap.CircuitNames + circuit]); - DigitalLogger.CircuitIsCritical[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitIsCritical + circuit]); - DigitalLogger.CircuitState[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitState + circuit]); - trilist.SetSigTrueAction(joinMap.CircuitCycle + circuit, () => DigitalLogger.CycleCircuit(circuit - 1)); - trilist.SetSigTrueAction(joinMap.CircuitOnCmd + circuit, () => DigitalLogger.TurnOnCircuit(circuit - 1)); - trilist.SetSigTrueAction(joinMap.CircuitOffCmd + circuit, () => DigitalLogger.TurnOffCircuit(circuit - 1)); - - } - } - } -} \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/DisplayControllerBridge.cs b/PepperDashEssentials/Bridges/DisplayControllerBridge.cs deleted file mode 100644 index 25791796..00000000 --- a/PepperDashEssentials/Bridges/DisplayControllerBridge.cs +++ /dev/null @@ -1,153 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.DeviceSupport; -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Devices.Common; - -using Newtonsoft.Json; - - -namespace PepperDash.Essentials.Bridges -{ - public static class DisplayControllerApiExtensions - { - public static void LinkToApi(this PepperDash.Essentials.Core.DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey) - { - int inputNumber = 0; - IntFeedback inputNumberFeedback; - List inputKeys = new List(); - - DisplayControllerJoinMap joinMap = new DisplayControllerJoinMap(); - - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); - - if(!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - - joinMap.OffsetJoinNumbers(joinStart); - - Debug.Console(1, "Linking to Trilist '{0}'",trilist.ID.ToString("X")); - Debug.Console(0, "Linking to Display: {0}", displayDevice.Name); - - trilist.StringInput[joinMap.Name].StringValue = displayDevice.Name; - - var commMonitor = displayDevice as ICommunicationMonitor; - if (commMonitor != null) - { - commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); - } - - inputNumberFeedback = new IntFeedback(() => { return inputNumber; }); - - // Two way feedbacks - var twoWayDisplay = displayDevice as PepperDash.Essentials.Core.TwoWayDisplayBase; - if (twoWayDisplay != null) - { - trilist.SetBool(joinMap.IsTwoWayDisplay, true); - - twoWayDisplay.CurrentInputFeedback.OutputChange += new EventHandler(CurrentInputFeedback_OutputChange); - - - inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect]); - } - - // Power Off - trilist.SetSigTrueAction(joinMap.PowerOff, () => - { - inputNumber = 102; - inputNumberFeedback.FireUpdate(); - displayDevice.PowerOff(); - }); - - displayDevice.PowerIsOnFeedback.OutputChange += new EventHandler( (o,a) => { - if (!a.BoolValue) - { - inputNumber = 102; - inputNumberFeedback.FireUpdate(); - - } - else - { - inputNumber = 0; - inputNumberFeedback.FireUpdate(); - } - }); - - displayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff]); - - // PowerOn - trilist.SetSigTrueAction(joinMap.PowerOn, () => - { - inputNumber = 0; - inputNumberFeedback.FireUpdate(); - displayDevice.PowerOn(); - }); - - - displayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn]); - - int count = 1; - foreach (var input in displayDevice.InputPorts) - { - inputKeys.Add(input.Key.ToString()); - var tempKey = inputKeys.ElementAt(count - 1); - trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset + count), () => { displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector); }); - Debug.Console(2, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}", joinMap.InputSelectOffset + count, displayDevice.InputPorts[tempKey].Key.ToString()); - trilist.StringInput[(ushort)(joinMap.InputNamesOffset + count)].StringValue = input.Key.ToString(); - count++; - } - - Debug.Console(2, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect); - trilist.SetUShortSigAction(joinMap.InputSelect, (a) => - { - if (a == 0) - { - displayDevice.PowerOff(); - inputNumber = 0; - } - else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber) - { - displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector); - inputNumber = a; - } - else if (a == 102) - { - displayDevice.PowerToggle(); - - } - if (twoWayDisplay != null) - inputNumberFeedback.FireUpdate(); - }); - - - var volumeDisplay = displayDevice as IBasicVolumeControls; - if (volumeDisplay != null) - { - trilist.SetBoolSigAction(joinMap.VolumeUp, (b) => volumeDisplay.VolumeUp(b)); - trilist.SetBoolSigAction(joinMap.VolumeDown, (b) => volumeDisplay.VolumeDown(b)); - trilist.SetSigTrueAction(joinMap.VolumeMute, () => volumeDisplay.MuteToggle()); - - var volumeDisplayWithFeedback = volumeDisplay as IBasicVolumeWithFeedback; - if(volumeDisplayWithFeedback != null) - { - trilist.SetUShortSigAction(joinMap.VolumeLevel, new Action((u) => volumeDisplayWithFeedback.SetVolume(u))); - volumeDisplayWithFeedback.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel]); - volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMute]); - } - } - } - - static void CurrentInputFeedback_OutputChange(object sender, FeedbackEventArgs e) - { - - Debug.Console(0, "CurrentInputFeedback_OutputChange {0}", e.StringValue); - - } - - } - -} \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/DmBladeChassisControllerBridge.cs b/PepperDashEssentials/Bridges/DmBladeChassisControllerBridge.cs deleted file mode 100644 index 6daddbb0..00000000 --- a/PepperDashEssentials/Bridges/DmBladeChassisControllerBridge.cs +++ /dev/null @@ -1,222 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.DM; -using Crestron.SimplSharpPro.DM.Endpoints; -using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.DM; - -using Newtonsoft.Json; - -namespace PepperDash.Essentials.Bridges { - public static class DmBladeChassisControllerApiExtentions { - public static void LinkToApi(this DmBladeChassisController dmChassis, BasicTriList trilist, uint joinStart, string joinMapKey) { - DmBladeChassisControllerJoinMap joinMap = new DmBladeChassisControllerJoinMap(); - - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); - - if (!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - - - joinMap.OffsetJoinNumbers(joinStart); - - Debug.Console(1, dmChassis, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - - var chassis = dmChassis.Chassis as BladeSwitch; - - dmChassis.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); - - - // Link up outputs - for (uint i = 1; i <= dmChassis.Chassis.NumberOfOutputs; i++) { - var ioSlot = i; - - // Control - trilist.SetUShortSigAction(joinMap.OutputVideo + ioSlot, new Action(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video))); - - if (dmChassis.TxDictionary.ContainsKey(ioSlot)) { - Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot); - var txKey = dmChassis.TxDictionary[ioSlot]; - var basicTxDevice = DeviceManager.GetDeviceForKey(txKey) as BasicDmTxControllerBase; - - var advancedTxDevice = basicTxDevice as DmTxControllerBase; - - if (dmChassis.Chassis is DmMd128x128 || dmChassis.Chassis is DmMd64x64) { - dmChassis.InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); - } - else { - if (advancedTxDevice != null) { - advancedTxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); - Debug.Console(2, "Linking Tx Online Feedback from Advanced Transmitter at input {0}", ioSlot); - } - else if (dmChassis.InputEndpointOnlineFeedbacks[ioSlot] != null) { - Debug.Console(2, "Linking Tx Online Feedback from Input Card {0}", ioSlot); - dmChassis.InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); - } - } - - if (basicTxDevice != null && advancedTxDevice == null) - trilist.BooleanInput[joinMap.TxAdvancedIsPresent + ioSlot].BoolValue = true; - - if (advancedTxDevice != null) { - advancedTxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); - } - else if (advancedTxDevice == null || basicTxDevice != null) { - Debug.Console(1, "Setting up actions and feedbacks on input card {0}", ioSlot); - dmChassis.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); - - var inputPort = dmChassis.InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; - if (inputPort != null) { - Debug.Console(1, "Port value for input card {0} is set", ioSlot); - var port = inputPort.Port; - - if (port != null) { - if (port is HdmiInputWithCEC) { - Debug.Console(1, "Port is HdmiInputWithCec"); - - var hdmiInPortWCec = port as HdmiInputWithCEC; - - if (hdmiInPortWCec.HdcpSupportedLevel != eHdcpSupportedLevel.Unknown) { - SetHdcpStateAction(true, hdmiInPortWCec, joinMap.HdcpSupportState + ioSlot, trilist); - } - - dmChassis.InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); - - if (dmChassis.InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) - trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = (ushort)dmChassis.InputCardHdcpCapabilityTypes[ioSlot]; - else - trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = 1; - } - } - } - else { - inputPort = dmChassis.InputPorts[string.Format("inputCard{0}--dmIn", ioSlot)]; - - if (inputPort != null) { - var port = inputPort.Port; - - if (port is DMInputPortWithCec) { - Debug.Console(1, "Port is DMInputPortWithCec"); - - var dmInPortWCec = port as DMInputPortWithCec; - - if (dmInPortWCec != null) { - SetHdcpStateAction(dmChassis.PropertiesConfig.InputSlotSupportsHdcp2[ioSlot], dmInPortWCec, joinMap.HdcpSupportState + ioSlot, trilist); - } - - dmChassis.InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); - - if (dmChassis.InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) - trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = (ushort)dmChassis.InputCardHdcpCapabilityTypes[ioSlot]; - else - trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = 1; - } - } - } - } - } - else { - dmChassis.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); - - var inputPort = dmChassis.InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; - if (inputPort != null) { - var hdmiPort = inputPort.Port as EndpointHdmiInput; - - if (hdmiPort != null) { - SetHdcpStateAction(true, hdmiPort, joinMap.HdcpSupportState + ioSlot, trilist); - dmChassis.InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); - } - } - } - if (dmChassis.RxDictionary.ContainsKey(ioSlot)) { - Debug.Console(2, "Creating Rx Feedbacks {0}", ioSlot); - //var rxKey = dmChassis.RxDictionary[ioSlot]; - //var rxDevice = DeviceManager.GetDeviceForKey(rxKey) as DmRmcControllerBase; - //var hdBaseTDevice = DeviceManager.GetDeviceForKey(rxKey) as DmHdBaseTControllerBase; - //if (hdBaseTDevice != null) { - dmChassis.OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]); - //} - //else if (rxDevice != null) { - // rxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]); - //} - } - - // Feedback - dmChassis.VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo + ioSlot]); - - - dmChassis.OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames + ioSlot]); - dmChassis.InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames + ioSlot]); - dmChassis.OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames + ioSlot]); - } - } - - static void SetHdcpStateAction(bool hdcpTypeSimple, HdmiInputWithCEC port, uint join, BasicTriList trilist) { - if (hdcpTypeSimple) { - trilist.SetUShortSigAction(join, - new Action(s => { - if (s == 0) { - port.HdcpSupportOff(); - } - else if (s > 0) { - port.HdcpSupportOn(); - } - })); - } - else { - trilist.SetUShortSigAction(join, - new Action(u => { - port.HdcpReceiveCapability = (eHdcpCapabilityType)u; - })); - } - } - - static void SetHdcpStateAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist) { - if (hdcpTypeSimple) { - trilist.SetUShortSigAction(join, - new Action(s => { - if (s == 0) { - port.HdcpSupportOff(); - } - else if (s > 0) { - port.HdcpSupportOn(); - } - })); - } - else { - trilist.SetUShortSigAction(join, - new Action(u => { - port.HdcpCapability = (eHdcpCapabilityType)u; - })); - } - } - - static void SetHdcpStateAction(bool supportsHdcp2, DMInputPortWithCec port, uint join, BasicTriList trilist) { - if (!supportsHdcp2) { - trilist.SetUShortSigAction(join, - new Action(s => { - if (s == 0) { - port.HdcpSupportOff(); - } - else if (s > 0) { - port.HdcpSupportOn(); - } - })); - } - else { - trilist.SetUShortSigAction(join, - new Action(u => { - port.HdcpReceiveCapability = (eHdcpCapabilityType)u; - })); - } - } - - } -} \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs b/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs index e193cc2c..6522a5f0 100644 --- a/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs +++ b/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs @@ -15,7 +15,7 @@ using PepperDash.Essentials.DM; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class DmChassisControllerApiExtentions { @@ -23,7 +23,7 @@ namespace PepperDash.Essentials.Bridges { DmChassisControllerJoinMap joinMap = new DmChassisControllerJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/DmRmcControllerBridge.cs b/PepperDashEssentials/Bridges/DmRmcControllerBridge.cs index ca7bdeca..5609cf03 100644 --- a/PepperDashEssentials/Bridges/DmRmcControllerBridge.cs +++ b/PepperDashEssentials/Bridges/DmRmcControllerBridge.cs @@ -11,7 +11,7 @@ using PepperDash.Essentials.DM; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class DmRmcControllerApiExtensions { @@ -19,7 +19,7 @@ namespace PepperDash.Essentials.Bridges { DmRmcControllerJoinMap joinMap = new DmRmcControllerJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/DmTxControllerBridge.cs b/PepperDashEssentials/Bridges/DmTxControllerBridge.cs index 91f8c6d7..c565f41e 100644 --- a/PepperDashEssentials/Bridges/DmTxControllerBridge.cs +++ b/PepperDashEssentials/Bridges/DmTxControllerBridge.cs @@ -14,7 +14,7 @@ using PepperDash.Essentials.DM; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class DmTxControllerApiExtensions { @@ -22,7 +22,7 @@ namespace PepperDash.Essentials.Bridges { DmTxControllerJoinMap joinMap = new DmTxControllerJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/DmpsAudioOutputControllerBridge.cs b/PepperDashEssentials/Bridges/DmpsAudioOutputControllerBridge.cs index 406550a4..eec058da 100644 --- a/PepperDashEssentials/Bridges/DmpsAudioOutputControllerBridge.cs +++ b/PepperDashEssentials/Bridges/DmpsAudioOutputControllerBridge.cs @@ -12,7 +12,7 @@ using PepperDash.Essentials.DM; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class DmpsAudioOutputControllerApiExtensions { @@ -20,7 +20,7 @@ namespace PepperDash.Essentials.Bridges { DmpsAudioOutputControllerJoinMap joinMap = new DmpsAudioOutputControllerJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/DmpsRoutingControllerBridge.cs b/PepperDashEssentials/Bridges/DmpsRoutingControllerBridge.cs index cc95e07b..ea775039 100644 --- a/PepperDashEssentials/Bridges/DmpsRoutingControllerBridge.cs +++ b/PepperDashEssentials/Bridges/DmpsRoutingControllerBridge.cs @@ -12,7 +12,7 @@ using PepperDash.Essentials.DM; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class DmpsRoutingControllerApiExtentions { @@ -20,7 +20,7 @@ namespace PepperDash.Essentials.Bridges { DmpsRoutingControllerJoinMap joinMap = new DmpsRoutingControllerJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/EiscBridge.cs b/PepperDashEssentials/Bridges/EiscBridge.cs new file mode 100644 index 00000000..4c999f20 --- /dev/null +++ b/PepperDashEssentials/Bridges/EiscBridge.cs @@ -0,0 +1,232 @@ +using System; +using System.Collections.Generic; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.EthernetCommunication; +using PepperDash.Core; +using PepperDash.Essentials.Bridges; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; + +namespace PepperDash.Essentials.Bridges +{ + [Obsolete("Please use 'eiscapiadvanced' in configurations going forward")] + public class EiscApi : BridgeApi + { + public EiscApiPropertiesConfig PropertiesConfig { get; private set; } + + protected Dictionary JoinMaps { get; private set; } + + public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc { get; private set; } + + public EiscApi(DeviceConfig dc) : + base(dc.Key) + { + JoinMaps = new Dictionary(); + + PropertiesConfig = dc.Properties.ToObject(); + //PropertiesConfig = JsonConvert.DeserializeObject(dc.Properties.ToString()); + + Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(PropertiesConfig.Control.IpIdInt, PropertiesConfig.Control.TcpSshProperties.Address, Global.ControlSystem); + + Eisc.SigChange += Eisc_SigChange; + + Eisc.Register(); + + AddPostActivationAction(() => + { + Debug.Console(1, this, "Linking Devices..."); + + foreach (var d in PropertiesConfig.Devices) + { + var device = DeviceManager.GetDeviceForKey(d.DeviceKey); + + if (device == null) continue; + + Debug.Console(1, this, "Linking Device: '{0}'", device.Key); + if (device is IBridge) // Check for this first to allow bridges in plugins to override existing bridges that apply to the same type. + { + Debug.Console(2, this, "'{0}' is IBridge", device.Key); + + var dev = device as IBridge; + + dev.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); + } + if (!(device is IBridgeAdvanced)) continue; + Debug.Console(2, this, "'{0}' is IBridgeAdvanced", device.Key); + + var advDev = device as IBridgeAdvanced; + + try + { + advDev.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, null); + } + catch (NullReferenceException) + { + Debug.ConsoleWithLog(0, this, + "Please update the bridge config to use EiscBridgeAdvanced with this device: {0}", device.Key); + } + + } + Debug.Console(1, this, "Devices Linked."); + + + }); + } + + /// + /// Adds a join map + /// + /// + /// + public void AddJoinMap(string deviceKey, JoinMapBaseAdvanced joinMap) + { + if (!JoinMaps.ContainsKey(deviceKey)) + { + JoinMaps.Add(deviceKey, joinMap); + } + else + { + Debug.Console(2, this, "Unable to add join map with key '{0}'. Key already exists in JoinMaps dictionary", deviceKey); + } + } + + /// + /// Prints all the join maps on this bridge + /// + public void PrintJoinMaps() + { + Debug.Console(0, this, "Join Maps for EISC IPID: {0}", Eisc.ID.ToString("X")); + + foreach (var joinMap in JoinMaps) + { + Debug.Console(0, "Join map for device '{0}':", joinMap.Key); + joinMap.Value.PrintJoinMapInfo(); + } + } + + /// + /// Prints the join map for a device by key + /// + /// + public void PrintJoinMapForDevice(string deviceKey) + { + var joinMap = JoinMaps[deviceKey]; + + if (joinMap == null) + { + Debug.Console(0, this, "Unable to find joinMap for device with key: '{0}'", deviceKey); + return; + } + + Debug.Console(0, "Join map for device '{0}' on EISC '{1}':", deviceKey, Key); + joinMap.PrintJoinMapInfo(); + } + + /// + /// Used for debugging to trigger an action based on a join number and type + /// + /// + /// + /// + public void ExecuteJoinAction(uint join, string type, object state) + { + try + { + switch (type.ToLower()) + { + case "digital": + { + var uo = Eisc.BooleanOutput[join].UserObject as Action; + if (uo != null) + { + Debug.Console(1, this, "Executing Action: {0}", uo.ToString()); + uo(Convert.ToBoolean(state)); + } + else + Debug.Console(1, this, "User Action is null. Nothing to Execute"); + break; + } + case "analog": + { + var uo = Eisc.BooleanOutput[join].UserObject as Action; + if (uo != null) + { + Debug.Console(1, this, "Executing Action: {0}", uo.ToString()); + uo(Convert.ToUInt16(state)); + } + else + Debug.Console(1, this, "User Action is null. Nothing to Execute"); break; + } + case "serial": + { + var uo = Eisc.BooleanOutput[join].UserObject as Action; + if (uo != null) + { + Debug.Console(1, this, "Executing Action: {0}", uo.ToString()); + uo(Convert.ToString(state)); + } + else + Debug.Console(1, this, "User Action is null. Nothing to Execute"); + break; + } + default: + { + Debug.Console(1, "Unknown join type. Use digital/serial/analog"); + break; + } + } + } + catch (Exception e) + { + Debug.Console(1, this, "Error: {0}", e); + } + + } + + /// + /// Handles incoming sig changes + /// + /// + /// + void Eisc_SigChange(object currentDevice, SigEventArgs args) + { + try + { + if (Debug.Level >= 1) + Debug.Console(1, this, "EiscApiAdvanced change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue); + var uo = args.Sig.UserObject; + + if (uo == null) return; + + Debug.Console(1, this, "Executing Action: {0}", uo.ToString()); + if (uo is Action) + (uo as Action)(args.Sig.BoolValue); + else if (uo is Action) + (uo as Action)(args.Sig.UShortValue); + else if (uo is Action) + (uo as Action)(args.Sig.StringValue); + } + catch (Exception e) + { + Debug.Console(2, this, "Error in Eisc_SigChange handler: {0}", e); + } + } + } + + public class EiscApiFactory : EssentialsDeviceFactory + { + public EiscApiFactory() + { + TypeNames = new List() { "eiscapi" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new EiscApi Device"); + + return new EiscApi(dc); + } + } + +} \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/GenericLightingBridge.cs b/PepperDashEssentials/Bridges/GenericLightingBridge.cs index 543e124e..5365b813 100644 --- a/PepperDashEssentials/Bridges/GenericLightingBridge.cs +++ b/PepperDashEssentials/Bridges/GenericLightingBridge.cs @@ -10,7 +10,7 @@ using PepperDash.Essentials.Devices.Common; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class GenericLightingApiExtensions { @@ -18,7 +18,7 @@ namespace PepperDash.Essentials.Bridges { GenericLightingJoinMap joinMap = new GenericLightingJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/GenericRelayDeviceBridge.cs b/PepperDashEssentials/Bridges/GenericRelayDeviceBridge.cs index 95566712..8175f115 100644 --- a/PepperDashEssentials/Bridges/GenericRelayDeviceBridge.cs +++ b/PepperDashEssentials/Bridges/GenericRelayDeviceBridge.cs @@ -11,7 +11,7 @@ using PepperDash.Essentials.Core.CrestronIO; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class GenericRelayDeviceApiExtensions { @@ -19,7 +19,7 @@ namespace PepperDash.Essentials.Bridges { GenericRelayControllerJoinMap joinMap = new GenericRelayControllerJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/GlsOccupancySensorBaseControllerBridge.cs b/PepperDashEssentials/Bridges/GlsOccupancySensorBaseControllerBridge.cs index d905beef..b073750c 100644 --- a/PepperDashEssentials/Bridges/GlsOccupancySensorBaseControllerBridge.cs +++ b/PepperDashEssentials/Bridges/GlsOccupancySensorBaseControllerBridge.cs @@ -12,7 +12,7 @@ using PepperDash.Core; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class GlsOccupancySensorBaseControllerApiExtensions { @@ -20,7 +20,7 @@ namespace PepperDash.Essentials.Bridges { GlsOccupancySensorBaseJoinMap joinMap = new GlsOccupancySensorBaseJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/HdMdxxxCEControllerBridge.cs b/PepperDashEssentials/Bridges/HdMdxxxCEControllerBridge.cs index 0ec23c55..bf6fdb54 100644 --- a/PepperDashEssentials/Bridges/HdMdxxxCEControllerBridge.cs +++ b/PepperDashEssentials/Bridges/HdMdxxxCEControllerBridge.cs @@ -14,7 +14,7 @@ using PepperDash.Essentials.DM; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class HdMdxxxCEControllerApiExtensions { @@ -22,7 +22,7 @@ namespace PepperDash.Essentials.Bridges { HdMdxxxCEControllerJoinMap joinMap = new HdMdxxxCEControllerJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/IBasicCommunicationBridge.cs b/PepperDashEssentials/Bridges/IBasicCommunicationBridge.cs index 86fbf78b..b23860d3 100644 --- a/PepperDashEssentials/Bridges/IBasicCommunicationBridge.cs +++ b/PepperDashEssentials/Bridges/IBasicCommunicationBridge.cs @@ -10,7 +10,7 @@ using PepperDash.Essentials.Core; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class IBasicCommunicationApiExtensions { @@ -18,7 +18,7 @@ namespace PepperDash.Essentials.Bridges { IBasicCommunicationJoinMap joinMap = new IBasicCommunicationJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/IBridge.cs b/PepperDashEssentials/Bridges/IBridge.cs index d86a1d1d..497985c7 100644 --- a/PepperDashEssentials/Bridges/IBridge.cs +++ b/PepperDashEssentials/Bridges/IBridge.cs @@ -1,12 +1,12 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; using Crestron.SimplSharpPro.DeviceSupport; namespace PepperDash.Essentials.Bridges { + /// + /// Defines a device that uses the legacy JoinMapBase for its join map + /// + [Obsolete("IBridgeAdvanced should be used going forward with JoinMapBaseAdvanced")] public interface IBridge { void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey); diff --git a/PepperDashEssentials/Bridges/IDigitalInputBridge.cs b/PepperDashEssentials/Bridges/IDigitalInputBridge.cs index 4d42cbdc..078e0b13 100644 --- a/PepperDashEssentials/Bridges/IDigitalInputBridge.cs +++ b/PepperDashEssentials/Bridges/IDigitalInputBridge.cs @@ -11,7 +11,7 @@ using PepperDash.Essentials.Core.CrestronIO; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class IDigitalInputApiExtenstions { @@ -19,7 +19,7 @@ namespace PepperDash.Essentials.Bridges { IDigitalInputJoinMap joinMap = new IDigitalInputJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/IRSetTopBoxBaseBridge.cs b/PepperDashEssentials/Bridges/IRSetTopBoxBaseBridge.cs index 68d765bc..76e5b5ee 100644 --- a/PepperDashEssentials/Bridges/IRSetTopBoxBaseBridge.cs +++ b/PepperDashEssentials/Bridges/IRSetTopBoxBaseBridge.cs @@ -10,14 +10,14 @@ using PepperDash.Essentials.Devices.Common; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class IRSetTopBoxBaseApiExtensions { public static void LinkToApi(this PepperDash.Essentials.Devices.Common.IRSetTopBoxBase stbDevice, BasicTriList trilist, uint joinStart, string joinMapKey) { SetTopBoxControllerJoinMap joinMap = new SetTopBoxControllerJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/JoinMaps/AirMediaControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/AirMediaControllerJoinMap.cs index 042a3bf3..5b02c05b 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/AirMediaControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/AirMediaControllerJoinMap.cs @@ -7,6 +7,7 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class AirMediaControllerJoinMap : JoinMapBase { #region Digitals diff --git a/PepperDashEssentials/Bridges/JoinMaps/AppleTvJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/AppleTvJoinMap.cs index 8945d9c9..ac84ee31 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/AppleTvJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/AppleTvJoinMap.cs @@ -7,6 +7,7 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class AppleTvJoinMap : JoinMapBase { #region Digitals diff --git a/PepperDashEssentials/Bridges/JoinMaps/C2nRthsControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/C2nRthsControllerJoinMap.cs index be0f002e..bbf8268d 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/C2nRthsControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/C2nRthsControllerJoinMap.cs @@ -1,43 +1,45 @@ -using System.Linq; -using Crestron.SimplSharp.Reflection; -using PepperDash.Essentials.Core; - -namespace PepperDash.Essentials.Bridges -{ - public class C2nRthsControllerJoinMap:JoinMapBase - { - public uint IsOnline { get; set; } - public uint Name { get; set; } - public uint Temperature { get; set; } - public uint Humidity { get; set; } - public uint TemperatureFormat { get; set; } - - public C2nRthsControllerJoinMap() - { - //digital - IsOnline = 1; - TemperatureFormat = 2; - - //Analog - Temperature = 2; - Humidity = 3; - - //serial - Name = 1; - - - } - - public override void OffsetJoinNumbers(uint joinStart) - { - var joinOffset = joinStart - 1; - var properties = - GetType().GetCType().GetProperties().Where(p => p.PropertyType == typeof(uint)).ToList(); - - foreach (var propertyInfo in properties) - { - propertyInfo.SetValue(this, (uint)propertyInfo.GetValue(this, null) + joinOffset, null); - } - } - } +using System; +using System.Linq; +using Crestron.SimplSharp.Reflection; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Bridges +{ + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] + public class C2nRthsControllerJoinMap:JoinMapBase + { + public uint IsOnline { get; set; } + public uint Name { get; set; } + public uint Temperature { get; set; } + public uint Humidity { get; set; } + public uint TemperatureFormat { get; set; } + + public C2nRthsControllerJoinMap() + { + //digital + IsOnline = 1; + TemperatureFormat = 2; + + //Analog + Temperature = 2; + Humidity = 3; + + //serial + Name = 1; + + + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + var properties = + GetType().GetCType().GetProperties().Where(p => p.PropertyType == typeof(uint)).ToList(); + + foreach (var propertyInfo in properties) + { + propertyInfo.SetValue(this, (uint)propertyInfo.GetValue(this, null) + joinOffset, null); + } + } + } } \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/JoinMaps/CameraControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/CameraControllerJoinMap.cs index cf087e5f..1546ff23 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/CameraControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/CameraControllerJoinMap.cs @@ -8,54 +8,59 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { - public class CameraControllerJoinMap : JoinMapBase + /// + /// Join map for CameraBase devices + /// + /// + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] + public class CameraControllerJoinMap : JoinMapBaseAdvanced { - public uint IsOnline { get; set; } - public uint PowerOff { get; set; } - public uint PowerOn { get; set; } - public uint Up { get; set; } - public uint Down { get; set; } - public uint Left { get; set; } - public uint Right { get; set; } - public uint ZoomIn { get; set; } - public uint ZoomOut { get; set; } - public uint PresetRecallOffset { get; set; } - public uint PresetSaveOffset { get; set; } - public uint NumberOfPresets { get; set; } + [JoinName("TiltUp")] + public JoinDataComplete TiltUp = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata() { Label = "Tilt Up", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("TiltDown")] + public JoinDataComplete TiltDown = new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 }, new JoinMetadata() { Label = "Tilt Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("PanLeft")] + public JoinDataComplete PanLeft = new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 }, new JoinMetadata() { Label = "Pan Left", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("PanRight")] + public JoinDataComplete PanRight = new JoinDataComplete(new JoinData() { JoinNumber = 4, JoinSpan = 1 }, new JoinMetadata() { Label = "Pan Right", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("ZoomIn")] + public JoinDataComplete ZoomIn = new JoinDataComplete(new JoinData() { JoinNumber = 5, JoinSpan = 1 }, new JoinMetadata() { Label = "Zoom In", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("ZoomOut")] + public JoinDataComplete ZoomOut = new JoinDataComplete(new JoinData() { JoinNumber = 6, JoinSpan = 1 }, new JoinMetadata() { Label = "Zoom Out", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); - public CameraControllerJoinMap() + [JoinName("IsOnline")] + public JoinDataComplete IsOnline = new JoinDataComplete(new JoinData() { JoinNumber = 9, JoinSpan = 1 }, new JoinMetadata() { Label = "Is Online", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("PowerOn")] + public JoinDataComplete PowerOn = new JoinDataComplete(new JoinData() { JoinNumber = 7, JoinSpan = 1 }, new JoinMetadata() { Label = "Power On", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("PowerOff")] + public JoinDataComplete PowerOff = new JoinDataComplete(new JoinData() { JoinNumber = 8, JoinSpan = 1 }, new JoinMetadata() { Label = "Power Off", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("NumberOfPresets")] + public JoinDataComplete NumberOfPresets = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 }, new JoinMetadata() { Label = "Tells Essentials the number of defined presets", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("PresetRecallStart")] + public JoinDataComplete PresetRecallStart = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 20 }, new JoinMetadata() { Label = "Preset Recall Start", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("PresetLabelStart")] + public JoinDataComplete PresetLabelStart = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 20 }, new JoinMetadata() { Label = "Preset Label Start", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("PresetSaveStart")] + public JoinDataComplete PresetSaveStart = new JoinDataComplete(new JoinData() { JoinNumber = 31, JoinSpan = 20 }, new JoinMetadata() { Label = "Preset Save Start", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("CameraModeAuto")] + public JoinDataComplete CameraModeAuto = new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Auto", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CameraModeManual")] + public JoinDataComplete CameraModeManual = new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Manual", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CameraModeOff")] + public JoinDataComplete CameraModeOff = new JoinDataComplete(new JoinData() { JoinNumber = 53, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Off", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("SupportsCameraModeAuto")] + public JoinDataComplete SupportsCameraModeAuto = new JoinDataComplete(new JoinData() { JoinNumber = 55, JoinSpan = 1 }, new JoinMetadata() { Label = "Supports Camera Mode Auto", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("SupportsCameraModeOff")] + public JoinDataComplete SupportsCameraModeOff = new JoinDataComplete(new JoinData() { JoinNumber = 56, JoinSpan = 1 }, new JoinMetadata() { Label = "Supports Camera Mode Off", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("SupportsPresets")] + public JoinDataComplete SupportsPresets = new JoinDataComplete(new JoinData() { JoinNumber = 57, JoinSpan = 1 }, new JoinMetadata() { Label = "Supports Presets", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + public CameraControllerJoinMap(uint joinStart) + : base(joinStart, typeof(CameraControllerJoinMap)) { - // Digital - IsOnline = 9; - PowerOff = 8; - PowerOn = 7; - Up = 1; - Down = 2; - Left = 3; - Right = 4; - ZoomIn = 5; - ZoomOut = 6; - PresetRecallOffset = 10; - PresetSaveOffset = 30; - NumberOfPresets = 5; - // Analog - } - - public override void OffsetJoinNumbers(uint joinStart) - { - var joinOffset = joinStart - 1; - - IsOnline = IsOnline + joinOffset; - PowerOff = PowerOff + joinOffset; - PowerOn = PowerOn + joinOffset; - Up = Up + joinOffset; - Down = Down + joinOffset; - Left = Left + joinOffset; - Right = Right + joinOffset; - ZoomIn = ZoomIn + joinOffset; - ZoomOut = ZoomOut + joinOffset; - PresetRecallOffset = PresetRecallOffset + joinOffset; - PresetSaveOffset = PresetSaveOffset + joinOffset; } } } \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/JoinMaps/DigitalLoggerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/DigitalLoggerJoinMap.cs index 2b0a1c15..3f4c8c43 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/DigitalLoggerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/DigitalLoggerJoinMap.cs @@ -8,6 +8,7 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class DigitalLoggerJoinMap : JoinMapBase { public uint IsOnline { get; set; } diff --git a/PepperDashEssentials/Bridges/JoinMaps/DisplayControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/DisplayControllerJoinMap.cs index ddbec182..48671d24 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/DisplayControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/DisplayControllerJoinMap.cs @@ -7,6 +7,7 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class DisplayControllerJoinMap : JoinMapBase { #region Digitals diff --git a/PepperDashEssentials/Bridges/JoinMaps/DmBladeChassisControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/DmBladeChassisControllerJoinMap.cs index 29ee6471..0779523a 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/DmBladeChassisControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/DmBladeChassisControllerJoinMap.cs @@ -1,109 +1,110 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using PepperDash.Essentials.Core; - -namespace PepperDash.Essentials.Bridges { - public class DmBladeChassisControllerJoinMap : JoinMapBase { - #region Digital/Analogs - #endregion - - #region Digitals - /// - /// High when device is online - /// - public uint IsOnline { get; set; } - /// - /// Range reports video sync feedback for each input - /// - public uint VideoSyncStatus { get; set; } - /// - /// Range reports high if corresponding input's endpoint is online - /// - public uint InputEndpointOnline { get; set; } - /// - /// Range reports high if corresponding output's endpoint is online - /// - public uint OutputEndpointOnline { get; set; } - /// - /// Range reports high if corresponding input's transmitter supports bridging as a separate device for detailed AV switching, HDCP control, etc. - /// - public uint TxAdvancedIsPresent { get; set; } // indicates that there is an attached transmitter that should be bridged to be interacted with - #endregion - - #region Analogs - /// - /// Range sets and reports the current video source for the corresponding output - /// - public uint OutputVideo { get; set; } - /// - /// Range sets and reports the current HDCP state for the corresponding input card - /// - public uint HdcpSupportState { get; set; } - /// - /// Range reports the highest supported HDCP state level for the corresponding input card - /// - public uint HdcpSupportCapability { get; set; } - #endregion - - #region Serials - /// - /// Range sets and reports the name for the corresponding input card - /// - public uint InputNames { get; set; } - /// - /// Range sets and reports the name for the corresponding output card - /// - public uint OutputNames { get; set; } - /// - /// Range reports the name of the current video source for the corresponding output card - /// - public uint OutputCurrentVideoInputNames { get; set; } - /// - /// Range reports the current input resolution for each corresponding input card - /// - public uint InputCurrentResolution { get; set; } - #endregion - - public DmBladeChassisControllerJoinMap() { - //Digital/Analog - - //Digital - IsOnline = 11; - VideoSyncStatus = 100; //101-299 - InputEndpointOnline = 500; //501-699 - OutputEndpointOnline = 700; //701-899 - TxAdvancedIsPresent = 1000; //1001-1199 - - //Analog - OutputVideo = 100; //101-299 - HdcpSupportState = 1000; //1001-1199 - HdcpSupportCapability = 1200; //1201-1399 - - - //Serial - InputNames = 100; //101-299 - OutputNames = 300; //301-499 - OutputCurrentVideoInputNames = 2000; //2001-2199 - InputCurrentResolution = 2400; // 2401-2599 - } - - public override void OffsetJoinNumbers(uint joinStart) { - var joinOffset = joinStart - 1; - - IsOnline = IsOnline + joinOffset; - OutputVideo = OutputVideo + joinOffset; - VideoSyncStatus = VideoSyncStatus + joinOffset; - InputNames = InputNames + joinOffset; - OutputNames = OutputNames + joinOffset; - OutputCurrentVideoInputNames = OutputCurrentVideoInputNames + joinOffset; - InputCurrentResolution = InputCurrentResolution + joinOffset; - InputEndpointOnline = InputEndpointOnline + joinOffset; - OutputEndpointOnline = OutputEndpointOnline + joinOffset; - HdcpSupportState = HdcpSupportState + joinOffset; - HdcpSupportCapability = HdcpSupportCapability + joinOffset; - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] + public class DmBladeChassisControllerJoinMap : JoinMapBase { + #region Digital/Analogs + #endregion + + #region Digitals + /// + /// High when device is online + /// + public uint IsOnline { get; set; } + /// + /// Range reports video sync feedback for each input + /// + public uint VideoSyncStatus { get; set; } + /// + /// Range reports high if corresponding input's endpoint is online + /// + public uint InputEndpointOnline { get; set; } + /// + /// Range reports high if corresponding output's endpoint is online + /// + public uint OutputEndpointOnline { get; set; } + /// + /// Range reports high if corresponding input's transmitter supports bridging as a separate device for detailed AV switching, HDCP control, etc. + /// + public uint TxAdvancedIsPresent { get; set; } // indicates that there is an attached transmitter that should be bridged to be interacted with + #endregion + + #region Analogs + /// + /// Range sets and reports the current video source for the corresponding output + /// + public uint OutputVideo { get; set; } + /// + /// Range sets and reports the current HDCP state for the corresponding input card + /// + public uint HdcpSupportState { get; set; } + /// + /// Range reports the highest supported HDCP state level for the corresponding input card + /// + public uint HdcpSupportCapability { get; set; } + #endregion + + #region Serials + /// + /// Range sets and reports the name for the corresponding input card + /// + public uint InputNames { get; set; } + /// + /// Range sets and reports the name for the corresponding output card + /// + public uint OutputNames { get; set; } + /// + /// Range reports the name of the current video source for the corresponding output card + /// + public uint OutputCurrentVideoInputNames { get; set; } + /// + /// Range reports the current input resolution for each corresponding input card + /// + public uint InputCurrentResolution { get; set; } + #endregion + + public DmBladeChassisControllerJoinMap() { + //Digital/Analog + + //Digital + IsOnline = 11; + VideoSyncStatus = 100; //101-299 + InputEndpointOnline = 500; //501-699 + OutputEndpointOnline = 700; //701-899 + TxAdvancedIsPresent = 1000; //1001-1199 + + //Analog + OutputVideo = 100; //101-299 + HdcpSupportState = 1000; //1001-1199 + HdcpSupportCapability = 1200; //1201-1399 + + + //Serial + InputNames = 100; //101-299 + OutputNames = 300; //301-499 + OutputCurrentVideoInputNames = 2000; //2001-2199 + InputCurrentResolution = 2400; // 2401-2599 + } + + public override void OffsetJoinNumbers(uint joinStart) { + var joinOffset = joinStart - 1; + + IsOnline = IsOnline + joinOffset; + OutputVideo = OutputVideo + joinOffset; + VideoSyncStatus = VideoSyncStatus + joinOffset; + InputNames = InputNames + joinOffset; + OutputNames = OutputNames + joinOffset; + OutputCurrentVideoInputNames = OutputCurrentVideoInputNames + joinOffset; + InputCurrentResolution = InputCurrentResolution + joinOffset; + InputEndpointOnline = InputEndpointOnline + joinOffset; + OutputEndpointOnline = OutputEndpointOnline + joinOffset; + HdcpSupportState = HdcpSupportState + joinOffset; + HdcpSupportCapability = HdcpSupportCapability + joinOffset; + } + } +} diff --git a/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs index ff6a42d9..2e1b8394 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs @@ -7,6 +7,7 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class DmChassisControllerJoinMap : JoinMapBase { #region Digital/Analogs diff --git a/PepperDashEssentials/Bridges/JoinMaps/DmRmcControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/DmRmcControllerJoinMap.cs index 7aa8081a..7e1534bf 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/DmRmcControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/DmRmcControllerJoinMap.cs @@ -7,6 +7,7 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class DmRmcControllerJoinMap : JoinMapBase { #region Digitals diff --git a/PepperDashEssentials/Bridges/JoinMaps/DmTxControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/DmTxControllerJoinMap.cs index ff673cab..f84134a1 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/DmTxControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/DmTxControllerJoinMap.cs @@ -1,12 +1,9 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class DmTxControllerJoinMap : JoinMapBase { #region Digitals diff --git a/PepperDashEssentials/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs index faa30775..47c7d50d 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs @@ -7,6 +7,7 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class DmpsAudioOutputControllerJoinMap : JoinMapBase { #region Digital/Analog diff --git a/PepperDashEssentials/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs index ba3a8cd0..308dddf0 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs @@ -7,6 +7,7 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class DmpsRoutingControllerJoinMap : JoinMapBase { #region Digitals diff --git a/PepperDashEssentials/Bridges/JoinMaps/GenericLightingJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/GenericLightingJoinMap.cs index df5606d0..3bc9b19a 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/GenericLightingJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/GenericLightingJoinMap.cs @@ -9,6 +9,7 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class GenericLightingJoinMap : JoinMapBase { public uint IsOnline { get; set; } diff --git a/PepperDashEssentials/Bridges/JoinMaps/GenericRelayControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/GenericRelayControllerJoinMap.cs index 5c91a358..56b50724 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/GenericRelayControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/GenericRelayControllerJoinMap.cs @@ -7,6 +7,7 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class GenericRelayControllerJoinMap : JoinMapBase { #region Digitals diff --git a/PepperDashEssentials/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs index 6e19dff2..800f516c 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs @@ -1,238 +1,239 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using PepperDash.Essentials.Core; - -namespace PepperDash.Essentials.Bridges -{ - public class GlsOccupancySensorBaseJoinMap : JoinMapBase - { - #region Digitals - - /// - /// High when device is online - /// - public uint IsOnline { get; set; } - /// - /// Forces the device to report occupied status - /// - public uint ForceOccupied { get; set; } - /// - /// Forces the device to report vacant status - /// - public uint ForceVacant { get; set; } - /// - /// Enables raw status reporting - /// - public uint EnableRawStates { get; set; } - /// - /// High when raw occupancy is detected - /// - public uint RawOccupancyFeedback { get; set; } - /// - /// High when PIR sensor detects motion - /// - public uint RawOccupancyPirFeedback { get; set; } - /// - /// High when US sensor detects motion - /// - public uint RawOccupancyUsFeedback { get; set; } - /// - /// High when occupancy is detected - /// - public uint RoomOccupiedFeedback { get; set; } - /// - /// Hich when occupancy is detected in the grace period - /// - public uint GraceOccupancyDetectedFeedback { get; set; } - /// - /// High when vacancy is detected - /// - public uint RoomVacantFeedback { get; set; } - - /// - /// Enables the LED Flash when set high - /// - public uint EnableLedFlash { get; set; } - /// - /// Disables the LED flash when set high - /// - public uint DisableLedFlash { get; set; } - /// - /// Enables the Short Timeout - /// - public uint EnableShortTimeout { get; set; } - /// - /// Disables the Short Timout - /// - public uint DisableShortTimeout { get; set; } - /// - /// Set high to enable one technology to trigger occupancy - /// - public uint OrWhenVacated { get; set; } - /// - /// Set high to require both technologies to trigger occupancy - /// - public uint AndWhenVacated { get; set; } - /// - /// Enables Ultrasonic Sensor A - /// - public uint EnableUsA { get; set; } - /// - /// Disables Ultrasonic Sensor A - /// - public uint DisableUsA { get; set; } - /// - /// Enables Ultrasonic Sensor B - /// - public uint EnableUsB { get; set; } - /// - /// Disables Ultrasonic Sensor B - /// - public uint DisableUsB { get; set; } - /// - /// Enables Pir - /// - public uint EnablePir { get; set; } - /// - /// Disables Pir - /// - public uint DisablePir { get; set; } - public uint IncrementUsInOccupiedState { get; set; } - public uint DecrementUsInOccupiedState { get; set; } - public uint IncrementUsInVacantState { get; set; } - public uint DecrementUsInVacantState { get; set; } - public uint IncrementPirInOccupiedState { get; set; } - public uint DecrementPirInOccupiedState { get; set; } - public uint IncrementPirInVacantState { get; set; } - public uint DecrementPirInVacantState { get; set; } - #endregion - - #region Analogs - /// - /// Sets adn reports the remote timeout value - /// - public uint Timeout { get; set; } - /// - /// Reports the local timeout value - /// - public uint TimeoutLocalFeedback { get; set; } - /// - /// Sets the minimum internal photo sensor value and reports the current level - /// - public uint InternalPhotoSensorValue { get; set; } - /// - /// Sets the minimum external photo sensor value and reports the current level - /// - public uint ExternalPhotoSensorValue { get; set; } - - public uint UsSensitivityInOccupiedState { get; set; } - - public uint UsSensitivityInVacantState { get; set; } - - public uint PirSensitivityInOccupiedState { get; set; } - - public uint PirSensitivityInVacantState { get; set; } - #endregion - - #region Serial - public uint Name { get; set; } - #endregion - - public GlsOccupancySensorBaseJoinMap() - { - IsOnline = 1; - ForceOccupied = 2; - ForceVacant = 3; - EnableRawStates = 4; - RoomOccupiedFeedback = 2; - GraceOccupancyDetectedFeedback = 3; - RoomVacantFeedback = 4; - RawOccupancyFeedback = 5; - RawOccupancyPirFeedback = 6; - RawOccupancyUsFeedback = 7; - EnableLedFlash = 11; - DisableLedFlash = 12; - EnableShortTimeout = 13; - DisableShortTimeout = 14; - OrWhenVacated = 15; - AndWhenVacated = 16; - EnableUsA = 17; - DisableUsA = 18; - EnableUsB = 19; - DisableUsB = 20; - EnablePir = 21; - DisablePir = 22; - IncrementUsInOccupiedState = 23; - DecrementUsInOccupiedState = 24; - IncrementUsInVacantState = 25; - DecrementUsInVacantState = 26; - IncrementPirInOccupiedState = 27; - DecrementPirInOccupiedState = 28; - IncrementPirInVacantState = 29; - DecrementPirInVacantState = 30; - - Timeout = 1; - TimeoutLocalFeedback = 2; - InternalPhotoSensorValue = 3; - ExternalPhotoSensorValue = 4; - UsSensitivityInOccupiedState = 5; - UsSensitivityInVacantState = 6; - PirSensitivityInOccupiedState = 7; - PirSensitivityInVacantState = 8; - - Name = 1; - - } - - public override void OffsetJoinNumbers(uint joinStart) - { - var joinOffset = joinStart - 1; - - IsOnline = IsOnline + joinOffset; - ForceOccupied = ForceOccupied + joinOffset; - ForceVacant = ForceVacant + joinOffset; - EnableRawStates = EnableRawStates + joinOffset; - RoomOccupiedFeedback = RoomOccupiedFeedback + joinOffset; - GraceOccupancyDetectedFeedback = GraceOccupancyDetectedFeedback + joinOffset; - RoomVacantFeedback = RoomVacantFeedback + joinOffset; - RawOccupancyFeedback = RawOccupancyFeedback + joinOffset; - RawOccupancyPirFeedback = RawOccupancyPirFeedback + joinOffset; - RawOccupancyUsFeedback = RawOccupancyUsFeedback + joinOffset; - EnableLedFlash = EnableLedFlash + joinOffset; - DisableLedFlash = DisableLedFlash + joinOffset; - EnableShortTimeout = EnableShortTimeout + joinOffset; - DisableShortTimeout = DisableShortTimeout + joinOffset; - OrWhenVacated = OrWhenVacated + joinOffset; - AndWhenVacated = AndWhenVacated + joinOffset; - EnableUsA = EnableUsA + joinOffset; - DisableUsA = DisableUsA + joinOffset; - EnableUsB = EnableUsB + joinOffset; - DisableUsB = DisableUsB + joinOffset; - EnablePir = EnablePir + joinOffset; - DisablePir = DisablePir + joinOffset; - IncrementUsInOccupiedState = IncrementUsInOccupiedState + joinOffset; - DecrementUsInOccupiedState = DecrementUsInOccupiedState + joinOffset; - IncrementUsInVacantState = IncrementUsInVacantState + joinOffset; - DecrementUsInVacantState = DecrementUsInVacantState + joinOffset; - IncrementPirInOccupiedState = IncrementPirInOccupiedState + joinOffset; - DecrementPirInOccupiedState = DecrementPirInOccupiedState + joinOffset; - IncrementPirInVacantState = IncrementPirInVacantState + joinOffset; - DecrementPirInVacantState = DecrementPirInVacantState + joinOffset; - - Timeout = Timeout + joinOffset; - TimeoutLocalFeedback = TimeoutLocalFeedback + joinOffset; - InternalPhotoSensorValue = InternalPhotoSensorValue + joinOffset; - ExternalPhotoSensorValue = ExternalPhotoSensorValue + joinOffset; - UsSensitivityInOccupiedState = UsSensitivityInOccupiedState + joinOffset; - UsSensitivityInVacantState = UsSensitivityInVacantState + joinOffset; - PirSensitivityInOccupiedState = PirSensitivityInOccupiedState + joinOffset; - PirSensitivityInVacantState = PirSensitivityInVacantState + joinOffset; - - Name = Name + joinOffset; - } - } - -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Bridges +{ + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] + public class GlsOccupancySensorBaseJoinMap : JoinMapBase + { + #region Digitals + + /// + /// High when device is online + /// + public uint IsOnline { get; set; } + /// + /// Forces the device to report occupied status + /// + public uint ForceOccupied { get; set; } + /// + /// Forces the device to report vacant status + /// + public uint ForceVacant { get; set; } + /// + /// Enables raw status reporting + /// + public uint EnableRawStates { get; set; } + /// + /// High when raw occupancy is detected + /// + public uint RawOccupancyFeedback { get; set; } + /// + /// High when PIR sensor detects motion + /// + public uint RawOccupancyPirFeedback { get; set; } + /// + /// High when US sensor detects motion + /// + public uint RawOccupancyUsFeedback { get; set; } + /// + /// High when occupancy is detected + /// + public uint RoomOccupiedFeedback { get; set; } + /// + /// Hich when occupancy is detected in the grace period + /// + public uint GraceOccupancyDetectedFeedback { get; set; } + /// + /// High when vacancy is detected + /// + public uint RoomVacantFeedback { get; set; } + + /// + /// Enables the LED Flash when set high + /// + public uint EnableLedFlash { get; set; } + /// + /// Disables the LED flash when set high + /// + public uint DisableLedFlash { get; set; } + /// + /// Enables the Short Timeout + /// + public uint EnableShortTimeout { get; set; } + /// + /// Disables the Short Timout + /// + public uint DisableShortTimeout { get; set; } + /// + /// Set high to enable one technology to trigger occupancy + /// + public uint OrWhenVacated { get; set; } + /// + /// Set high to require both technologies to trigger occupancy + /// + public uint AndWhenVacated { get; set; } + /// + /// Enables Ultrasonic Sensor A + /// + public uint EnableUsA { get; set; } + /// + /// Disables Ultrasonic Sensor A + /// + public uint DisableUsA { get; set; } + /// + /// Enables Ultrasonic Sensor B + /// + public uint EnableUsB { get; set; } + /// + /// Disables Ultrasonic Sensor B + /// + public uint DisableUsB { get; set; } + /// + /// Enables Pir + /// + public uint EnablePir { get; set; } + /// + /// Disables Pir + /// + public uint DisablePir { get; set; } + public uint IncrementUsInOccupiedState { get; set; } + public uint DecrementUsInOccupiedState { get; set; } + public uint IncrementUsInVacantState { get; set; } + public uint DecrementUsInVacantState { get; set; } + public uint IncrementPirInOccupiedState { get; set; } + public uint DecrementPirInOccupiedState { get; set; } + public uint IncrementPirInVacantState { get; set; } + public uint DecrementPirInVacantState { get; set; } + #endregion + + #region Analogs + /// + /// Sets adn reports the remote timeout value + /// + public uint Timeout { get; set; } + /// + /// Reports the local timeout value + /// + public uint TimeoutLocalFeedback { get; set; } + /// + /// Sets the minimum internal photo sensor value and reports the current level + /// + public uint InternalPhotoSensorValue { get; set; } + /// + /// Sets the minimum external photo sensor value and reports the current level + /// + public uint ExternalPhotoSensorValue { get; set; } + + public uint UsSensitivityInOccupiedState { get; set; } + + public uint UsSensitivityInVacantState { get; set; } + + public uint PirSensitivityInOccupiedState { get; set; } + + public uint PirSensitivityInVacantState { get; set; } + #endregion + + #region Serial + public uint Name { get; set; } + #endregion + + public GlsOccupancySensorBaseJoinMap() + { + IsOnline = 1; + ForceOccupied = 2; + ForceVacant = 3; + EnableRawStates = 4; + RoomOccupiedFeedback = 2; + GraceOccupancyDetectedFeedback = 3; + RoomVacantFeedback = 4; + RawOccupancyFeedback = 5; + RawOccupancyPirFeedback = 6; + RawOccupancyUsFeedback = 7; + EnableLedFlash = 11; + DisableLedFlash = 12; + EnableShortTimeout = 13; + DisableShortTimeout = 14; + OrWhenVacated = 15; + AndWhenVacated = 16; + EnableUsA = 17; + DisableUsA = 18; + EnableUsB = 19; + DisableUsB = 20; + EnablePir = 21; + DisablePir = 22; + IncrementUsInOccupiedState = 23; + DecrementUsInOccupiedState = 24; + IncrementUsInVacantState = 25; + DecrementUsInVacantState = 26; + IncrementPirInOccupiedState = 27; + DecrementPirInOccupiedState = 28; + IncrementPirInVacantState = 29; + DecrementPirInVacantState = 30; + + Timeout = 1; + TimeoutLocalFeedback = 2; + InternalPhotoSensorValue = 3; + ExternalPhotoSensorValue = 4; + UsSensitivityInOccupiedState = 5; + UsSensitivityInVacantState = 6; + PirSensitivityInOccupiedState = 7; + PirSensitivityInVacantState = 8; + + Name = 1; + + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + IsOnline = IsOnline + joinOffset; + ForceOccupied = ForceOccupied + joinOffset; + ForceVacant = ForceVacant + joinOffset; + EnableRawStates = EnableRawStates + joinOffset; + RoomOccupiedFeedback = RoomOccupiedFeedback + joinOffset; + GraceOccupancyDetectedFeedback = GraceOccupancyDetectedFeedback + joinOffset; + RoomVacantFeedback = RoomVacantFeedback + joinOffset; + RawOccupancyFeedback = RawOccupancyFeedback + joinOffset; + RawOccupancyPirFeedback = RawOccupancyPirFeedback + joinOffset; + RawOccupancyUsFeedback = RawOccupancyUsFeedback + joinOffset; + EnableLedFlash = EnableLedFlash + joinOffset; + DisableLedFlash = DisableLedFlash + joinOffset; + EnableShortTimeout = EnableShortTimeout + joinOffset; + DisableShortTimeout = DisableShortTimeout + joinOffset; + OrWhenVacated = OrWhenVacated + joinOffset; + AndWhenVacated = AndWhenVacated + joinOffset; + EnableUsA = EnableUsA + joinOffset; + DisableUsA = DisableUsA + joinOffset; + EnableUsB = EnableUsB + joinOffset; + DisableUsB = DisableUsB + joinOffset; + EnablePir = EnablePir + joinOffset; + DisablePir = DisablePir + joinOffset; + IncrementUsInOccupiedState = IncrementUsInOccupiedState + joinOffset; + DecrementUsInOccupiedState = DecrementUsInOccupiedState + joinOffset; + IncrementUsInVacantState = IncrementUsInVacantState + joinOffset; + DecrementUsInVacantState = DecrementUsInVacantState + joinOffset; + IncrementPirInOccupiedState = IncrementPirInOccupiedState + joinOffset; + DecrementPirInOccupiedState = DecrementPirInOccupiedState + joinOffset; + IncrementPirInVacantState = IncrementPirInVacantState + joinOffset; + DecrementPirInVacantState = DecrementPirInVacantState + joinOffset; + + Timeout = Timeout + joinOffset; + TimeoutLocalFeedback = TimeoutLocalFeedback + joinOffset; + InternalPhotoSensorValue = InternalPhotoSensorValue + joinOffset; + ExternalPhotoSensorValue = ExternalPhotoSensorValue + joinOffset; + UsSensitivityInOccupiedState = UsSensitivityInOccupiedState + joinOffset; + UsSensitivityInVacantState = UsSensitivityInVacantState + joinOffset; + PirSensitivityInOccupiedState = PirSensitivityInOccupiedState + joinOffset; + PirSensitivityInVacantState = PirSensitivityInVacantState + joinOffset; + + Name = Name + joinOffset; + } + } + +} diff --git a/PepperDashEssentials/Bridges/JoinMaps/HdMdxxxCEControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/HdMdxxxCEControllerJoinMap.cs index e88980fe..d9fad27e 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/HdMdxxxCEControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/HdMdxxxCEControllerJoinMap.cs @@ -7,6 +7,7 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class HdMdxxxCEControllerJoinMap : JoinMapBase { #region Digitals diff --git a/PepperDashEssentials/Bridges/JoinMaps/IBasicCommunicationJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/IBasicCommunicationJoinMap.cs index 953bae37..c8939ef8 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/IBasicCommunicationJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/IBasicCommunicationJoinMap.cs @@ -7,6 +7,7 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class IBasicCommunicationJoinMap : JoinMapBase { #region Digitals diff --git a/PepperDashEssentials/Bridges/JoinMaps/IDigitalInputJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/IDigitalInputJoinMap.cs index 65d4ada4..a4c4aaa9 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/IDigitalInputJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/IDigitalInputJoinMap.cs @@ -7,6 +7,7 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class IDigitalInputJoinMap : JoinMapBase { #region Digitals diff --git a/PepperDashEssentials/Bridges/JoinMaps/SetTopBoxControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/SetTopBoxControllerJoinMap.cs index aa23cb7a..20b0d9a9 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/SetTopBoxControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/SetTopBoxControllerJoinMap.cs @@ -1,212 +1,213 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using PepperDash.Essentials.Core; -using Crestron.SimplSharp.Reflection; - - -namespace PepperDash.Essentials.Bridges -{ - public class SetTopBoxControllerJoinMap : JoinMapBase - { - #region Digitals - public uint DvrList { get; set; } // - public uint Replay { get; set; } - public uint Up { get; set; } // - public uint Down { get; set; } // - public uint Left { get; set; } // - public uint Right { get; set; } // - public uint Select { get; set; } // - public uint Menu { get; set; } // - public uint Exit { get; set; } // - public uint Digit0 { get; set; } // - public uint Digit1 { get; set; } // - public uint Digit2 { get; set; } // - public uint Digit3 { get; set; } // - public uint Digit4 { get; set; } // - public uint Digit5 { get; set; } // - public uint Digit6 { get; set; } // - public uint Digit7 { get; set; } // - public uint Digit8 { get; set; } // - public uint Digit9 { get; set; } // - public uint Dash { get; set; } // - public uint KeypadEnter { get; set; } // - public uint ChannelUp { get; set; } // - public uint ChannelDown { get; set; } // - public uint LastChannel { get; set; } // - public uint Guide { get; set; } // - public uint Info { get; set; } // - public uint Red { get; set; } // - public uint Green { get; set; } // - public uint Yellow { get; set; } // - public uint Blue { get; set; } // - public uint ChapMinus { get; set; } - public uint ChapPlus { get; set; } - public uint FFwd { get; set; } // - public uint Pause { get; set; } // - public uint Play { get; set; } // - public uint Record { get; set; } - public uint Rewind { get; set; } // - public uint Stop { get; set; } // - - public uint PowerOn { get; set; } // - public uint PowerOff { get; set; } // - public uint PowerToggle { get; set; } // - - public uint HasKeypadAccessoryButton1 { get; set; } - public uint HasKeypadAccessoryButton2 { get; set; } - - public uint KeypadAccessoryButton1Press { get; set; } - public uint KeypadAccessoryButton2Press { get; set; } - - - public uint HasDvr { get; set; } - public uint HasPresets { get; set; } - public uint HasNumeric { get; set; } - public uint HasDpad { get; set; } - - - #endregion - - #region Analogs - - #endregion - - #region Strings - public uint Name { get; set; } - public uint LoadPresets { get; set; } - public uint KeypadAccessoryButton1Label { get; set; } - public uint KeypadAccessoryButton2Label { get; set; } - - #endregion - - public SetTopBoxControllerJoinMap() - { - PowerOn = 1; - PowerOff = 2; - PowerToggle = 3; - - HasDpad = 4; - Up = 4; - Down = 5; - Left = 6; - Right = 7; - Select = 8; - Menu = 9; - Exit = 10; - - HasNumeric = 11; - Digit0 = 11; - Digit1 = 12; - Digit2 = 13; - Digit3 = 14; - Digit4 = 15; - Digit5 = 16; - Digit6 = 17; - Digit7 = 18; - Digit8 = 19; - Digit9 = 20; - Dash = 21; - KeypadEnter = 22; - ChannelUp = 23; - ChannelDown = 24; - LastChannel = 25; - - Guide = 26; - Info = 27; - Red = 28; - Green = 29; - Yellow = 30; - Blue = 31; - - HasDvr = 32; - DvrList = 32; - Play = 33; - Pause = 34; - Stop = 35; - FFwd = 36; - Rewind = 37; - ChapPlus = 38; - ChapMinus = 39; - Replay = 40; - Record = 41; - HasKeypadAccessoryButton1 = 42; - KeypadAccessoryButton1Press = 42; - HasKeypadAccessoryButton2 = 43; - KeypadAccessoryButton2Press = 43; - - Name = 1; - KeypadAccessoryButton1Label = 42; - KeypadAccessoryButton2Label = 43; - - LoadPresets = 50; - } - - public override void OffsetJoinNumbers(uint joinStart) - { - var joinOffset = joinStart - 1; - - PowerOn += joinOffset; - PowerOff += joinOffset; - PowerToggle += joinOffset; - - HasDpad += joinOffset; - Up += joinOffset; - Down += joinOffset; - Left += joinOffset; - Right += joinOffset; - Select += joinOffset; - Menu += joinOffset; - Exit += joinOffset; - - HasNumeric += joinOffset; - Digit0 += joinOffset; - Digit1 += joinOffset; - Digit2 += joinOffset; - Digit3 += joinOffset; - Digit4 += joinOffset; - Digit5 += joinOffset; - Digit6 += joinOffset; - Digit7 += joinOffset; - Digit8 += joinOffset; - Digit9 += joinOffset; - Dash += joinOffset; - KeypadEnter += joinOffset; - ChannelUp += joinOffset; - ChannelDown += joinOffset; - LastChannel += joinOffset; - - Guide += joinOffset; - Info += joinOffset; - Red += joinOffset; - Green += joinOffset; - Yellow += joinOffset; - Blue += joinOffset; - - HasDvr += joinOffset; - DvrList += joinOffset; - Play += joinOffset; - Pause += joinOffset; - Stop += joinOffset; - FFwd += joinOffset; - Rewind += joinOffset; - ChapPlus += joinOffset; - ChapMinus += joinOffset; - Replay += joinOffset; - Record += joinOffset; - HasKeypadAccessoryButton1 += joinOffset; - KeypadAccessoryButton1Press += joinOffset; - HasKeypadAccessoryButton2 += joinOffset; - KeypadAccessoryButton2Press += joinOffset; - - Name += joinOffset; - KeypadAccessoryButton1Label += joinOffset; - KeypadAccessoryButton2Label += joinOffset; - - LoadPresets += joinOffset; - } - - } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; +using Crestron.SimplSharp.Reflection; + + +namespace PepperDash.Essentials.Bridges +{ + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] + public class SetTopBoxControllerJoinMap : JoinMapBase + { + #region Digitals + public uint DvrList { get; set; } // + public uint Replay { get; set; } + public uint Up { get; set; } // + public uint Down { get; set; } // + public uint Left { get; set; } // + public uint Right { get; set; } // + public uint Select { get; set; } // + public uint Menu { get; set; } // + public uint Exit { get; set; } // + public uint Digit0 { get; set; } // + public uint Digit1 { get; set; } // + public uint Digit2 { get; set; } // + public uint Digit3 { get; set; } // + public uint Digit4 { get; set; } // + public uint Digit5 { get; set; } // + public uint Digit6 { get; set; } // + public uint Digit7 { get; set; } // + public uint Digit8 { get; set; } // + public uint Digit9 { get; set; } // + public uint Dash { get; set; } // + public uint KeypadEnter { get; set; } // + public uint ChannelUp { get; set; } // + public uint ChannelDown { get; set; } // + public uint LastChannel { get; set; } // + public uint Guide { get; set; } // + public uint Info { get; set; } // + public uint Red { get; set; } // + public uint Green { get; set; } // + public uint Yellow { get; set; } // + public uint Blue { get; set; } // + public uint ChapMinus { get; set; } + public uint ChapPlus { get; set; } + public uint FFwd { get; set; } // + public uint Pause { get; set; } // + public uint Play { get; set; } // + public uint Record { get; set; } + public uint Rewind { get; set; } // + public uint Stop { get; set; } // + + public uint PowerOn { get; set; } // + public uint PowerOff { get; set; } // + public uint PowerToggle { get; set; } // + + public uint HasKeypadAccessoryButton1 { get; set; } + public uint HasKeypadAccessoryButton2 { get; set; } + + public uint KeypadAccessoryButton1Press { get; set; } + public uint KeypadAccessoryButton2Press { get; set; } + + + public uint HasDvr { get; set; } + public uint HasPresets { get; set; } + public uint HasNumeric { get; set; } + public uint HasDpad { get; set; } + + + #endregion + + #region Analogs + + #endregion + + #region Strings + public uint Name { get; set; } + public uint LoadPresets { get; set; } + public uint KeypadAccessoryButton1Label { get; set; } + public uint KeypadAccessoryButton2Label { get; set; } + + #endregion + + public SetTopBoxControllerJoinMap() + { + PowerOn = 1; + PowerOff = 2; + PowerToggle = 3; + + HasDpad = 4; + Up = 4; + Down = 5; + Left = 6; + Right = 7; + Select = 8; + Menu = 9; + Exit = 10; + + HasNumeric = 11; + Digit0 = 11; + Digit1 = 12; + Digit2 = 13; + Digit3 = 14; + Digit4 = 15; + Digit5 = 16; + Digit6 = 17; + Digit7 = 18; + Digit8 = 19; + Digit9 = 20; + Dash = 21; + KeypadEnter = 22; + ChannelUp = 23; + ChannelDown = 24; + LastChannel = 25; + + Guide = 26; + Info = 27; + Red = 28; + Green = 29; + Yellow = 30; + Blue = 31; + + HasDvr = 32; + DvrList = 32; + Play = 33; + Pause = 34; + Stop = 35; + FFwd = 36; + Rewind = 37; + ChapPlus = 38; + ChapMinus = 39; + Replay = 40; + Record = 41; + HasKeypadAccessoryButton1 = 42; + KeypadAccessoryButton1Press = 42; + HasKeypadAccessoryButton2 = 43; + KeypadAccessoryButton2Press = 43; + + Name = 1; + KeypadAccessoryButton1Label = 42; + KeypadAccessoryButton2Label = 43; + + LoadPresets = 50; + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + PowerOn += joinOffset; + PowerOff += joinOffset; + PowerToggle += joinOffset; + + HasDpad += joinOffset; + Up += joinOffset; + Down += joinOffset; + Left += joinOffset; + Right += joinOffset; + Select += joinOffset; + Menu += joinOffset; + Exit += joinOffset; + + HasNumeric += joinOffset; + Digit0 += joinOffset; + Digit1 += joinOffset; + Digit2 += joinOffset; + Digit3 += joinOffset; + Digit4 += joinOffset; + Digit5 += joinOffset; + Digit6 += joinOffset; + Digit7 += joinOffset; + Digit8 += joinOffset; + Digit9 += joinOffset; + Dash += joinOffset; + KeypadEnter += joinOffset; + ChannelUp += joinOffset; + ChannelDown += joinOffset; + LastChannel += joinOffset; + + Guide += joinOffset; + Info += joinOffset; + Red += joinOffset; + Green += joinOffset; + Yellow += joinOffset; + Blue += joinOffset; + + HasDvr += joinOffset; + DvrList += joinOffset; + Play += joinOffset; + Pause += joinOffset; + Stop += joinOffset; + FFwd += joinOffset; + Rewind += joinOffset; + ChapPlus += joinOffset; + ChapMinus += joinOffset; + Replay += joinOffset; + Record += joinOffset; + HasKeypadAccessoryButton1 += joinOffset; + KeypadAccessoryButton1Press += joinOffset; + HasKeypadAccessoryButton2 += joinOffset; + KeypadAccessoryButton2Press += joinOffset; + + Name += joinOffset; + KeypadAccessoryButton1Label += joinOffset; + KeypadAccessoryButton2Label += joinOffset; + + LoadPresets += joinOffset; + } + + } } \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/JoinMaps/StatusSignControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/StatusSignControllerJoinMap.cs index d3a95383..3d8916a7 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/StatusSignControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/StatusSignControllerJoinMap.cs @@ -1,49 +1,51 @@ -using System.Linq; -using Crestron.SimplSharp.Reflection; -using PepperDash.Essentials.Core; - -namespace PepperDash.Essentials.Bridges -{ - public class StatusSignControllerJoinMap:JoinMapBase - { - public uint IsOnline { get; set; } - public uint Name { get; set; } - public uint RedLed { get; set; } - public uint GreenLed { get; set; } - public uint BlueLed { get; set; } - public uint RedControl { get; set; } - public uint GreenControl { get; set; } - public uint BlueControl { get; set; } - - public StatusSignControllerJoinMap() - { - //digital - IsOnline = 1; - RedControl = 2; - GreenControl = 3; - BlueControl = 4; - - //Analog - RedLed = 2; - GreenLed = 3; - BlueLed = 4; - - //string - Name = 1; - - - } - - public override void OffsetJoinNumbers(uint joinStart) - { - var joinOffset = joinStart - 1; - var properties = - GetType().GetCType().GetProperties().Where(p => p.PropertyType == typeof (uint)).ToList(); - - foreach (var propertyInfo in properties) - { - propertyInfo.SetValue(this, (uint) propertyInfo.GetValue(this, null) + joinOffset, null); - } - } - } +using System; +using System.Linq; +using Crestron.SimplSharp.Reflection; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Bridges +{ + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] + public class StatusSignControllerJoinMap:JoinMapBase + { + public uint IsOnline { get; set; } + public uint Name { get; set; } + public uint RedLed { get; set; } + public uint GreenLed { get; set; } + public uint BlueLed { get; set; } + public uint RedControl { get; set; } + public uint GreenControl { get; set; } + public uint BlueControl { get; set; } + + public StatusSignControllerJoinMap() + { + //digital + IsOnline = 1; + RedControl = 2; + GreenControl = 3; + BlueControl = 4; + + //Analog + RedLed = 2; + GreenLed = 3; + BlueLed = 4; + + //string + Name = 1; + + + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + var properties = + GetType().GetCType().GetProperties().Where(p => p.PropertyType == typeof (uint)).ToList(); + + foreach (var propertyInfo in properties) + { + propertyInfo.SetValue(this, (uint) propertyInfo.GetValue(this, null) + joinOffset, null); + } + } + } } \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/JoinMaps/SystemMonitorJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/SystemMonitorJoinMap.cs index 6358700f..fe59416a 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/SystemMonitorJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/SystemMonitorJoinMap.cs @@ -1,12 +1,9 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { + [Obsolete("Please use version PepperDash.Essentials.Core.Bridges")] public class SystemMonitorJoinMap : JoinMapBase { /// @@ -14,11 +11,21 @@ namespace PepperDash.Essentials.Bridges /// public uint ProgramStartJoin { get; set; } + /// + /// Offset to indicate where the range of iterated Ethernet joins will start + /// + public uint EthernetStartJoin { get; set; } + /// /// Offset between each program join set /// public uint ProgramOffsetJoin { get; set; } + /// + /// Offset between each Ethernet Interface join set + /// + public uint EthernetOffsetJoin { get; set; } + #region Digitals /// /// Range Sets and reports whether the corresponding program slot is started @@ -87,6 +94,68 @@ namespace PepperDash.Essentials.Bridges /// Serialized JSON output that aggregates the program info of the corresponding program /// public uint AggregatedProgramInfo { get; set; } + /// + /// Reports the controller serial number + /// + public uint SerialNumber { get; set; } + /// + /// Reports the controller model + /// + public uint Model { get; set; } + /// + /// Reports the Host name set on the corresponding interface + /// + public uint HostName { get; set; } + /// + /// Reports the Current IP address set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned address. + /// + public uint CurrentIpAddress { get; set; } + /// + /// Reporst the Current Default Gateway set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned gateway + /// + public uint CurrentDefaultGateway { get; set; } + /// + /// Reports the Current Subnet Mask set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned subnet mask + /// + public uint CurrentSubnetMask { get; set; } + /// + /// Reports the Static IP address set on the corresponding interface. If DHCP is disabled, this will match the Current IP address + /// + public uint StaticIpAddress { get; set; } + /// + /// Reporst the Static Default Gateway set on the corresponding interface. If DHCP is disabled, this will match the Current gateway + /// + public uint StaticDefaultGateway { get; set; } + /// + /// Reports the Current Subnet Mask set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned subnet mask + /// + public uint StaticSubnetMask { get; set; } + /// + /// Reports the current DomainFeedback on the corresponding interface + /// + public uint Domain { get; set; } + /// + /// Reports the current DNS Servers on the corresponding interface + /// + public uint DnsServer { get; set; } + /// + /// Reports the MAC Address of the corresponding interface + /// + public uint MacAddress { get; set; } + /// + /// Reports the DHCP Status of the corresponding interface + /// + public uint DhcpStatus { get; set; } + + /// + /// Reports the current uptime. Updated in 5 minute intervals. + /// + public uint Uptime { get; set; } + + /// + /// Reports the date of the last boot + /// + public uint LastBoot { get; set; } #endregion public SystemMonitorJoinMap() @@ -98,6 +167,10 @@ namespace PepperDash.Essentials.Bridges SnmpAppVersion = 3; BACnetAppVersion = 4; ControllerVersion = 5; + SerialNumber = 6; + Model = 7; + Uptime = 8; + LastBoot = 9; ProgramStartJoin = 10; @@ -115,6 +188,23 @@ namespace PepperDash.Essentials.Bridges ProgramCrestronDatabaseVersion = 3; ProgramEnvironmentVersion = 4; AggregatedProgramInfo = 5; + + EthernetStartJoin = 75; + + EthernetOffsetJoin = 15; + + // Offset in groups of 15 + HostName = 1; + CurrentIpAddress = 2; + CurrentSubnetMask = 3; + CurrentDefaultGateway = 4; + StaticIpAddress = 5; + StaticSubnetMask = 6; + StaticDefaultGateway = 7; + Domain = 8; + DnsServer = 9; + MacAddress = 10; + DhcpStatus = 11; } public override void OffsetJoinNumbers(uint joinStart) @@ -131,6 +221,7 @@ namespace PepperDash.Essentials.Bridges // Sets the initial join value where the iterated program joins will begin ProgramStartJoin = ProgramStartJoin + joinOffset; + EthernetStartJoin = EthernetStartJoin + joinOffset; } } } \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/StatusSignControllerBridge.cs b/PepperDashEssentials/Bridges/StatusSignControllerBridge.cs index df38ba26..0b35677d 100644 --- a/PepperDashEssentials/Bridges/StatusSignControllerBridge.cs +++ b/PepperDashEssentials/Bridges/StatusSignControllerBridge.cs @@ -4,7 +4,7 @@ using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.CrestronIO; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class StatusSignDeviceApiExtensions { @@ -13,7 +13,7 @@ namespace PepperDash.Essentials.Bridges { var joinMap = new StatusSignControllerJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); diff --git a/PepperDashEssentials/Bridges/SystemMonitorBridge.cs b/PepperDashEssentials/Bridges/SystemMonitorBridge.cs index 4e66ea08..5999c500 100644 --- a/PepperDashEssentials/Bridges/SystemMonitorBridge.cs +++ b/PepperDashEssentials/Bridges/SystemMonitorBridge.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.Diagnostics; using PepperDash.Core; using PepperDash.Essentials.Core; @@ -11,15 +6,15 @@ using PepperDash.Essentials.Core.Monitoring; using Newtonsoft.Json; -namespace PepperDash.Essentials.Bridges +namespace PepperDash.Essentials.Core.Bridges { public static class SystemMonitorBridge { public static void LinkToApi(this SystemMonitorController systemMonitorController, BasicTriList trilist, uint joinStart, string joinMapKey) { - SystemMonitorJoinMap joinMap = new SystemMonitorJoinMap(); + var joinMap = new SystemMonitorJoinMap(); - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if(!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); @@ -30,36 +25,71 @@ namespace PepperDash.Essentials.Bridges Debug.Console(2, systemMonitorController, "Linking API starting at join: {0}", joinStart); systemMonitorController.TimeZoneFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeZone]); - //trilist.SetUShortSigAction(joinMap.TimeZone, new Action(u => systemMonitorController.SetTimeZone(u))); systemMonitorController.TimeZoneTextFeedback.LinkInputSig(trilist.StringInput[joinMap.TimeZoneName]); - systemMonitorController.IOControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.IOControllerVersion]); + systemMonitorController.IoControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.IOControllerVersion]); systemMonitorController.SnmpVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.SnmpAppVersion]); - systemMonitorController.BACnetAppVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.BACnetAppVersion]); + systemMonitorController.BaCnetAppVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.BACnetAppVersion]); systemMonitorController.ControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.ControllerVersion]); + systemMonitorController.SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumber]); + systemMonitorController.ModelFeedback.LinkInputSig(trilist.StringInput[joinMap.Model]); + systemMonitorController.UptimeFeedback.LinkInputSig(trilist.StringInput[joinMap.Uptime]); + systemMonitorController.LastStartFeedback.LinkInputSig(trilist.StringInput[joinMap.LastBoot]); // iterate the program status feedback collection and map all the joins + LinkProgramInfoJoins(systemMonitorController, trilist, joinMap); + + LinkEthernetInfoJoins(systemMonitorController, trilist, joinMap); + } + + private static void LinkEthernetInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, SystemMonitorJoinMap joinMap) + { + var ethernetSlotJoinStart = joinMap.EthernetStartJoin; + + foreach (var fb in systemMonitorController.EthernetStatusFeedbackCollection) + { + fb.Value.CurrentIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentIpAddress]); + fb.Value.CurrentSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentSubnetMask]); + fb.Value.CurrentDefaultGatewayFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentDefaultGateway]); + fb.Value.StaticIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticIpAddress]); + fb.Value.StaticSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticSubnetMask]); + fb.Value.StaticDefaultGatewayFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticDefaultGateway]); + fb.Value.HostNameFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.HostName]); + fb.Value.MacAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.MacAddress]); + fb.Value.DomainFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.Domain]); + fb.Value.DnsServerFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DnsServer]); + fb.Value.DhcpStatusFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DhcpStatus]); + + ethernetSlotJoinStart += joinMap.EthernetOffsetJoin; + } + } + + private static void LinkProgramInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, + SystemMonitorJoinMap joinMap) + { var programSlotJoinStart = joinMap.ProgramStartJoin; foreach (var p in systemMonitorController.ProgramStatusFeedbackCollection) { var programNumber = p.Value.Program.Number; - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart, new Action - (b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Start)); + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart, + b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Start); p.Value.ProgramStartedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStart]); - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop, new Action - (b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Stop)); + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop, + b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Stop); p.Value.ProgramStoppedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStop]); - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister, new Action - (b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register)); - p.Value.ProgramRegisteredFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramRegister]); + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister, + b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register); + p.Value.ProgramRegisteredFeedback.LinkInputSig( + trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramRegister]); - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister, new Action - (b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister)); - p.Value.ProgramUnregisteredFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramUnregister]); + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister, + b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister); + p.Value.ProgramUnregisteredFeedback.LinkInputSig( + trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramUnregister]); p.Value.ProgramNameFeedback.LinkInputSig(trilist.StringInput[programSlotJoinStart + joinMap.ProgramName]); p.Value.ProgramCompileTimeFeedback.LinkInputSig( diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index e052f274..f0cdc9d5 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -10,6 +10,7 @@ using Crestron.SimplSharp.Reflection; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Devices.Common; using PepperDash.Essentials.DM; @@ -25,6 +26,7 @@ namespace PepperDash.Essentials { HttpLogoServer LogoServer; + public ControlSystem() : base() { @@ -46,7 +48,12 @@ namespace PepperDash.Essentials ConsoleAccessLevelEnum.AccessOperator); } - // CrestronConsole.AddNewConsoleCommand(S => { ConfigWriter.WriteConfigFile(null); }, "writeconfig", "writes the current config to a file", ConsoleAccessLevelEnum.AccessOperator); + CrestronConsole.AddNewConsoleCommand(PluginLoader.ReportAssemblyVersions, "reportversions", "Reports the versions of the loaded assemblies", ConsoleAccessLevelEnum.AccessOperator); + + CrestronConsole.AddNewConsoleCommand(PepperDash.Essentials.Core.DeviceFactory.GetDeviceFactoryTypes, "gettypes", "Gets the device types that can be built. Accepts a filter string.", ConsoleAccessLevelEnum.AccessOperator); + + CrestronConsole.AddNewConsoleCommand(BridgeHelper.PrintJoinMap, "getjoinmap", "map(s) for bridge or device on bridge [brKey [devKey]]", ConsoleAccessLevelEnum.AccessOperator); + CrestronConsole.AddNewConsoleCommand(s => { Debug.Console(0, Debug.ErrorLogLevel.Notice, "CONSOLE MESSAGE: {0}", s); @@ -74,6 +81,7 @@ namespace PepperDash.Essentials "Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl); }, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator); + if (!Debug.DoNotLoadOnNextBoot) GoWithLoad(); } @@ -81,7 +89,7 @@ namespace PepperDash.Essentials /// /// Determines if the program is running on a processor (appliance) or server (VC-4). /// - /// Sets Global.FilePathPrefix based on platform + /// Sets Global.FilePathPrefix and Global.ApplicationDirectoryPathPrefix based on platform /// public void DeterminePlatform() { @@ -108,7 +116,7 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", Global.AssemblyVersion); // Check if User/ProgramX exists - if (Directory.Exists(directoryPrefix + dirSeparator + "User" + if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + "User" + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber))) { Debug.Console(0, @"User/program{0} directory found", InitialParametersClass.ApplicationNumber); @@ -153,16 +161,23 @@ namespace PepperDash.Essentials public void GoWithLoad() { try - { + { Debug.SetDoNotLoadOnNextBoot(false); + PluginLoader.AddProgramAssemblies(); + + new Core.DeviceFactory(); + new Devices.Common.DeviceFactory(); + new DM.DeviceFactory(); + new DeviceFactory(); + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials load from configuration"); var filesReady = SetupFilesystem(); if (filesReady) { Debug.Console(0, Debug.ErrorLogLevel.Notice, "Checking for plugins"); - LoadPlugins(); + PluginLoader.LoadPlugins(); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Folder structure verified. Loading config..."); if (!ConfigReader.LoadConfig2()) @@ -197,118 +212,7 @@ namespace PepperDash.Essentials } - /// - /// Initial simple implementation. Reads user/programXX/plugins folder and - /// use - /// - void LoadPlugins() - { - var dir = Global.FilePathPrefix + "plugins"; - if (Directory.Exists(dir)) - { - // TODO Clear out or create localPlugins folder (maybe in program slot folder) - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Plugins directory found, checking for factory plugins"); - var di = new DirectoryInfo(dir); - var zFiles = di.GetFiles("*.cplz"); - foreach (var fi in zFiles) - { - Debug.Console(0, "Found cplz: {0}. Unzipping into plugins directory", fi.Name); - var result = CrestronZIP.Unzip(fi.FullName, di.FullName); - Debug.Console(0, "UnZip Result: {0}", result.ToString()); - fi.Delete(); - } - var files = di.GetFiles("*.dll"); - Dictionary assyList = new Dictionary(); - foreach (FileInfo fi in files) - { - // TODO COPY plugin to loadedPlugins folder - // TODO LOAD that loadedPlugins dll file - try - { - var assy = Assembly.LoadFrom(fi.FullName); - var ver = assy.GetName().Version; - var verStr = string.Format("{0}.{1}.{2}.{3}", ver.Major, ver.Minor, ver.Build, ver.Revision); - assyList.Add(fi.FullName, assy); - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loaded plugin file '{0}', version {1}", fi.FullName, verStr); - } - catch - { - Debug.Console(2, "Assembly {0} is not a custom assembly", fi.FullName); - continue; //catching any load issues and continuing. There will be exceptions loading Crestron .dlls from the cplz Probably should do something different here - } - } - foreach (var assy in assyList) - { - // iteratate this assembly's classes, looking for "LoadPlugin()" methods - try - { - var types = assy.Value.GetTypes(); - foreach (var type in types) - { - try - { - var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static); - var loadPlugin = methods.FirstOrDefault(m => m.Name.Equals("LoadPlugin")); - if (loadPlugin != null) - { - Debug.Console(2, "LoadPlugin method found in {0}", type.Name); - - var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static); - - var minimumVersion = fields.FirstOrDefault(p => p.Name.Equals("MinimumEssentialsFrameworkVersion")); - if (minimumVersion != null) - { - Debug.Console(2, "MinimumEssentialsFrameworkVersion found"); - - var minimumVersionString = minimumVersion.GetValue(null) as string; - - if (!string.IsNullOrEmpty(minimumVersionString)) - { - var passed = Global.IsRunningMinimumVersionOrHigher(minimumVersionString); - - if (!passed) - { - Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", minimumVersionString); - continue; - } - else - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Passed plugin passed dependency check (required version {0})", minimumVersionString); - } - } - else - { - Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion found but not set. Loading plugin, but your mileage may vary."); - } - } - else - { - Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion not found. Loading plugin, but your mileage may vary."); - } - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding plugin: {0}", assy.Key); - loadPlugin.Invoke(null, null); - } - } - catch - { - Debug.Console(2, "Load Plugin not found. {0} is not a plugin assembly", assy.Value.FullName); - continue; - } - - } - } - catch - { - Debug.Console(2, "Assembly {0} is not a custom assembly. Types cannot be loaded.", assy.Value.FullName); - continue; - } - } - // plugin dll will be loaded. Any classes in plugin should have a static constructor - // that registers that class with the Core.DeviceFactory - } - } + /// /// Verifies filesystem is set up. IR, SGD, and programX folders @@ -391,12 +295,10 @@ namespace PepperDash.Essentials /// public void LoadDevices() { + // Build the processor wrapper class - DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor")); - - // Add global System Monitor device DeviceManager.AddDevice(new PepperDash.Essentials.Core.Monitoring.SystemMonitorController("systemMonitor")); @@ -456,33 +358,15 @@ namespace PepperDash.Essentials } // Try local factories first - var newDev = DeviceFactory.GetDevice(devConf); + IKeyed newDev = null; - if (newDev == null) - newDev = BridgeFactory.GetDevice(devConf); - - // Then associated library factories if (newDev == null) newDev = PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf); - if (newDev == null) - newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf); - if (newDev == null) - newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf); - if (newDev == null) - newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf); - //if (newDev == null) // might want to consider the ability to override an essentials "type" - //{ - // // iterate plugin factories - // foreach (var f in FactoryObjects) - // { - // var cresFactory = f as IGetCrestronDevice; - // if (cresFactory != null) - // { - // newDev = cresFactory.GetDevice(devConf, this); - // } - // } - //} + // + //if (newDev == null) + // newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf); + // if (newDev != null) DeviceManager.AddDevice(newDev); diff --git a/PepperDashEssentials/Devices/Amplifier.cs b/PepperDashEssentials/Devices/Amplifier.cs index 20d8efa0..b2725109 100644 --- a/PepperDashEssentials/Devices/Amplifier.cs +++ b/PepperDashEssentials/Devices/Amplifier.cs @@ -6,11 +6,12 @@ using Crestron.SimplSharp; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Routing; namespace PepperDash.Essentials { - public class Amplifier : Device, IRoutingSinkNoSwitching + public class Amplifier : EssentialsDevice, IRoutingSinkNoSwitching { public event SourceInfoChangeHandler CurrentSourceChange; @@ -54,4 +55,18 @@ namespace PepperDash.Essentials #endregion } + + public class AmplifierFactory : EssentialsDeviceFactory + { + public AmplifierFactory() + { + TypeNames = new List() { "amplifier" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Amplifier Device"); + return new Amplifier(dc.Key, dc.Name); + } + } } \ No newline at end of file diff --git a/PepperDashEssentials/Factory/DeviceFactory.cs b/PepperDashEssentials/Factory/DeviceFactory.cs index 24c4bfe1..5b15f28c 100644 --- a/PepperDashEssentials/Factory/DeviceFactory.cs +++ b/PepperDashEssentials/Factory/DeviceFactory.cs @@ -4,94 +4,45 @@ using System.Linq; using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharpPro; +using Crestron.SimplSharp.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Room.MobileControl; namespace PepperDash.Essentials { - public class DeviceFactory - { - public static IKeyed GetDevice(DeviceConfig dc) - { - var key = dc.Key; - var name = dc.Name; - var type = dc.Type; - var properties = dc.Properties; + /// + /// Responsible for loading all of the device types for this library + /// + public class DeviceFactory + { - var typeName = dc.Type.ToLower(); + public DeviceFactory() + { + var assy = Assembly.GetExecutingAssembly(); + PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy); - if (typeName == "amplifier") + var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract); + + if (types != null) { - return new Amplifier(dc.Key, dc.Name); - } - else if (dc.Group.ToLower() == "touchpanel") // typeName.StartsWith("tsw")) - { - return UiDeviceFactory.GetUiDevice(dc); + foreach (var type in types) + { + try + { + var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); + factory.LoadTypeFactories(); + } + catch (Exception e) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name); + } + } } - - else if (typeName == "mockdisplay") - { - return new MockDisplay(key, name); - } - - else if (typeName == "generic") - { - return new Device(key, name); - } - - //// MOVE into something else??? - //else if (typeName == "basicirdisplay") - //{ - // var ir = IRPortHelper.GetIrPort(properties); - // if (ir != null) - // return new BasicIrDisplay(key, name, ir.Port, ir.FileName); - //} - - else if (typeName == "commmock") - { - var comm = CommFactory.CreateCommForDevice(dc); - var props = JsonConvert.DeserializeObject( - properties.ToString()); - return new ConsoleCommMockDevice(key, name, props, comm); - } - - else if (typeName == "appserver") - { - var props = JsonConvert.DeserializeObject(properties.ToString()); - return new MobileControlSystemController(key, name, props); - } - - else if (typeName == "mobilecontrolbridge-ddvc01") - { - var comm = CommFactory.GetControlPropertiesConfig(dc); - - var bridge = new PepperDash.Essentials.Room.MobileControl.MobileControlDdvc01RoomBridge(key, name, comm.IpIdInt); - bridge.AddPreActivationAction(() => - { - var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as MobileControlSystemController; - if (parent == null) - { - Debug.Console(0, bridge, "ERROR: Cannot connect bridge. System controller not present"); - } - Debug.Console(0, bridge, "Linking to parent controller"); - bridge.AddParent(parent); - parent.AddBridge(bridge); - }); - - return bridge; - } - - else if (typeName == "roomonwhenoccupancydetectedfeature") - { - return new RoomOnToDefaultSourceWhenOccupied(dc); - } - - return null; - } - } - + } + } } diff --git a/PepperDashEssentials/Factory/UiDeviceFactory.cs b/PepperDashEssentials/Factory/UiDeviceFactory.cs deleted file mode 100644 index 6176b6d1..00000000 --- a/PepperDashEssentials/Factory/UiDeviceFactory.cs +++ /dev/null @@ -1,191 +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 Crestron.SimplSharpPro.UI; - -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; -using PepperDash.Essentials.Core.PageManagers; -using PepperDash.Essentials.DM.Endpoints.DGEs; - - -namespace PepperDash.Essentials -{ - public class UiDeviceFactory - { - public static IKeyed GetUiDevice(DeviceConfig config) - { - var comm = CommFactory.GetControlPropertiesConfig(config); - - var typeName = config.Type.ToLower(); - - EssentialsTouchpanelController panelController = null; - - var props = JsonConvert.DeserializeObject(config.Properties.ToString()); - - if (typeName.Contains("dge")) - { - Dge100 dgeDevice = null; - if (typeName == "dge100") - dgeDevice = new Dge100(comm.IpIdInt, Global.ControlSystem); - else if (typeName == "dmdge200c") - dgeDevice = new DmDge200C(comm.IpIdInt, Global.ControlSystem); - - if (dgeDevice == null) - { - Debug.Console(1, "Unable to create DGE device"); - return null; - } - - var dgeController = new DgeController(config.Key + "-comPorts", config.Name, dgeDevice, config, props); - - DeviceManager.AddDevice(dgeController); - - panelController = new EssentialsTouchpanelController(config.Key, config.Name, dgeController.DigitalGraphicsEngine, - props.ProjectName, props.SgdFile); - } - else - { - panelController = new EssentialsTouchpanelController(config.Key, config.Name, config.Type, props, comm.IpIdInt); - } - - panelController.AddPostActivationAction(() => - { - var mainDriver = new EssentialsPanelMainInterfaceDriver(panelController.Panel, props); - // Then the sub drivers - - // spin up different room drivers depending on room type - var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey); - if (room is EssentialsHuddleSpaceRoom) - { - - // Header Driver - Debug.Console(0, panelController, "Adding header driver"); - mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, props); - - // AV Driver - Debug.Console(0, panelController, "Adding huddle space AV driver"); - var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props); - avDriver.DefaultRoomKey = props.DefaultRoomKey; - mainDriver.AvDriver = avDriver; - avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom; - - // Environment Driver - if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0) - { - Debug.Console(0, panelController, "Adding environment driver"); - mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, props); - - mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment); - } - - mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom); - - panelController.LoadAndShowDriver(mainDriver); // This is a little convoluted. - - if (panelController.Panel is TswFt5ButtonSystem) - { - var tsw = panelController.Panel as TswFt5ButtonSystem; - // Wire up hard keys - tsw.Power.UserObject = new Action(b => { if (!b) avDriver.PowerButtonPressed(); }); - //tsw.Home.UserObject = new Action(b => { if (!b) HomePressed(); }); - if(mainDriver.EnvironmentDriver != null) - tsw.Lights.UserObject = new Action(b => - { - if (!b) - { - //mainDriver.AvDriver.PopupInterlock.ShowInterlockedWithToggle(mainDriver.EnvironmentDriver.BackgroundSubpageJoin); - mainDriver.EnvironmentDriver.Toggle(); - } - }); - tsw.Up.UserObject = new Action(avDriver.VolumeUpPress); - tsw.Down.UserObject = new Action(avDriver.VolumeDownPress); - } - } - //else if (room is EssentialsPresentationRoom) - //{ - // Debug.Console(0, panelController, "Adding presentation room driver"); - // var avDriver = new EssentialsPresentationPanelAvFunctionsDriver(mainDriver, props); - // avDriver.CurrentRoom = room as EssentialsPresentationRoom; - // avDriver.DefaultRoomKey = props.DefaultRoomKey; - // mainDriver.AvDriver = avDriver ; - // mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, props); - // panelController.LoadAndShowDriver(mainDriver); - - // if (panelController.Panel is TswFt5ButtonSystem) - // { - // var tsw = panelController.Panel as TswFt5ButtonSystem; - // // Wire up hard keys - // tsw.Power.UserObject = new Action(b => { if (!b) avDriver.PowerButtonPressed(); }); - // //tsw.Home.UserObject = new Action(b => { if (!b) HomePressed(); }); - // tsw.Up.UserObject = new Action(avDriver.VolumeUpPress); - // tsw.Down.UserObject = new Action(avDriver.VolumeDownPress); - // } - //} - else if (room is EssentialsHuddleVtc1Room) - { - Debug.Console(0, panelController, "Adding huddle space VTC AV driver"); - - // Header Driver - mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, props); - - // AV Driver - var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, props); - - var codecDriver = new PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver(panelController.Panel, avDriver, - (room as EssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver); - avDriver.SetVideoCodecDriver(codecDriver); - avDriver.DefaultRoomKey = props.DefaultRoomKey; - mainDriver.AvDriver = avDriver; - avDriver.CurrentRoom = room as EssentialsHuddleVtc1Room; - - // Environment Driver - if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0) - { - Debug.Console(0, panelController, "Adding environment driver"); - mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, props); - - mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment); - } - - mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom); - - panelController.LoadAndShowDriver(mainDriver); // This is a little convoluted. - - if (panelController.Panel is TswFt5ButtonSystem) - { - var tsw = panelController.Panel as TswFt5ButtonSystem; - // Wire up hard keys - tsw.Power.UserObject = new Action(b => { if (!b) avDriver.EndMeetingPress(); }); - //tsw.Home.UserObject = new Action(b => { if (!b) HomePressed(); }); - if (mainDriver.EnvironmentDriver != null) - tsw.Lights.UserObject = new Action(b => - { - if (!b) - { - //mainDriver.AvDriver.PopupInterlock.ShowInterlockedWithToggle(mainDriver.EnvironmentDriver.BackgroundSubpageJoin); - mainDriver.EnvironmentDriver.Toggle(); - } - }); - tsw.Up.UserObject = new Action(avDriver.VolumeUpPress); - tsw.Down.UserObject = new Action(avDriver.VolumeDownPress); - } - } - else - { - Debug.Console(0, panelController, "ERROR: Cannot load AvFunctionsDriver for room '{0}'", props.DefaultRoomKey); - } - }); - - return panelController; - } - - } -} \ No newline at end of file diff --git a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs index 8ec55881..c6c85d1a 100644 --- a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs +++ b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs @@ -186,7 +186,7 @@ namespace PepperDash.Essentials.Fusion FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource); - FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff")); + FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey)); // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig); @@ -342,7 +342,7 @@ namespace PepperDash.Essentials.Fusion // Current Source var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig); - defaultDisplaySourceNone.OutputSig.UserObject = new Action(b => { if (!b) (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff"); }); ; + defaultDisplaySourceNone.OutputSig.UserObject = new Action(b => { if (!b) (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey); }); ; } } } diff --git a/PepperDashEssentials/HttpApiHandler.cs b/PepperDashEssentials/HttpApiHandler.cs deleted file mode 100644 index 0a757999..00000000 --- a/PepperDashEssentials/HttpApiHandler.cs +++ /dev/null @@ -1,266 +0,0 @@ -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.Text; -//using Crestron.SimplSharp; -//using Crestron.SimplSharp.CrestronIO; -//using Crestron.SimplSharp.Net.Http; - -//using Newtonsoft.Json; -//using Newtonsoft.Json.Linq; - -//using PepperDash.Essentials.Core; -//using PepperDash.Essentials.Core.Http; -//using PepperDash.Core; - -//namespace PepperDash.Essentials -//{ -// public class EssentialsHttpApiHandler -// { -// string ConfigPath; -// string PresetsPathPrefix; -// EssentialsHttpServer Server; - -// /// -// /// -// /// -// /// HTTP server to attach to -// /// The full path to configuration file -// /// The folder prefix for the presets path, eq "\HTML\presets\" -// public EssentialsHttpApiHandler(EssentialsHttpServer server, string configPath, string presetsPathPrefix) -// { -// if (server == null) throw new ArgumentNullException("server"); -// Server = server; -// ConfigPath = configPath; -// PresetsPathPrefix = presetsPathPrefix; -// server.ApiRequest += Server_ApiRequest; -// } - - -// void Server_ApiRequest(object sender, Crestron.SimplSharp.Net.Http.OnHttpRequestArgs args) -// { -// try -// { -// var path = args.Request.Path.ToLower(); - -// if (path == "/api/config") -// HandleApiConfig(args); -// else if (path.StartsWith("/api/presetslist/")) -// HandleApiPresetsList(args); -// else if (path == "/api/presetslists") -// HandleApiGetPresetsLists(args.Request, args.Response); -// else -// { -// args.Response.Code = 404; -// return; -// } -// args.Response.Header.SetHeaderValue("Access-Control-Allow-Origin", "*"); -// args.Response.Header.SetHeaderValue("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS"); -// } -// catch (Exception e) -// { -// Debug.Console(1, "Uncaught HTTP server error: \n{0}", e); -// args.Response.Code = 500; -// } -// } - -// /// -// /// GET will return the running configuration. POST will attempt to take in a new config -// /// and restart the program. -// /// -// void HandleApiConfig(OnHttpRequestArgs args) -// { -// var request = args.Request; -// if (request.Header.RequestType == "GET") -// { -// if (File.Exists(ConfigPath)) -// { -// Debug.Console(2, "Sending config:{0}", ConfigPath); -// args.Response.Header.ContentType = EssentialsHttpServer.GetContentType(new FileInfo(ConfigPath).Extension); -// args.Response.ContentStream = new FileStream(ConfigPath, FileMode.Open, FileAccess.Read); -// } -// } -// else if (request.Header.RequestType == "POST") -// { -// Debug.Console(2, "Post type: '{0}'", request.Header.ContentType); - -// // Make sure we're receiving at least good json -// Debug.Console(1, "Receving new config"); -// if (GetContentStringJson(args) == null) -// return; - -// //---------------------------- try to move these into common method -// // Move current file aside -// var bakPath = ConfigPath + ".bak"; -// if (File.Exists(bakPath)) -// File.Delete(bakPath); -// File.Move(ConfigPath, bakPath); - -// // Write the file -// using (FileStream fs = File.Open(ConfigPath, FileMode.OpenOrCreate)) -// using (StreamWriter sw = new StreamWriter(fs)) -// { -// try -// { -// sw.Write(args.Request.ContentString); -// } -// catch (Exception e) -// { -// string err = string.Format("Error writing received config file:\r{0}", e); -// CrestronConsole.PrintLine(err); -// ErrorLog.Warn(err); -// // Put file back -// File.Move(ConfigPath + ".bak", ConfigPath); -// args.Response.Code = 500; -// return; -// } -// } - -// // If client says "yeah, restart" and has a good token -// // Restart program -// string consoleResponse = null; -// var restart = CrestronConsole.SendControlSystemCommand("progreset -p:" + -// InitialParametersClass.ApplicationNumber, ref consoleResponse); -// if (!restart) Debug.Console(0, "CAN'T DO THAT YO: {0}", consoleResponse); -// } -// } - -// void HandleApiPresetsList(OnHttpRequestArgs args) -// { -// var listPath = PresetsPathPrefix + args.Request.Path.Remove(0, 17); -// Debug.Console(2, "Checking for preset list '{0}'", listPath); - -// if (args.Request.Header.RequestType == "GET") -// { -// if (File.Exists(listPath)) -// { -// Debug.Console(2, "Sending presets file:{0}", listPath); -// args.Response.Header.ContentType = EssentialsHttpServer.GetContentType(new FileInfo(listPath).Extension); -// args.Response.ContentStream = new FileStream(listPath, FileMode.Open, FileAccess.Read); -// } -// } -// else if (args.Request.Header.RequestType == "POST") -// { -// // Make sure we're receiving at least good json -// Debug.Console(1, "Receving new presets"); -// if (GetContentStringJson(args) == null) -// return; - -// //---------------------------- try to move these into common method -// // Move current file aside -// var bakPath = listPath + ".new"; -// Debug.Console(2, "Moving presets file to {0}", bakPath); -// if(File.Exists(bakPath)) -// File.Delete(bakPath); -// File.Move(listPath, bakPath); - -// Debug.Console(2, "Writing new file"); -// // Write the file -// using (FileStream fs = File.OpenWrite(listPath)) -// using (StreamWriter sw = new StreamWriter(fs)) -// { -// try -// { -// Debug.Console(2, "Writing {1}, {0} bytes", args.Request.ContentString.Length, listPath); -// sw.Write(args.Request.ContentString); -// } -// catch (Exception e) -// { -// string err = string.Format("Error writing received presets file:\r{0}", e); -// CrestronConsole.PrintLine(err); -// ErrorLog.Warn(err); -// // Put file back -// File.Move(listPath + ".bak", listPath); -// args.Response.Code = 500; -// return; -// } -// } -// } -// } - - -// void HandleApiGetPresetsLists(HttpServerRequest request, HttpServerResponse response) -// { -// if (request.Header.RequestType != "GET") -// { -// response.Code = 404; // This should be a 405 with an allow header -// return; -// } - -// if (Directory.Exists(PresetsPathPrefix)) -// { -// //CrestronConsole.PrintLine("Parsing presets directory"); -// List files = Directory.GetFiles(PresetsPathPrefix, "*.json") -// .ToList().Select(f => Path.GetFileName(f)).ToList(); -// if (files.Count > 0) -// files.Sort(); -// var json = JsonConvert.SerializeObject(files); -// response.Header.ContentType = "application/json"; -// response.ContentString = json; -// } - -// // //CrestronConsole.PrintLine("Found {0} files", files.Count); -// // JObject jo = new JObject(); -// // JArray ja = new JArray(); - -// // foreach (var filename in files) -// // { -// // try -// // { -// // using (StreamReader sr = new StreamReader(filename)) -// // { -// // JObject tempJo = JObject.Parse(sr.ReadToEnd()); -// // if (tempJo.Value("content").Equals("presetsList")) -// // { -// // var jItem = new JObject(); // make a new object -// // jItem.Add("Name", tempJo["name"]); -// // jItem.Add("File", filename); -// // jItem.Add("Url", Uri.EscapeUriString(new Uri( -// // filename.Replace("\\html", "") -// // .Replace("\\HTML", "") -// // .Replace('\\', '/'), UriKind.Relative).ToString())); -// // ja.Add(jItem); // add to array -// // } -// // else -// // CrestronConsole.PrintLine("Cannot use presets file '{0}'", filename); -// // } -// // } -// // catch -// // { -// // // ignore failures - maybe delete them -// // CrestronConsole.PrintLine("Unable to read presets file '{0}'", filename); -// // } -// // } -// // jo.Add("PresetChannelLists", ja); -// // //CrestronConsole.PrintLine(jo.ToString()); -// // response.Header.ContentType = "application/json"; -// // response.ContentString = jo.ToString(); -// //} -// //else -// // CrestronConsole.PrintLine("No presets files in directory"); -// } - -// /// -// /// Simply does what it says -// /// -// JObject GetContentStringJson(OnHttpRequestArgs args) -// { -// //var content = args.Request.ContentString; -// //Debug.Console(1, "{0}", content); - -// try -// { -// // just see if it parses properly -// return JObject.Parse(args.Request.ContentString); -// } -// catch (Exception e) -// { -// string err = string.Format("JSON Error reading config file:\r{0}", e); -// CrestronConsole.PrintLine(err); -// ErrorLog.Warn(err); -// args.Response.Code = 400; // Bad request -// return null; -// } -// } -// } -//} \ No newline at end of file diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj index f96ea4d5..6c606273 100644 --- a/PepperDashEssentials/PepperDashEssentials.csproj +++ b/PepperDashEssentials/PepperDashEssentials.csproj @@ -108,43 +108,31 @@ + - + - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + @@ -152,21 +140,18 @@ + + - - - - - @@ -179,7 +164,7 @@ - + diff --git a/PepperDashEssentials/PluginLoading/PluginLoading.cs b/PepperDashEssentials/PluginLoading/PluginLoading.cs new file mode 100644 index 00000000..405241a3 --- /dev/null +++ b/PepperDashEssentials/PluginLoading/PluginLoading.cs @@ -0,0 +1,491 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharp.CrestronIO; +using Crestron.SimplSharp.Reflection; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Plugins; + +namespace PepperDash.Essentials +{ + /// + /// Deals with loading plugins at runtime + /// + public static class PluginLoader + { + /// + /// The complete list of loaded assemblies. Includes Essentials Framework assemblies and plugins + /// + public static List LoadedAssemblies { get; private set; } + + /// + /// The list of assemblies loaded from the plugins folder + /// + static List LoadedPluginFolderAssemblies; + + /// + /// The directory to look in for .cplz plugin packages + /// + static string _pluginDirectory = Global.FilePathPrefix + "plugins"; + + /// + /// The directory where plugins will be moved to and loaded from + /// + static string _loadedPluginsDirectoryPath = _pluginDirectory + Global.DirectorySeparator + "loadedAssemblies"; + + // The temp directory where .cplz archives will be unzipped to + static string _tempDirectory = _pluginDirectory + Global.DirectorySeparator + "temp"; + + static PluginLoader() + { + LoadedAssemblies = new List(); + LoadedPluginFolderAssemblies = new List(); + } + + /// + /// Retrieves all the loaded assemblies from the program directory + /// + public static void AddProgramAssemblies() + { + Debug.Console(2, "Getting Assemblies loaded with Essentials"); + // Get the loaded assembly filenames + var appDi = new DirectoryInfo(Global.ApplicationDirectoryPathPrefix); + var assemblyFiles = appDi.GetFiles("*.dll"); + + Debug.Console(2, "Found {0} Assemblies", assemblyFiles.Length); + + foreach (var fi in assemblyFiles) + { + string version = string.Empty; + Assembly assembly = null; + + switch (fi.Name) + { + case ("PepperDashEssentials.dll"): + { + version = Global.AssemblyVersion; + assembly = Assembly.GetExecutingAssembly(); + break; + } + case ("PepperDashEssentialsBase.dll"): + { + + break; + } + case ("PepperDash_Core.dll"): + { + version = PepperDash.Core.Debug.PepperDashCoreVersion; + break; + } + } + + LoadedAssemblies.Add(new LoadedAssembly(fi.Name, version, assembly)); + } + + if (Debug.Level > 1) + { + Debug.Console(2, "Loaded Assemblies:"); + + foreach (var assembly in LoadedAssemblies) + { + Debug.Console(2, "Assembly: {0}", assembly.Name); + } + } + } + + /// + /// Loads an assembly via Reflection and adds it to the list of loaded assemblies + /// + /// + static LoadedAssembly LoadAssembly(string filePath) + { + Debug.Console(2, "Attempting to load {0}", filePath); + var assembly = Assembly.LoadFrom(filePath); + if (assembly != null) + { + var assyVersion = GetAssemblyVersion(assembly); + + var loadedAssembly = new LoadedAssembly(assembly.GetName().Name, assyVersion, assembly); + LoadedAssemblies.Add(loadedAssembly); + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loaded assembly '{0}', version {1}", loadedAssembly.Name, loadedAssembly.Version); + return loadedAssembly; + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to load assembly: '{0}'", filePath); + } + + return null; + + } + + /// + /// Attempts to get the assembly informational version and if not possible gets the version + /// + /// + /// + static string GetAssemblyVersion(Assembly assembly) + { + var ver = assembly.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false); + if (ver != null && ver.Length > 0) + { + // Get the AssemblyInformationalVersion + AssemblyInformationalVersionAttribute verAttribute = ver[0] as AssemblyInformationalVersionAttribute; + return verAttribute.InformationalVersion; + } + else + { + // Get the AssemblyVersion + var version = assembly.GetName().Version; + var verStr = string.Format("{0}.{1}.{2}.{3}", version.Major, version.Minor, version.Build, version.Revision); + return verStr; + } + } + + /// + /// Checks if the filename matches an already loaded assembly file's name + /// + /// + /// True if file already matches loaded assembly file. + public static bool CheckIfAssemblyLoaded(string name) + { + Debug.Console(2, "Checking if assembly: {0} is loaded...", name); + var loadedAssembly = LoadedAssemblies.FirstOrDefault(s => s.Name.Equals(name)); + + if (loadedAssembly != null) + { + Debug.Console(2, "Assembly already loaded."); + return true; + } + else + { + Debug.Console(2, "Assembly not loaded."); + return false; + } + } + + /// + /// Used by console command to report the currently loaded assemblies and versions + /// + /// + public static void ReportAssemblyVersions(string command) + { + Debug.Console(0, "Loaded Assemblies:"); + foreach (var assembly in LoadedAssemblies) + { + Debug.Console(0, "{0} Version: {1}", assembly.Name, assembly.Version); + } + } + + /// + /// Moves any .dll assemblies not already loaded from the plugins folder to loadedPlugins folder + /// + static void MoveDllAssemblies() + { + Debug.Console(0, "Looking for .dll assemblies from plugins folder..."); + + var pluginDi = new DirectoryInfo(_pluginDirectory); + var pluginFiles = pluginDi.GetFiles("*.dll"); + + if (pluginFiles.Length > 0) + { + if (!Directory.Exists(_loadedPluginsDirectoryPath)) + { + Directory.CreateDirectory(_loadedPluginsDirectoryPath); + } + } + + foreach (var pluginFile in pluginFiles) + { + try + { + Debug.Console(0, "Found .dll: {0}", pluginFile.Name); + + if (!CheckIfAssemblyLoaded(pluginFile.Name)) + { + string filePath = string.Empty; + + filePath = _loadedPluginsDirectoryPath + Global.DirectorySeparator + pluginFile.Name; + + // Check if there is a previous file in the loadedPlugins directory and delete + if (File.Exists(filePath)) + { + Debug.Console(0, "Found existing file in loadedPlugins: {0} Deleting and moving new file to replace it", filePath); + File.Delete(filePath); + } + + // Move the file + File.Move(pluginFile.FullName, filePath); + Debug.Console(2, "Moved {0} to {1}", pluginFile.FullName, filePath); + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Skipping assembly: {0}. There is already an assembly with that name loaded.", pluginFile.FullName); + } + } + catch (Exception e) + { + Debug.Console(2, "Error with plugin file {0} . Exception: {1}", pluginFile.FullName, e); + continue; //catching any load issues and continuing. There will be exceptions loading Crestron .dlls from the cplz Probably should do something different here + } + } + + Debug.Console(0, "Done with .dll assemblies"); + } + + /// + /// Unzips each .cplz archive into the temp directory and moves any unloaded files into loadedPlugins + /// + static void UnzipAndMoveCplzArchives() + { + Debug.Console(0, "Looking for .cplz archives from plugins folder..."); + var di = new DirectoryInfo(_pluginDirectory); + var zFiles = di.GetFiles("*.cplz"); + + if (zFiles.Length > 0) + { + if (!Directory.Exists(_loadedPluginsDirectoryPath)) + { + Directory.CreateDirectory(_loadedPluginsDirectoryPath); + } + } + + foreach (var zfi in zFiles) + { + Directory.CreateDirectory(_tempDirectory); + var tempDi = new DirectoryInfo(_tempDirectory); + + Debug.Console(0, "Found cplz: {0}. Unzipping into temp plugins directory", zfi.Name); + var result = CrestronZIP.Unzip(zfi.FullName, tempDi.FullName); + Debug.Console(0, "UnZip Result: {0}", result.ToString()); + + var tempFiles = tempDi.GetFiles("*.dll"); + foreach (var tempFile in tempFiles) + { + try + { + if (!CheckIfAssemblyLoaded(tempFile.Name)) + { + string filePath = string.Empty; + + filePath = _loadedPluginsDirectoryPath + Global.DirectorySeparator + tempFile.Name; + + // Check if there is a previous file in the loadedPlugins directory and delete + if (File.Exists(filePath)) + { + Debug.Console(0, "Found existing file in loadedPlugins: {0} Deleting and moving new file to replace it", filePath); + File.Delete(filePath); + } + + // Move the file + File.Move(tempFile.FullName, filePath); + Debug.Console(2, "Moved {0} to {1}", tempFile.FullName, filePath); + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Skipping assembly: {0}. There is already an assembly with that name loaded.", tempFile.FullName); + } + } + catch (Exception e) + { + Debug.Console(2, "Assembly {0} is not a custom assembly. Exception: {1}", tempFile.FullName, e); + continue; //catching any load issues and continuing. There will be exceptions loading Crestron .dlls from the cplz Probably should do something different here + } + } + + // Delete the .cplz and the temp directory + Directory.Delete(_tempDirectory, true); + zfi.Delete(); + } + + Debug.Console(0, "Done with .cplz archives"); + } + + /// + /// Attempts to load the assemblies from the loadedPlugins folder + /// + static void LoadPluginAssemblies() + { + Debug.Console(0, "Loading assemblies from loadedPlugins folder..."); + var pluginDi = new DirectoryInfo(_loadedPluginsDirectoryPath); + var pluginFiles = pluginDi.GetFiles("*.dll"); + + Debug.Console(2, "Found {0} plugin assemblies to load", pluginFiles.Length); + + foreach (var pluginFile in pluginFiles) + { + var loadedAssembly = LoadAssembly(pluginFile.FullName); + + LoadedPluginFolderAssemblies.Add(loadedAssembly); + } + + Debug.Console(0, "All Plugins Loaded."); + } + + /// + /// Iterate the loaded assemblies and try to call the LoadPlugin method + /// + static void LoadCustomPluginTypes() + { + Debug.Console(0, "Loading Custom Plugin Types..."); + foreach (var loadedAssembly in LoadedPluginFolderAssemblies) + { + // iteratate this assembly's classes, looking for "LoadPlugin()" methods + try + { + var assy = loadedAssembly.Assembly; + var types = assy.GetTypes(); + foreach (var type in types) + { + try + { + if (typeof(IPluginDeviceFactory).IsAssignableFrom(type)) + { + var plugin = (IPluginDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); + LoadCustomPlugin(plugin, loadedAssembly); + } + else + { + var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static); + var loadPlugin = methods.FirstOrDefault(m => m.Name.Equals("LoadPlugin")); + if (loadPlugin != null) + { + LoadCustomLegacyPlugin(type, loadPlugin, loadedAssembly); + } + } + } + catch (Exception e) + { + Debug.Console(2, "Load Plugin not found. {0} is not a plugin assembly. Exception: {1}", loadedAssembly.Name, e); + continue; + } + + } + } + catch (Exception e) + { + Debug.Console(2, "Error Loading Assembly: {0} Exception: (1) ", loadedAssembly.Name, e); + continue; + } + } + // plugin dll will be loaded. Any classes in plugin should have a static constructor + // that registers that class with the Core.DeviceFactory + Debug.Console(0, "Done Loading Custom Plugin Types."); + } + + /// + /// Loads a + /// + /// + static void LoadCustomPlugin(IPluginDeviceFactory plugin, LoadedAssembly loadedAssembly) + { + var passed = Global.IsRunningMinimumVersionOrHigher(plugin.MinimumEssentialsFrameworkVersion); + + if (!passed) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", plugin.MinimumEssentialsFrameworkVersion); + return; + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Passed plugin passed dependency check (required version {0})", plugin.MinimumEssentialsFrameworkVersion); + } + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading plugin: {0}", loadedAssembly.Name); + plugin.LoadTypeFactories(); + } + + /// + /// Loads a a custom plugin via the legacy method + /// + /// + /// + static void LoadCustomLegacyPlugin(CType type, MethodInfo loadPlugin, LoadedAssembly loadedAssembly) + { + Debug.Console(2, "LoadPlugin method found in {0}", type.Name); + + var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static); + + var minimumVersion = fields.FirstOrDefault(p => p.Name.Equals("MinimumEssentialsFrameworkVersion")); + if (minimumVersion != null) + { + Debug.Console(2, "MinimumEssentialsFrameworkVersion found"); + + var minimumVersionString = minimumVersion.GetValue(null) as string; + + if (!string.IsNullOrEmpty(minimumVersionString)) + { + var passed = Global.IsRunningMinimumVersionOrHigher(minimumVersionString); + + if (!passed) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", minimumVersionString); + return; + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Passed plugin passed dependency check (required version {0})", minimumVersionString); + } + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion found but not set. Loading plugin, but your mileage may vary."); + } + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion not found. Loading plugin, but your mileage may vary."); + } + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading legacy plugin: {0}", loadedAssembly.Name); + loadPlugin.Invoke(null, null); + + } + + /// + /// Loads plugins + /// + public static void LoadPlugins() + { + if (Directory.Exists(_pluginDirectory)) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Plugins directory found, checking for plugins"); + + // Deal with any .dll files + MoveDllAssemblies(); + + // Deal with any .cplz files + UnzipAndMoveCplzArchives(); + + if(Directory.Exists(_loadedPluginsDirectoryPath)) { + // Load the assemblies from the loadedPlugins folder into the AppDomain + LoadPluginAssemblies(); + + // Load the types from any custom plugin assemblies + LoadCustomPluginTypes(); + } + } + } + } + + /// + /// Represents an assembly loaded at runtime and it's associated metadata + /// + public class LoadedAssembly + { + public string Name { get; private set; } + public string Version { get; private set; } + public Assembly Assembly { get; private set; } + + public LoadedAssembly(string name, string version, Assembly assembly) + { + Name = name; + Version = version; + Assembly = assembly; + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/Room/Config/EssentialsHuddleRoomPropertiesConfig.cs b/PepperDashEssentials/Room/Config/EssentialsHuddleRoomPropertiesConfig.cs index 2044484d..528436d6 100644 --- a/PepperDashEssentials/Room/Config/EssentialsHuddleRoomPropertiesConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsHuddleRoomPropertiesConfig.cs @@ -4,6 +4,10 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; + namespace PepperDash.Essentials.Room.Config { /// @@ -11,9 +15,28 @@ namespace PepperDash.Essentials.Room.Config /// public class EssentialsHuddleRoomPropertiesConfig : EssentialsRoomPropertiesConfig { + /// + /// The key of the default display device + /// + [JsonProperty("defaultDisplayKey")] public string DefaultDisplayKey { get; set; } + + /// + /// The key of the default audio device + /// + [JsonProperty("defaultAudioKey")] public string DefaultAudioKey { get; set; } + + /// + /// The key of the source list for the room + /// + [JsonProperty("sourceListKey")] public string SourceListKey { get; set; } + + /// + /// The key of the default source item from the source list + /// + [JsonProperty("defaultSourceItem")] public string DefaultSourceItem { get; set; } } } \ No newline at end of file diff --git a/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs b/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs index 44c88724..27539ebd 100644 --- a/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs @@ -348,7 +348,7 @@ namespace PepperDash.Essentials CrestronEnvironment.Sleep(1000); - RunRouteAction("roomOff"); + RunRouteAction("roomOff", SourceListKey); } /// @@ -357,7 +357,7 @@ namespace PepperDash.Essentials public override bool RunDefaultPresentRoute() { if (DefaultSourceItem != null) - RunRouteAction(DefaultSourceItem); + RunRouteAction(DefaultSourceItem, SourceListKey); return DefaultSourceItem != null; } @@ -368,7 +368,7 @@ namespace PepperDash.Essentials /// public bool RunDefaultCallRoute() { - RunRouteAction(DefaultCodecRouteString); + RunRouteAction(DefaultCodecRouteString, SourceListKey); return true; } @@ -376,9 +376,9 @@ namespace PepperDash.Essentials /// /// /// - public void RunRouteAction(string routeKey) + public void RunRouteAction(string routeKey, string sourceListKey) { - RunRouteAction(routeKey, null); + RunRouteAction(routeKey, sourceListKey, null); } /// @@ -386,7 +386,7 @@ namespace PepperDash.Essentials /// route or commands /// /// - public void RunRouteAction(string routeKey, Action successCallback) + public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback) { // Run this on a separate thread new CTimer(o => @@ -398,10 +398,10 @@ namespace PepperDash.Essentials { Debug.Console(1, this, "Run route action '{0}'", routeKey); - var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey); + var dict = ConfigReader.ConfigObject.GetSourceListForKey(sourceListKey); if (dict == null) { - Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey); + Debug.Console(1, this, "WARNING: Config source list '{0}' not found", sourceListKey); return; } @@ -619,7 +619,7 @@ namespace PepperDash.Essentials { if (!EnablePowerOnToLastSource || LastSourceKey == null) return; - RunRouteAction(LastSourceKey); + RunRouteAction(LastSourceKey, SourceListKey); } /// @@ -630,7 +630,7 @@ namespace PepperDash.Essentials var allRooms = DeviceManager.AllDevices.Where(d => d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions); foreach (var room in allRooms) - (room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff"); + (room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff", (room as EssentialsHuddleSpaceRoom).SourceListKey); } #region IPrivacy Members diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs index 9bec05b8..b14e563d 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs @@ -264,8 +264,30 @@ namespace PepperDash.Essentials /// public void RunRouteAction(string routeKey) { - RunRouteAction(routeKey, null); - } + RunRouteAction(routeKey, new Action(() => { })); + } + + /// + /// + /// + /// + /// + /// + public void RunRouteAction(string routeKey, string souceListKey) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public void RunRouteAction(string routeKey, string souceListKey, Action successCallback) + { + throw new NotImplementedException(); + } /// /// Gets a source from config list SourceListKey and dynamically build and executes the diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index b2db56ae..c5021526 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -394,8 +394,30 @@ namespace PepperDash.Essentials /// public void RunRouteAction(string routeKey) { - RunRouteAction(routeKey, null); - } + RunRouteAction(routeKey, new Action(() => { })); + } + + /// + /// + /// + /// + /// + /// + public void RunRouteAction(string routeKey, string souceListKey) + { + throw new NotImplementedException(); + } + + /// + /// + /// + /// + /// + /// + public void RunRouteAction(string routeKey, string souceListKey, Action successCallback) + { + throw new NotImplementedException(); + } /// /// Gets a source from config list SourceListKey and dynamically build and executes the diff --git a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs index df1ecdce..d008eee0 100644 --- a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs +++ b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs @@ -9,11 +9,12 @@ using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.UI; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.PageManagers; namespace PepperDash.Essentials { - public class EssentialsTouchpanelController : Device, IHasBasicTriListWithSmartObject + public class EssentialsTouchpanelController : EssentialsDevice, IHasBasicTriListWithSmartObject { public BasicTriListWithSmartObject Panel { get; private set; } @@ -197,4 +198,132 @@ namespace PepperDash.Essentials (uo as Action)(args.Button.State == eButtonState.Pressed); } } + + public class EssentialsTouchpanelControllerFactory : EssentialsDeviceFactory + { + public EssentialsTouchpanelControllerFactory() + { + TypeNames = new List() { "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "xpanel" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + var comm = CommFactory.GetControlPropertiesConfig(dc); + var props = Newtonsoft.Json.JsonConvert.DeserializeObject(dc.Properties.ToString()); + + Debug.Console(1, "Factory Attempting to create new Generic Comm Device"); + + var panelController = new EssentialsTouchpanelController(dc.Key, dc.Name, dc.Type, props, comm.IpIdInt); + + panelController.AddPostActivationAction(() => + { + var mainDriver = new EssentialsPanelMainInterfaceDriver(panelController.Panel, props); + // Then the sub drivers + + // spin up different room drivers depending on room type + var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey); + if (room is EssentialsHuddleSpaceRoom) + { + + // Header Driver + Debug.Console(0, panelController, "Adding header driver"); + mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, props); + + // AV Driver + Debug.Console(0, panelController, "Adding huddle space AV driver"); + var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props); + avDriver.DefaultRoomKey = props.DefaultRoomKey; + mainDriver.AvDriver = avDriver; + avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom; + + // Environment Driver + if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0) + { + Debug.Console(0, panelController, "Adding environment driver"); + mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, props); + + mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment); + } + + mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom); + + panelController.LoadAndShowDriver(mainDriver); // This is a little convoluted. + + if (panelController.Panel is TswFt5ButtonSystem) + { + var tsw = panelController.Panel as TswFt5ButtonSystem; + // Wire up hard keys + tsw.Power.UserObject = new Action(b => { if (!b) avDriver.PowerButtonPressed(); }); + //tsw.Home.UserObject = new Action(b => { if (!b) HomePressed(); }); + if (mainDriver.EnvironmentDriver != null) + tsw.Lights.UserObject = new Action(b => + { + if (!b) + { + //mainDriver.AvDriver.PopupInterlock.ShowInterlockedWithToggle(mainDriver.EnvironmentDriver.BackgroundSubpageJoin); + mainDriver.EnvironmentDriver.Toggle(); + } + }); + tsw.Up.UserObject = new Action(avDriver.VolumeUpPress); + tsw.Down.UserObject = new Action(avDriver.VolumeDownPress); + } + } + else if (room is EssentialsHuddleVtc1Room) + { + Debug.Console(0, panelController, "Adding huddle space VTC AV driver"); + + // Header Driver + mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, props); + + // AV Driver + var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, props); + + var codecDriver = new PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver(panelController.Panel, avDriver, + (room as EssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver); + avDriver.SetVideoCodecDriver(codecDriver); + avDriver.DefaultRoomKey = props.DefaultRoomKey; + mainDriver.AvDriver = avDriver; + avDriver.CurrentRoom = room as EssentialsHuddleVtc1Room; + + // Environment Driver + if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0) + { + Debug.Console(0, panelController, "Adding environment driver"); + mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, props); + + mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment); + } + + mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom); + + panelController.LoadAndShowDriver(mainDriver); // This is a little convoluted. + + if (panelController.Panel is TswFt5ButtonSystem) + { + var tsw = panelController.Panel as TswFt5ButtonSystem; + // Wire up hard keys + tsw.Power.UserObject = new Action(b => { if (!b) avDriver.EndMeetingPress(); }); + //tsw.Home.UserObject = new Action(b => { if (!b) HomePressed(); }); + if (mainDriver.EnvironmentDriver != null) + tsw.Lights.UserObject = new Action(b => + { + if (!b) + { + //mainDriver.AvDriver.PopupInterlock.ShowInterlockedWithToggle(mainDriver.EnvironmentDriver.BackgroundSubpageJoin); + mainDriver.EnvironmentDriver.Toggle(); + } + }); + tsw.Up.UserObject = new Action(avDriver.VolumeUpPress); + tsw.Down.UserObject = new Action(avDriver.VolumeDownPress); + } + } + else + { + Debug.Console(0, panelController, "ERROR: Cannot load AvFunctionsDriver for room '{0}'", props.DefaultRoomKey); + } + }); + + return panelController; + } + } } \ No newline at end of file diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs index 144fafb4..232a99da 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs @@ -564,7 +564,7 @@ namespace PepperDash.Essentials void UiSelectSource(string key) { // Run the route and when it calls back, show the source - CurrentRoom.RunRouteAction(key, null); + CurrentRoom.RunRouteAction(key, new Action(() => { })); } /// diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 57e68010..9248e50a 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -726,7 +726,7 @@ namespace PepperDash.Essentials void UiSelectSource(string key) { // Run the route and when it calls back, show the source - CurrentRoom.RunRouteAction(key, null); + CurrentRoom.RunRouteAction(key, new Action(() => { })); } /// @@ -941,7 +941,7 @@ namespace PepperDash.Essentials if (_CurrentRoom != null) _CurrentRoom.CurrentSourceChange += new SourceInfoChangeHandler(CurrentRoom_CurrentSingleSourceChange); - TriList.SetSigFalseAction(UIBoolJoin.CallStopSharingPress, () => _CurrentRoom.RunRouteAction("codecOsd")); + TriList.SetSigFalseAction(UIBoolJoin.CallStopSharingPress, () => _CurrentRoom.RunRouteAction("codecOsd", _CurrentRoom.SourceListKey)); (Parent as EssentialsPanelMainInterfaceDriver).HeaderDriver.SetupHeaderButtons(this, CurrentRoom); } @@ -987,7 +987,7 @@ namespace PepperDash.Essentials if (CurrentRoom.CurrentSourceInfo != null && CurrentRoom.CurrentSourceInfo.DisableCodecSharing) { Debug.Console(1, CurrentRoom, "Transitioning to in-call, cancelling non-sharable source"); - CurrentRoom.RunRouteAction("codecOsd"); + CurrentRoom.RunRouteAction("codecOsd", CurrentRoom.SourceListKey); } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs new file mode 100644 index 00000000..5bde418f --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs @@ -0,0 +1,309 @@ +using System; +using System.Collections.Generic; +using Crestron.SimplSharp.Reflection; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.EthernetCommunication; + +using Newtonsoft.Json; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; + +//using PepperDash.Essentials.Devices.Common.Cameras; + +namespace PepperDash.Essentials.Core.Bridges +{ + /// + /// Helper methods for bridges + /// + public static class BridgeHelper + { + public static void PrintJoinMap(string command) + { + var targets = command.Split(' '); + + var bridgeKey = targets[0].Trim(); + + var bridge = DeviceManager.GetDeviceForKey(bridgeKey) as EiscApiAdvanced; + + if (bridge == null) + { + Debug.Console(0, "Unable to find advanced bridge with key: '{0}'", bridgeKey); + return; + } + + if (targets.Length > 1) + { + var deviceKey = targets[1].Trim(); + + if (string.IsNullOrEmpty(deviceKey)) return; + bridge.PrintJoinMapForDevice(deviceKey); + } + else + { + bridge.PrintJoinMaps(); + } + } + } + + + /// + /// Base class for all bridge class variants + /// + public class BridgeBase : EssentialsDevice + { + public BridgeApi Api { get; protected set; } + + public BridgeBase(string key) : + base(key) + { + + } + } + + /// + /// Base class for bridge API variants + /// + public abstract class BridgeApi : EssentialsDevice + { + protected BridgeApi(string key) : + base(key) + { + + } + } + + /// + /// Bridge API using EISC + /// + public class EiscApiAdvanced : BridgeApi + { + public EiscApiPropertiesConfig PropertiesConfig { get; private set; } + + protected Dictionary JoinMaps { get; private set; } + + public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc { get; private set; } + + public EiscApiAdvanced(DeviceConfig dc) : + base(dc.Key) + { + JoinMaps = new Dictionary(); + + PropertiesConfig = dc.Properties.ToObject(); + //PropertiesConfig = JsonConvert.DeserializeObject(dc.Properties.ToString()); + + Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(PropertiesConfig.Control.IpIdInt, PropertiesConfig.Control.TcpSshProperties.Address, Global.ControlSystem); + + Eisc.SigChange += Eisc_SigChange; + + Eisc.Register(); + + AddPostActivationAction( () => + { + Debug.Console(1, this, "Linking Devices..."); + + foreach (var d in PropertiesConfig.Devices) + { + var device = DeviceManager.GetDeviceForKey(d.DeviceKey); + + if (device == null) continue; + + Debug.Console(1, this, "Linking Device: '{0}'", device.Key); + //if (device is IBridge) // Check for this first to allow bridges in plugins to override existing bridges that apply to the same type. + //{ + // Debug.Console(2, this, "'{0}' is IBridge", device.Key); + //} + if (!typeof (IBridgeAdvanced).IsAssignableFrom(device.GetType().GetCType())) + { + continue; + } + + var bridge = device as IBridgeAdvanced; + if (bridge != null) bridge.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, this); + } + + + }); + } + + /// + /// Adds a join map + /// + /// + /// + public void AddJoinMap(string deviceKey, JoinMapBaseAdvanced joinMap) + { + if (!JoinMaps.ContainsKey(deviceKey)) + { + JoinMaps.Add(deviceKey, joinMap); + } + else + { + Debug.Console(2, this, "Unable to add join map with key '{0}'. Key already exists in JoinMaps dictionary", deviceKey); + } + } + + /// + /// Prints all the join maps on this bridge + /// + public void PrintJoinMaps() + { + Debug.Console(0, this, "Join Maps for EISC IPID: {0}", Eisc.ID.ToString("X")); + + foreach (var joinMap in JoinMaps) + { + Debug.Console(0, "Join map for device '{0}':", joinMap.Key); + joinMap.Value.PrintJoinMapInfo(); + } + } + + /// + /// Prints the join map for a device by key + /// + /// + public void PrintJoinMapForDevice(string deviceKey) + { + var joinMap = JoinMaps[deviceKey]; + + if (joinMap == null) + { + Debug.Console(0, this, "Unable to find joinMap for device with key: '{0}'", deviceKey); + return; + } + + Debug.Console(0, "Join map for device '{0}' on EISC '{1}':", deviceKey, Key); + joinMap.PrintJoinMapInfo(); + } + + /// + /// Used for debugging to trigger an action based on a join number and type + /// + /// + /// + /// + public void ExecuteJoinAction(uint join, string type, object state) + { + try + { + switch (type.ToLower()) + { + case "digital": + { + var uo = Eisc.BooleanOutput[join].UserObject as Action; + if (uo != null) + { + Debug.Console(1, this, "Executing Action: {0}", uo.ToString()); + uo(Convert.ToBoolean(state)); + } + else + Debug.Console(1, this, "User Action is null. Nothing to Execute"); + break; + } + case "analog": + { + var uo = Eisc.BooleanOutput[join].UserObject as Action; + if (uo != null) + { + Debug.Console(1, this, "Executing Action: {0}", uo.ToString()); + uo(Convert.ToUInt16(state)); + } + else + Debug.Console(1, this, "User Action is null. Nothing to Execute"); break; + } + case "serial": + { + var uo = Eisc.BooleanOutput[join].UserObject as Action; + if (uo != null) + { + Debug.Console(1, this, "Executing Action: {0}", uo.ToString()); + uo(Convert.ToString(state)); + } + else + Debug.Console(1, this, "User Action is null. Nothing to Execute"); + break; + } + default: + { + Debug.Console(1, "Unknown join type. Use digital/serial/analog"); + break; + } + } + } + catch (Exception e) + { + Debug.Console(1, this, "Error: {0}", e); + } + + } + + /// + /// Handles incoming sig changes + /// + /// + /// + void Eisc_SigChange(object currentDevice, SigEventArgs args) + { + try + { + if (Debug.Level >= 1) + Debug.Console(1, this, "EiscApiAdvanced change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue); + var uo = args.Sig.UserObject; + + if (uo == null) return; + + Debug.Console(1, this, "Executing Action: {0}", uo.ToString()); + if (uo is Action) + (uo as Action)(args.Sig.BoolValue); + else if (uo is Action) + (uo as Action)(args.Sig.UShortValue); + else if (uo is Action) + (uo as Action)(args.Sig.StringValue); + } + catch (Exception e) + { + Debug.Console(2, this, "Error in Eisc_SigChange handler: {0}", e); + } + } + } + + public class EiscApiPropertiesConfig + { + [JsonProperty("control")] + public EssentialsControlPropertiesConfig Control { get; set; } + + [JsonProperty("devices")] + public List Devices { get; set; } + + + public class ApiDevicePropertiesConfig + { + [JsonProperty("deviceKey")] + public string DeviceKey { get; set; } + + [JsonProperty("joinStart")] + public uint JoinStart { get; set; } + + [JsonProperty("joinMapKey")] + public string JoinMapKey { get; set; } + } + + } + + public class EiscApiAdvancedFactory : EssentialsDeviceFactory + { + public EiscApiAdvancedFactory() + { + TypeNames = new List() { "eiscapiadv", "eiscapiadvanced" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new EiscApiAdvanced Device"); + + return new EiscApiAdvanced(dc); + + } + } + +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/IBridge.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/IBridge.cs new file mode 100644 index 00000000..1f10e554 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/IBridge.cs @@ -0,0 +1,13 @@ +using System; +using Crestron.SimplSharpPro.DeviceSupport; + +namespace PepperDash.Essentials.Core.Bridges +{ + /// + /// Defines a device that uses JoinMapBaseAdvanced for its join map + /// + public interface IBridgeAdvanced + { + void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge); + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AirMediaControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AirMediaControllerJoinMap.cs new file mode 100644 index 00000000..1c091233 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AirMediaControllerJoinMap.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class AirMediaControllerJoinMap : JoinMapBase + { + #region Digitals + /// + /// Indicates that the device is online when high + /// + public uint IsOnline { get; set; } + /// + /// Indicates that the device is in session when high + /// + public uint IsInSession { get; set; } + /// + /// Indicates sync detected on HDMI input when high + /// + public uint HdmiVideoSync { get; set; } + /// + /// Set High to enable automatic input routing and low to disable. Feedback high when enabled + /// + public uint AutomaticInputRoutingEnabled { get; set; } + #endregion + + #region Analogs + /// + /// Selects source and provides feedback + /// + public uint VideoOut { get; set; } + /// + /// Provided error feedback + /// + public uint ErrorFB { get; set; } + /// + /// Indicates the number of connected users as feedback + /// + public uint NumberOfUsersConnectedFB { get; set; } + /// + /// Sets the login code and provides the current code as feedback + /// + public uint LoginCode { get; set; } + #endregion + + #region Serials + /// + /// Provides the name defined in config as feedback + /// + public uint Name { get; set; } + /// + /// Provides the connection address as feedback + /// + public uint ConnectionAddressFB { get; set; } + /// + /// Provides the hostname as feedback + /// + public uint HostnameFB { get; set; } + /// + /// Provides the serial number as feedback + /// + public uint SerialNumberFeedback { get; set; } + #endregion + + public AirMediaControllerJoinMap() + { + // Digital + IsOnline = 1; + IsInSession = 2; + HdmiVideoSync = 3; + AutomaticInputRoutingEnabled = 4; + + // Analog + VideoOut = 1; + ErrorFB = 2; + NumberOfUsersConnectedFB = 3; + LoginCode = 4; + + // Serial + Name = 1; + ConnectionAddressFB = 2; + HostnameFB = 3; + SerialNumberFeedback = 4; + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + IsOnline = IsOnline + joinOffset; + IsInSession = IsInSession + joinOffset; + HdmiVideoSync = HdmiVideoSync + joinOffset; + AutomaticInputRoutingEnabled = AutomaticInputRoutingEnabled + joinOffset; + + VideoOut = VideoOut + joinOffset; + ErrorFB = ErrorFB + joinOffset; + NumberOfUsersConnectedFB = NumberOfUsersConnectedFB + joinOffset; + LoginCode = LoginCode + joinOffset; + + Name = Name + joinOffset; + ConnectionAddressFB = ConnectionAddressFB + joinOffset; + HostnameFB = HostnameFB + joinOffset; + SerialNumberFeedback = SerialNumberFeedback + joinOffset; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AppleTvJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AppleTvJoinMap.cs new file mode 100644 index 00000000..aae9e37b --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AppleTvJoinMap.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class AppleTvJoinMap : JoinMapBase + { + #region Digitals + /// + /// Sends up arrow command while high + /// + public uint UpArrow { get; set; } + /// + /// Sends down arrow command while high + /// + public uint DnArrow { get; set; } + /// + /// Sends left arrow command while high + /// + public uint LeftArrow { get; set; } + /// + /// Sends right arrow command while high + /// + public uint RightArrow { get; set; } + /// + /// Sends menu command + /// + public uint Menu { get; set; } + /// + /// Sends select command + /// + public uint Select { get; set; } + /// + /// Sends play/pause command + /// + public uint PlayPause { get; set; } + #endregion + + public AppleTvJoinMap() + { + UpArrow = 1; + DnArrow = 2; + LeftArrow = 3; + RightArrow = 4; + Menu = 5; + Select = 6; + PlayPause = 7; + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + UpArrow = UpArrow + joinOffset; + DnArrow = DnArrow + joinOffset; + LeftArrow = LeftArrow + joinOffset; + RightArrow = RightArrow + joinOffset; + Menu = Menu + joinOffset; + Select = Select + joinOffset; + PlayPause = PlayPause + joinOffset; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/C2nRthsControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/C2nRthsControllerJoinMap.cs new file mode 100644 index 00000000..2ef315b5 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/C2nRthsControllerJoinMap.cs @@ -0,0 +1,43 @@ +using System.Linq; +using Crestron.SimplSharp.Reflection; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class C2nRthsControllerJoinMap:JoinMapBase + { + public uint IsOnline { get; set; } + public uint Name { get; set; } + public uint Temperature { get; set; } + public uint Humidity { get; set; } + public uint TemperatureFormat { get; set; } + + public C2nRthsControllerJoinMap() + { + //digital + IsOnline = 1; + TemperatureFormat = 2; + + //Analog + Temperature = 2; + Humidity = 3; + + //serial + Name = 1; + + + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + var properties = + GetType().GetCType().GetProperties().Where(p => p.PropertyType == typeof(uint)).ToList(); + + foreach (var propertyInfo in properties) + { + propertyInfo.SetValue(this, (uint)propertyInfo.GetValue(this, null) + joinOffset, null); + } + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/CameraControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/CameraControllerJoinMap.cs new file mode 100644 index 00000000..187978d1 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/CameraControllerJoinMap.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + /// + /// Join map for CameraBase devices + /// + public class CameraControllerJoinMap : JoinMapBaseAdvanced + { + [JoinName("TiltUp")] + public JoinDataComplete TiltUp = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata() { Label = "Tilt Up", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("TiltDown")] + public JoinDataComplete TiltDown = new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 }, new JoinMetadata() { Label = "Tilt Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("PanLeft")] + public JoinDataComplete PanLeft = new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 }, new JoinMetadata() { Label = "Pan Left", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("PanRight")] + public JoinDataComplete PanRight = new JoinDataComplete(new JoinData() { JoinNumber = 4, JoinSpan = 1 }, new JoinMetadata() { Label = "Pan Right", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("ZoomIn")] + public JoinDataComplete ZoomIn = new JoinDataComplete(new JoinData() { JoinNumber = 5, JoinSpan = 1 }, new JoinMetadata() { Label = "Zoom In", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("ZoomOut")] + public JoinDataComplete ZoomOut = new JoinDataComplete(new JoinData() { JoinNumber = 6, JoinSpan = 1 }, new JoinMetadata() { Label = "Zoom Out", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("IsOnline")] + public JoinDataComplete IsOnline = new JoinDataComplete(new JoinData() { JoinNumber = 9, JoinSpan = 1 }, new JoinMetadata() { Label = "Is Online", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("PowerOn")] + public JoinDataComplete PowerOn = new JoinDataComplete(new JoinData() { JoinNumber = 7, JoinSpan = 1 }, new JoinMetadata() { Label = "Power On", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("PowerOff")] + public JoinDataComplete PowerOff = new JoinDataComplete(new JoinData() { JoinNumber = 8, JoinSpan = 1 }, new JoinMetadata() { Label = "Power Off", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("NumberOfPresets")] + public JoinDataComplete NumberOfPresets = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 }, new JoinMetadata() { Label = "Tells Essentials the number of defined presets", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("PresetRecallStart")] + public JoinDataComplete PresetRecallStart = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 20 }, new JoinMetadata() { Label = "Preset Recall Start", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("PresetLabelStart")] + public JoinDataComplete PresetLabelStart = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 20 }, new JoinMetadata() { Label = "Preset Label Start", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial }); + [JoinName("PresetSaveStart")] + public JoinDataComplete PresetSaveStart = new JoinDataComplete(new JoinData() { JoinNumber = 31, JoinSpan = 20 }, new JoinMetadata() { Label = "Preset Save Start", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("CameraModeAuto")] + public JoinDataComplete CameraModeAuto = new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Auto", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CameraModeManual")] + public JoinDataComplete CameraModeManual = new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Manual", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("CameraModeOff")] + public JoinDataComplete CameraModeOff = new JoinDataComplete(new JoinData() { JoinNumber = 53, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Off", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("SupportsCameraModeAuto")] + public JoinDataComplete SupportsCameraModeAuto = new JoinDataComplete(new JoinData() { JoinNumber = 55, JoinSpan = 1 }, new JoinMetadata() { Label = "Supports Camera Mode Auto", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("SupportsCameraModeOff")] + public JoinDataComplete SupportsCameraModeOff = new JoinDataComplete(new JoinData() { JoinNumber = 56, JoinSpan = 1 }, new JoinMetadata() { Label = "Supports Camera Mode Off", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("SupportsPresets")] + public JoinDataComplete SupportsPresets = new JoinDataComplete(new JoinData() { JoinNumber = 57, JoinSpan = 1 }, new JoinMetadata() { Label = "Supports Presets", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + public CameraControllerJoinMap(uint joinStart) + : base(joinStart, typeof(CameraControllerJoinMap)) + { + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DigitalLoggerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DigitalLoggerJoinMap.cs new file mode 100644 index 00000000..df90a18b --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DigitalLoggerJoinMap.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class DigitalLoggerJoinMap : JoinMapBase + { + public uint IsOnline { get; set; } + public uint CircuitNames { get; set; } + public uint CircuitState { get; set; } + public uint CircuitCycle { get; set; } + public uint CircuitIsCritical { get; set; } + public uint CircuitOnCmd { get; set; } + public uint CircuitOffCmd { get; set; } + + public DigitalLoggerJoinMap() + { + // Digital + IsOnline = 9; + CircuitState = 0; + CircuitCycle = 0; + CircuitIsCritical = 10; + CircuitOnCmd = 10; + CircuitOffCmd = 20; + // Serial + CircuitNames = 0; + // Analog + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + IsOnline = IsOnline + joinOffset; + CircuitNames = CircuitNames + joinOffset; + CircuitState = CircuitState + joinOffset; + CircuitCycle = CircuitCycle + joinOffset; + CircuitIsCritical = CircuitIsCritical + joinOffset; + CircuitOnCmd = CircuitOnCmd + joinOffset; + CircuitOffCmd = CircuitOffCmd + joinOffset; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DisplayControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DisplayControllerJoinMap.cs new file mode 100644 index 00000000..c2fe8573 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DisplayControllerJoinMap.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class DisplayControllerJoinMap : JoinMapBase + { + #region Digitals + /// + /// Turns the display off and reports power off feedback + /// + public uint PowerOff { get; set; } + /// + /// Turns the display on and repots power on feedback + /// + public uint PowerOn { get; set; } + /// + /// Indicates that the display device supports two way communication when high + /// + public uint IsTwoWayDisplay { get; set; } + /// + /// Increments the volume while high + /// + public uint VolumeUp { get; set; } + /// + /// Decrements teh volume while high + /// + public uint VolumeDown { get; set; } + /// + /// Toggles the mute state. Feedback is high when volume is muted + /// + public uint VolumeMute { get; set; } + /// + /// Range of digital joins to select inputs and report current input as feedback + /// + public uint InputSelectOffset { get; set; } + /// + /// Range of digital joins to report visibility for input buttons + /// + public uint ButtonVisibilityOffset { get; set; } + /// + /// High if the device is online + /// + public uint IsOnline { get; set; } + #endregion + + #region Analogs + /// + /// Analog join to set the input and report current input as feedback + /// + public uint InputSelect { get; set; } + /// + /// Sets the volume level and reports the current level as feedback + /// + public uint VolumeLevel { get; set; } + #endregion + + #region Serials + /// + /// Reports the name of the display as defined in config as feedback + /// + public uint Name { get; set; } + /// + /// Range of serial joins that reports the names of the inputs as feedback + /// + public uint InputNamesOffset { get; set; } + #endregion + + public DisplayControllerJoinMap() + { + // Digital + IsOnline = 50; + PowerOff = 1; + PowerOn = 2; + IsTwoWayDisplay = 3; + VolumeUp = 5; + VolumeDown = 6; + VolumeMute = 7; + + ButtonVisibilityOffset = 40; + InputSelectOffset = 10; + + // Analog + InputSelect = 11; + VolumeLevel = 5; + + // Serial + Name = 1; + InputNamesOffset = 10; + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + IsOnline = IsOnline + joinOffset; + PowerOff = PowerOff + joinOffset; + PowerOn = PowerOn + joinOffset; + IsTwoWayDisplay = IsTwoWayDisplay + joinOffset; + ButtonVisibilityOffset = ButtonVisibilityOffset + joinOffset; + Name = Name + joinOffset; + InputNamesOffset = InputNamesOffset + joinOffset; + InputSelectOffset = InputSelectOffset + joinOffset; + + InputSelect = InputSelect + joinOffset; + + VolumeUp = VolumeUp + joinOffset; + VolumeDown = VolumeDown + joinOffset; + VolumeMute = VolumeMute + joinOffset; + VolumeLevel = VolumeLevel + joinOffset; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmBladeChassisControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmBladeChassisControllerJoinMap.cs new file mode 100644 index 00000000..001d6f94 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmBladeChassisControllerJoinMap.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges { + public class DmBladeChassisControllerJoinMap : JoinMapBase { + #region Digital/Analogs + #endregion + + #region Digitals + /// + /// High when device is online + /// + public uint IsOnline { get; set; } + /// + /// Range reports video sync feedback for each input + /// + public uint VideoSyncStatus { get; set; } + /// + /// Range reports high if corresponding input's endpoint is online + /// + public uint InputEndpointOnline { get; set; } + /// + /// Range reports high if corresponding output's endpoint is online + /// + public uint OutputEndpointOnline { get; set; } + /// + /// Range reports high if corresponding input's transmitter supports bridging as a separate device for detailed AV switching, HDCP control, etc. + /// + public uint TxAdvancedIsPresent { get; set; } // indicates that there is an attached transmitter that should be bridged to be interacted with + #endregion + + #region Analogs + /// + /// Range sets and reports the current video source for the corresponding output + /// + public uint OutputVideo { get; set; } + /// + /// Range sets and reports the current HDCP state for the corresponding input card + /// + public uint HdcpSupportState { get; set; } + /// + /// Range reports the highest supported HDCP state level for the corresponding input card + /// + public uint HdcpSupportCapability { get; set; } + #endregion + + #region Serials + /// + /// Range sets and reports the name for the corresponding input card + /// + public uint InputNames { get; set; } + /// + /// Range sets and reports the name for the corresponding output card + /// + public uint OutputNames { get; set; } + /// + /// Range reports the name of the current video source for the corresponding output card + /// + public uint OutputCurrentVideoInputNames { get; set; } + /// + /// Range reports the current input resolution for each corresponding input card + /// + public uint InputCurrentResolution { get; set; } + #endregion + + public DmBladeChassisControllerJoinMap() { + //Digital/Analog + + //Digital + IsOnline = 11; + VideoSyncStatus = 100; //101-299 + InputEndpointOnline = 500; //501-699 + OutputEndpointOnline = 700; //701-899 + TxAdvancedIsPresent = 1000; //1001-1199 + + //Analog + OutputVideo = 100; //101-299 + HdcpSupportState = 1000; //1001-1199 + HdcpSupportCapability = 1200; //1201-1399 + + + //Serial + InputNames = 100; //101-299 + OutputNames = 300; //301-499 + OutputCurrentVideoInputNames = 2000; //2001-2199 + InputCurrentResolution = 2400; // 2401-2599 + } + + public override void OffsetJoinNumbers(uint joinStart) { + var joinOffset = joinStart - 1; + + IsOnline = IsOnline + joinOffset; + OutputVideo = OutputVideo + joinOffset; + VideoSyncStatus = VideoSyncStatus + joinOffset; + InputNames = InputNames + joinOffset; + OutputNames = OutputNames + joinOffset; + OutputCurrentVideoInputNames = OutputCurrentVideoInputNames + joinOffset; + InputCurrentResolution = InputCurrentResolution + joinOffset; + InputEndpointOnline = InputEndpointOnline + joinOffset; + OutputEndpointOnline = OutputEndpointOnline + joinOffset; + HdcpSupportState = HdcpSupportState + joinOffset; + HdcpSupportCapability = HdcpSupportCapability + joinOffset; + } + } +} diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs new file mode 100644 index 00000000..5059333f --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class DmChassisControllerJoinMap : JoinMapBase + { +#region Digital/Analogs + /// + /// Analog input sets System ID, output reports current ID as feedback. + /// Digital input applies System ID, output is high when applying busy. + /// + public uint SystemId { get; set; } +#endregion + +#region Digitals + /// + /// High when device is online + /// + public uint IsOnline { get; set; } + /// + /// Range reports video sync feedback for each input + /// + public uint VideoSyncStatus { get; set; } + /// + /// Range reports high if corresponding input's endpoint is online + /// + public uint InputEndpointOnline { get; set; } + /// + /// Range reports high if corresponding output's endpoint is online + /// + public uint OutputEndpointOnline { get; set; } + /// + /// Range reports high if corresponding input's transmitter supports bridging as a separate device for detailed AV switching, HDCP control, etc. + /// + public uint TxAdvancedIsPresent { get; set; } // indicates that there is an attached transmitter that should be bridged to be interacted with + /// + /// Range reports high if corresponding output is disabled by HDCP. + /// + public uint OutputDisabledByHdcp { get; set; } // indicates that there is an attached transmitter that should be bridged to be interacted with +#endregion + +#region Analogs + /// + /// Range sets and reports the current video source for the corresponding output + /// + public uint OutputVideo { get; set; } + /// + /// Range sets and reports the current audio source for the corresponding output + /// + public uint OutputAudio { get; set; } + /// + /// Range sets and reports the current Usb source for the corresponding output + /// + public uint OutputUsb { get; set; } + /// + /// Range sets and reports the current Usb source for the corresponding input + /// + public uint InputUsb { get; set; } + /// + /// Range sets and reports the current HDCP state for the corresponding input card + /// + public uint HdcpSupportState { get; set; } + /// + /// Range reports the highest supported HDCP state level for the corresponding input card + /// + public uint HdcpSupportCapability { get; set; } +#endregion + +#region Serials + /// + /// Range sets and reports the name for the corresponding input card + /// + public uint InputNames { get; set; } + /// + /// Range sets and reports the name for the corresponding output card + /// + public uint OutputNames { get; set; } + /// + /// Range reports the name of the current video source for the corresponding output card + /// + public uint OutputCurrentVideoInputNames { get; set; } + /// + /// Range reports the name of the current audio source for the corresponding output card + /// + public uint OutputCurrentAudioInputNames { get; set; } + /// + /// Range reports the current input resolution for each corresponding input card + /// + public uint InputCurrentResolution { get; set; } +#endregion + + public DmChassisControllerJoinMap() + { + //Digital/Analog + SystemId = 10; // Analog sets/gets SystemId, digital input applies and provides feedback of ID change busy + + //Digital + IsOnline = 11; + VideoSyncStatus = 100; //101-299 + InputEndpointOnline = 500; //501-699 + OutputEndpointOnline = 700; //701-899 + TxAdvancedIsPresent = 1000; //1001-1199 + OutputDisabledByHdcp = 1200; //1201-1399 + + //Analog + OutputVideo = 100; //101-299 + OutputAudio = 300; //301-499 + OutputUsb = 500; //501-699 + InputUsb = 700; //701-899 + HdcpSupportState = 1000; //1001-1199 + HdcpSupportCapability = 1200; //1201-1399 + + + //Serial + InputNames = 100; //101-299 + OutputNames = 300; //301-499 + OutputCurrentVideoInputNames = 2000; //2001-2199 + OutputCurrentAudioInputNames = 2200; //2201-2399 + InputCurrentResolution = 2400; // 2401-2599 + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + SystemId = SystemId + joinOffset; + IsOnline = IsOnline + joinOffset; + OutputVideo = OutputVideo + joinOffset; + OutputAudio = OutputAudio + joinOffset; + OutputUsb = OutputUsb + joinOffset; + InputUsb = InputUsb + joinOffset; + VideoSyncStatus = VideoSyncStatus + joinOffset; + InputNames = InputNames + joinOffset; + OutputNames = OutputNames + joinOffset; + OutputCurrentVideoInputNames = OutputCurrentVideoInputNames + joinOffset; + OutputCurrentAudioInputNames = OutputCurrentAudioInputNames + joinOffset; + InputCurrentResolution = InputCurrentResolution + joinOffset; + InputEndpointOnline = InputEndpointOnline + joinOffset; + OutputEndpointOnline = OutputEndpointOnline + joinOffset; + HdcpSupportState = HdcpSupportState + joinOffset; + HdcpSupportCapability = HdcpSupportCapability + joinOffset; + OutputDisabledByHdcp = OutputDisabledByHdcp + joinOffset; + TxAdvancedIsPresent = TxAdvancedIsPresent + joinOffset; + } + } +} diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs new file mode 100644 index 00000000..0bdedbbf --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class DmRmcControllerJoinMap : JoinMapBase + { + #region Digitals + /// + /// High when device is online (if not attached to a DMP3 or DM chassis with a CPU3 card + /// + public uint IsOnline { get; set; } + #endregion + + #region Serials + /// + /// Reports the current output resolution + /// + public uint CurrentOutputResolution { get; set; } + /// + /// Reports the EDID manufacturer value + /// + public uint EdidManufacturer { get; set; } + /// + /// Reports the EDID Name value + /// + public uint EdidName { get; set; } + /// + /// Reports the EDID preffered timing value + /// + public uint EdidPrefferedTiming { get; set; } + /// + /// Reports the EDID serial number value + /// + public uint EdidSerialNumber { get; set; } + #endregion + + public DmRmcControllerJoinMap() + { + // Digital + IsOnline = 1; + + // Serial + CurrentOutputResolution = 1; + EdidManufacturer = 2; + EdidName = 3; + EdidPrefferedTiming = 4; + EdidSerialNumber = 5; + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + IsOnline = IsOnline + joinOffset; + CurrentOutputResolution = CurrentOutputResolution + joinOffset; + EdidManufacturer = EdidManufacturer + joinOffset; + EdidName = EdidName + joinOffset; + EdidPrefferedTiming = EdidPrefferedTiming + joinOffset; + EdidSerialNumber = EdidSerialNumber + joinOffset; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs new file mode 100644 index 00000000..b01da694 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs @@ -0,0 +1,98 @@ +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class DmTxControllerJoinMap : JoinMapBase + { + #region Digitals + /// + /// High when device is online (if not attached to a DMP3 or DM chassis with a CPU3 card + /// + public uint IsOnline { get; set; } + /// + /// High when video sync is detected + /// + public uint VideoSyncStatus { get; set; } + /// + /// + /// + public uint FreeRunEnabled { get; set; } + #endregion + + #region Analogs + /// + /// Sets and reports the video source + /// + public uint VideoInput { get; set; } + /// + /// Sets and reports the audio source + /// + public uint AudioInput { get; set; } + /// + /// Reports the highest supported HDCP state level for the corresponding input card + /// + public uint HdcpSupportCapability { get; set; } + /// + /// Sets and reports the current HDCP state for the corresponding input port + /// + public uint Port1HdcpState { get; set; } + /// + /// Sets and reports the current HDCP state for the corresponding input port + /// + public uint Port2HdcpState { get; set; } + + /// + /// Sets and reports the current VGA Brightness level + /// + public uint VgaBrightness { get; set; } + + /// + /// Sets and reports the current VGA Contrast level + /// + public uint VgaContrast { get; set; } + #endregion + + #region Serials + /// + /// Reports the current input resolution + /// + public uint CurrentInputResolution { get; set; } + #endregion + + + public DmTxControllerJoinMap() + { + // Digital + IsOnline = 1; + VideoSyncStatus = 2; + FreeRunEnabled = 3; + // Serial + CurrentInputResolution = 1; + // Analog + VideoInput = 1; + AudioInput = 2; + HdcpSupportCapability = 3; + Port1HdcpState = 4; + Port2HdcpState = 5; + VgaBrightness = 6; + VgaContrast = 7; + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + IsOnline = IsOnline + joinOffset; + VideoSyncStatus = VideoSyncStatus + joinOffset; + FreeRunEnabled = FreeRunEnabled + joinOffset; + CurrentInputResolution = CurrentInputResolution + joinOffset; + VideoInput = VideoInput + joinOffset; + AudioInput = AudioInput + joinOffset; + HdcpSupportCapability = HdcpSupportCapability + joinOffset; + Port1HdcpState = Port1HdcpState + joinOffset; + Port2HdcpState = Port2HdcpState + joinOffset; + VgaBrightness = VgaBrightness + joinOffset; + VgaContrast = VgaContrast + joinOffset; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs new file mode 100644 index 00000000..125700b2 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class DmpsAudioOutputControllerJoinMap : JoinMapBase + { + #region Digital/Analog + /// + /// Range of joins for Master Volume + /// Analog join 1 is volume level and feedback + /// Digital join 1 is Mute on and feedback + /// Digital join 2 is Mute off and feedback + /// Digital join 3 is volume up + /// Digital join 4 is volume down + /// + public uint MasterVolume { get; set; } + /// + /// Range of joins for Source Volume + /// Analog join 11 is volume level and feedback + /// Digital join 11 is Mute on and feedback + /// Digital join 12 is Mute off and feedback + /// Digital join 13 is volume up + /// Digital join 14 is volume down + /// + public uint SourceVolume { get; set; } + /// + /// Range of joins for Codec1 Volume (if applicable) + /// Analog join 21 is volume level and feedback + /// Digital join 21 is Mute on and feedback + /// Digital join 22 is Mute off and feedback + /// Digital join 23 is volume up + /// Digital join 24 is volume down + /// + public uint Codec1Volume { get; set; } + /// + /// Range of joins for Codec2 Volume (if applicable) + /// Analog join 31 is volume level and feedback + /// Digital join 31 is Mute on and feedback + /// Digital join 32 is Mute off and feedback + /// Digital join 33 is volume up + /// Digital join 34 is volume down + /// + public uint Codec2Volume { get; set; } + #endregion + + public DmpsAudioOutputControllerJoinMap() + { + MasterVolume = 1; // 1-10 + SourceVolume = 11; // 11-20 + Codec1Volume = 21; // 21-30 + Codec2Volume = 31; // 31-40 + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart; + + MasterVolume = MasterVolume + joinOffset; + SourceVolume = SourceVolume + joinOffset; + Codec1Volume = Codec1Volume + joinOffset; + Codec2Volume = Codec2Volume + joinOffset; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs new file mode 100644 index 00000000..b58611fe --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class DmpsRoutingControllerJoinMap : JoinMapBase + { + #region Digitals + /// + /// Range reports video sync feedback for each input + /// + public uint VideoSyncStatus { get; set; } + /// + /// Range reports high if corresponding input's endpoint is online + /// + public uint InputEndpointOnline { get; set; } + /// + /// Range reports high if corresponding output's endpoint is online + /// + public uint OutputEndpointOnline { get; set; } + #endregion + + + #region Analogs + /// + /// Range sets and reports the current video source for the corresponding output + /// + public uint OutputVideo { get; set; } + /// + /// Range sets and reports the current audio source for the corresponding output + /// + public uint OutputAudio { get; set; } + /// + /// Range sets and reports the current Usb source for the corresponding output + /// + //public uint OutputUsb { get; set; } + ///// + ///// Range sets and reports the current Usb source for the corresponding input + ///// + //public uint InputUsb { get; set; } + ///// + ///// Range sets and reports the current HDCP state for the corresponding input card + ///// + //public uint HdcpSupportState { get; set; } + ///// + ///// Range reports the highest supported HDCP state level for the corresponding input card + ///// + //public uint HdcpSupportCapability { get; set; } + #endregion + + #region Serials + /// + /// Range sets and reports the name for the corresponding input card + /// + public uint InputNames { get; set; } + /// + /// Range sets and reports the name for the corresponding output card + /// + public uint OutputNames { get; set; } + /// + /// Range reports the name of the current video source for the corresponding output card + /// + public uint OutputCurrentVideoInputNames { get; set; } + /// + /// Range reports the name of the current audio source for the corresponding output card + /// + public uint OutputCurrentAudioInputNames { get; set; } + /// + /// Range reports the current input resolution for each corresponding input card + /// + public uint InputCurrentResolution { get; set; } + #endregion + + + public DmpsRoutingControllerJoinMap() + { + //Digital + VideoSyncStatus = 100; //101-299 + InputEndpointOnline = 500; //501-699 + OutputEndpointOnline = 700; //701-899 + + //Analog + OutputVideo = 100; //101-299 + OutputAudio = 300; //301-499 + //OutputUsb = 500; //501-699 + //InputUsb = 700; //701-899 + VideoSyncStatus = 100; //101-299 + //HdcpSupportState = 1000; //1001-1199 + //HdcpSupportCapability = 1200; //1201-1399 + + + //Serial + InputNames = 100; //101-299 + OutputNames = 300; //301-499 + OutputCurrentVideoInputNames = 2000; //2001-2199 + OutputCurrentAudioInputNames = 2200; //2201-2399 + InputCurrentResolution = 2400; // 2401-2599 + InputEndpointOnline = 500; //501-699 + OutputEndpointOnline = 700; //701-899 + + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + OutputVideo = OutputVideo + joinOffset; + OutputAudio = OutputAudio + joinOffset; + //OutputUsb = OutputUsb + joinOffset; + //InputUsb = InputUsb + joinOffset; + VideoSyncStatus = VideoSyncStatus + joinOffset; + InputNames = InputNames + joinOffset; + OutputNames = OutputNames + joinOffset; + OutputCurrentVideoInputNames = OutputCurrentVideoInputNames + joinOffset; + OutputCurrentAudioInputNames = OutputCurrentAudioInputNames + joinOffset; + InputCurrentResolution = InputCurrentResolution + joinOffset; + InputEndpointOnline = InputEndpointOnline + joinOffset; + OutputEndpointOnline = OutputEndpointOnline + joinOffset; + //HdcpSupportState = HdcpSupportState + joinOffset; + //HdcpSupportCapability = HdcpSupportCapability + joinOffset; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GenericLightingJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GenericLightingJoinMap.cs new file mode 100644 index 00000000..242be651 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GenericLightingJoinMap.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Essentials.Core; + + +namespace PepperDash.Essentials.Core.Bridges +{ + public class GenericLightingJoinMap : JoinMapBase + { + public uint IsOnline { get; set; } + public uint SelectScene { get; set; } + public uint LightingSceneOffset { get; set; } + public uint ButtonVisibilityOffset { get; set; } + public uint IntegrationIdSet { get; set; } + + public GenericLightingJoinMap() + { + // Digital + IsOnline = 1; + SelectScene = 1; + IntegrationIdSet = 1; + LightingSceneOffset = 10; + ButtonVisibilityOffset = 40; + // Analog + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + IsOnline = IsOnline + joinOffset; + SelectScene = SelectScene + joinOffset; + LightingSceneOffset = LightingSceneOffset + joinOffset; + ButtonVisibilityOffset = ButtonVisibilityOffset + joinOffset; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GenericRelayControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GenericRelayControllerJoinMap.cs new file mode 100644 index 00000000..e4ccdfbd --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GenericRelayControllerJoinMap.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class GenericRelayControllerJoinMap : JoinMapBase + { + #region Digitals + /// + /// Sets and reports the state of the relay (High = closed, Low = Open) + /// + public uint Relay { get; set; } + #endregion + + public GenericRelayControllerJoinMap() + { + Relay = 1; + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + Relay = Relay + joinOffset; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs new file mode 100644 index 00000000..6e2cd175 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs @@ -0,0 +1,238 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class GlsOccupancySensorBaseJoinMap : JoinMapBase + { + #region Digitals + + /// + /// High when device is online + /// + public uint IsOnline { get; set; } + /// + /// Forces the device to report occupied status + /// + public uint ForceOccupied { get; set; } + /// + /// Forces the device to report vacant status + /// + public uint ForceVacant { get; set; } + /// + /// Enables raw status reporting + /// + public uint EnableRawStates { get; set; } + /// + /// High when raw occupancy is detected + /// + public uint RawOccupancyFeedback { get; set; } + /// + /// High when PIR sensor detects motion + /// + public uint RawOccupancyPirFeedback { get; set; } + /// + /// High when US sensor detects motion + /// + public uint RawOccupancyUsFeedback { get; set; } + /// + /// High when occupancy is detected + /// + public uint RoomOccupiedFeedback { get; set; } + /// + /// Hich when occupancy is detected in the grace period + /// + public uint GraceOccupancyDetectedFeedback { get; set; } + /// + /// High when vacancy is detected + /// + public uint RoomVacantFeedback { get; set; } + + /// + /// Enables the LED Flash when set high + /// + public uint EnableLedFlash { get; set; } + /// + /// Disables the LED flash when set high + /// + public uint DisableLedFlash { get; set; } + /// + /// Enables the Short Timeout + /// + public uint EnableShortTimeout { get; set; } + /// + /// Disables the Short Timout + /// + public uint DisableShortTimeout { get; set; } + /// + /// Set high to enable one technology to trigger occupancy + /// + public uint OrWhenVacated { get; set; } + /// + /// Set high to require both technologies to trigger occupancy + /// + public uint AndWhenVacated { get; set; } + /// + /// Enables Ultrasonic Sensor A + /// + public uint EnableUsA { get; set; } + /// + /// Disables Ultrasonic Sensor A + /// + public uint DisableUsA { get; set; } + /// + /// Enables Ultrasonic Sensor B + /// + public uint EnableUsB { get; set; } + /// + /// Disables Ultrasonic Sensor B + /// + public uint DisableUsB { get; set; } + /// + /// Enables Pir + /// + public uint EnablePir { get; set; } + /// + /// Disables Pir + /// + public uint DisablePir { get; set; } + public uint IncrementUsInOccupiedState { get; set; } + public uint DecrementUsInOccupiedState { get; set; } + public uint IncrementUsInVacantState { get; set; } + public uint DecrementUsInVacantState { get; set; } + public uint IncrementPirInOccupiedState { get; set; } + public uint DecrementPirInOccupiedState { get; set; } + public uint IncrementPirInVacantState { get; set; } + public uint DecrementPirInVacantState { get; set; } + #endregion + + #region Analogs + /// + /// Sets adn reports the remote timeout value + /// + public uint Timeout { get; set; } + /// + /// Reports the local timeout value + /// + public uint TimeoutLocalFeedback { get; set; } + /// + /// Sets the minimum internal photo sensor value and reports the current level + /// + public uint InternalPhotoSensorValue { get; set; } + /// + /// Sets the minimum external photo sensor value and reports the current level + /// + public uint ExternalPhotoSensorValue { get; set; } + + public uint UsSensitivityInOccupiedState { get; set; } + + public uint UsSensitivityInVacantState { get; set; } + + public uint PirSensitivityInOccupiedState { get; set; } + + public uint PirSensitivityInVacantState { get; set; } + #endregion + + #region Serial + public uint Name { get; set; } + #endregion + + public GlsOccupancySensorBaseJoinMap() + { + IsOnline = 1; + ForceOccupied = 2; + ForceVacant = 3; + EnableRawStates = 4; + RoomOccupiedFeedback = 2; + GraceOccupancyDetectedFeedback = 3; + RoomVacantFeedback = 4; + RawOccupancyFeedback = 5; + RawOccupancyPirFeedback = 6; + RawOccupancyUsFeedback = 7; + EnableLedFlash = 11; + DisableLedFlash = 12; + EnableShortTimeout = 13; + DisableShortTimeout = 14; + OrWhenVacated = 15; + AndWhenVacated = 16; + EnableUsA = 17; + DisableUsA = 18; + EnableUsB = 19; + DisableUsB = 20; + EnablePir = 21; + DisablePir = 22; + IncrementUsInOccupiedState = 23; + DecrementUsInOccupiedState = 24; + IncrementUsInVacantState = 25; + DecrementUsInVacantState = 26; + IncrementPirInOccupiedState = 27; + DecrementPirInOccupiedState = 28; + IncrementPirInVacantState = 29; + DecrementPirInVacantState = 30; + + Timeout = 1; + TimeoutLocalFeedback = 2; + InternalPhotoSensorValue = 3; + ExternalPhotoSensorValue = 4; + UsSensitivityInOccupiedState = 5; + UsSensitivityInVacantState = 6; + PirSensitivityInOccupiedState = 7; + PirSensitivityInVacantState = 8; + + Name = 1; + + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + IsOnline = IsOnline + joinOffset; + ForceOccupied = ForceOccupied + joinOffset; + ForceVacant = ForceVacant + joinOffset; + EnableRawStates = EnableRawStates + joinOffset; + RoomOccupiedFeedback = RoomOccupiedFeedback + joinOffset; + GraceOccupancyDetectedFeedback = GraceOccupancyDetectedFeedback + joinOffset; + RoomVacantFeedback = RoomVacantFeedback + joinOffset; + RawOccupancyFeedback = RawOccupancyFeedback + joinOffset; + RawOccupancyPirFeedback = RawOccupancyPirFeedback + joinOffset; + RawOccupancyUsFeedback = RawOccupancyUsFeedback + joinOffset; + EnableLedFlash = EnableLedFlash + joinOffset; + DisableLedFlash = DisableLedFlash + joinOffset; + EnableShortTimeout = EnableShortTimeout + joinOffset; + DisableShortTimeout = DisableShortTimeout + joinOffset; + OrWhenVacated = OrWhenVacated + joinOffset; + AndWhenVacated = AndWhenVacated + joinOffset; + EnableUsA = EnableUsA + joinOffset; + DisableUsA = DisableUsA + joinOffset; + EnableUsB = EnableUsB + joinOffset; + DisableUsB = DisableUsB + joinOffset; + EnablePir = EnablePir + joinOffset; + DisablePir = DisablePir + joinOffset; + IncrementUsInOccupiedState = IncrementUsInOccupiedState + joinOffset; + DecrementUsInOccupiedState = DecrementUsInOccupiedState + joinOffset; + IncrementUsInVacantState = IncrementUsInVacantState + joinOffset; + DecrementUsInVacantState = DecrementUsInVacantState + joinOffset; + IncrementPirInOccupiedState = IncrementPirInOccupiedState + joinOffset; + DecrementPirInOccupiedState = DecrementPirInOccupiedState + joinOffset; + IncrementPirInVacantState = IncrementPirInVacantState + joinOffset; + DecrementPirInVacantState = DecrementPirInVacantState + joinOffset; + + Timeout = Timeout + joinOffset; + TimeoutLocalFeedback = TimeoutLocalFeedback + joinOffset; + InternalPhotoSensorValue = InternalPhotoSensorValue + joinOffset; + ExternalPhotoSensorValue = ExternalPhotoSensorValue + joinOffset; + UsSensitivityInOccupiedState = UsSensitivityInOccupiedState + joinOffset; + UsSensitivityInVacantState = UsSensitivityInVacantState + joinOffset; + PirSensitivityInOccupiedState = PirSensitivityInOccupiedState + joinOffset; + PirSensitivityInVacantState = PirSensitivityInVacantState + joinOffset; + + Name = Name + joinOffset; + } + } + +} diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/HdMdxxxCEControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/HdMdxxxCEControllerJoinMap.cs new file mode 100644 index 00000000..d3769838 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/HdMdxxxCEControllerJoinMap.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class HdMdxxxCEControllerJoinMap : JoinMapBase + { + #region Digitals + /// + /// High when the pair is online + /// + public uint IsOnline { get; set; } + + /// + /// High when the remote end device is online + /// + public uint RemoteEndDetected { get; set; } + + /// + /// Sets Auto Route On and provides feedback + /// + public uint AutoRouteOn { get; set; } + + /// + /// Sets Auto Route Off and provides feedback + /// + public uint AutoRouteOff { get; set; } + + /// + /// Sets Priority Routing On and provides feedback + /// + public uint PriorityRoutingOn { get; set; } + + /// + /// Sets Priority Routing Off and provides feedback + /// + public uint PriorityRoutingOff { get; set; } + + /// + /// Enables OSD and provides feedback + /// + public uint InputOnScreenDisplayEnabled { get; set; } + + /// + /// Disables OSD and provides feedback + /// + public uint InputOnScreenDisplayDisabled { get; set; } + + /// + /// Provides Video Sync Detected feedback for each input + /// + public uint SyncDetected { get; set; } + #endregion + + #region Analogs + /// + /// Sets the video source for the receiver's HDMI out and provides feedback + /// + public uint VideoSource { get; set; } + + /// + /// Indicates the number of sources supported by the Tx/Rx pair + /// + public uint SourceCount { get; set; } + #endregion + + #region Serials + /// + /// Indicates the name of each input port + /// + public uint SourceNames { get; set; } + #endregion + + public HdMdxxxCEControllerJoinMap() + { + //Digital + IsOnline = 1; + RemoteEndDetected = 2; + AutoRouteOn = 3; + AutoRouteOff = 4; + PriorityRoutingOn = 5; + PriorityRoutingOff = 6; + InputOnScreenDisplayEnabled = 7; + InputOnScreenDisplayDisabled = 8; + SyncDetected = 10; // 11-15 + + //Analog + VideoSource = 1; + SourceCount = 2; + + //Serials + SourceNames = 10; // 11-15 + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + IsOnline = IsOnline + joinOffset; + RemoteEndDetected = RemoteEndDetected + joinOffset; + AutoRouteOn = AutoRouteOn + joinOffset; + AutoRouteOff = AutoRouteOff + joinOffset; + PriorityRoutingOn = PriorityRoutingOn + joinOffset; + PriorityRoutingOff = PriorityRoutingOff + joinOffset; + InputOnScreenDisplayEnabled = InputOnScreenDisplayEnabled + joinOffset; + InputOnScreenDisplayDisabled = InputOnScreenDisplayDisabled + joinOffset; + SyncDetected = SyncDetected + joinOffset; + + VideoSource = VideoSource + joinOffset; + SourceCount = SourceCount + joinOffset; + + SourceNames = SourceNames + joinOffset; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IBasicCommunicationJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IBasicCommunicationJoinMap.cs new file mode 100644 index 00000000..3669738e --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IBasicCommunicationJoinMap.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class IBasicCommunicationJoinMap : JoinMapBase + { + #region Digitals + /// + /// Set High to connect, Low to disconnect + /// + public uint Connect { get; set; } + /// + /// Reports Connected State (High = Connected) + /// + public uint Connected { get; set; } + #endregion + + #region Analogs + /// + /// Reports the connections status value + /// + public uint Status { get; set; } + #endregion + + #region Serials + /// + /// Data back from port + /// + public uint TextReceived { get; set; } + /// + /// Sends data to the port + /// + public uint SendText { get; set; } + /// + /// Takes a JSON serialized string that sets a COM port's parameters + /// + public uint SetPortConfig { get; set; } + #endregion + + public IBasicCommunicationJoinMap() + { + TextReceived = 1; + SendText = 1; + SetPortConfig = 2; + Connect = 1; + Connected = 1; + Status = 1; + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + TextReceived = TextReceived + joinOffset; + SendText = SendText + joinOffset; + SetPortConfig = SetPortConfig + joinOffset; + Connect = Connect + joinOffset; + Connected = Connected + joinOffset; + Status = Status + joinOffset; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalInputJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalInputJoinMap.cs new file mode 100644 index 00000000..ba9bcc0f --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalInputJoinMap.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class IDigitalInputJoinMap : JoinMapBase + { + #region Digitals + /// + /// Reports the state of the digital input + /// + public uint InputState { get; set; } + #endregion + + public IDigitalInputJoinMap() + { + InputState = 1; + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + InputState = InputState + joinOffset; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SetTopBoxControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SetTopBoxControllerJoinMap.cs new file mode 100644 index 00000000..dc634ab3 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SetTopBoxControllerJoinMap.cs @@ -0,0 +1,212 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; +using Crestron.SimplSharp.Reflection; + + +namespace PepperDash.Essentials.Core.Bridges +{ + public class SetTopBoxControllerJoinMap : JoinMapBase + { + #region Digitals + public uint DvrList { get; set; } // + public uint Replay { get; set; } + public uint Up { get; set; } // + public uint Down { get; set; } // + public uint Left { get; set; } // + public uint Right { get; set; } // + public uint Select { get; set; } // + public uint Menu { get; set; } // + public uint Exit { get; set; } // + public uint Digit0 { get; set; } // + public uint Digit1 { get; set; } // + public uint Digit2 { get; set; } // + public uint Digit3 { get; set; } // + public uint Digit4 { get; set; } // + public uint Digit5 { get; set; } // + public uint Digit6 { get; set; } // + public uint Digit7 { get; set; } // + public uint Digit8 { get; set; } // + public uint Digit9 { get; set; } // + public uint Dash { get; set; } // + public uint KeypadEnter { get; set; } // + public uint ChannelUp { get; set; } // + public uint ChannelDown { get; set; } // + public uint LastChannel { get; set; } // + public uint Guide { get; set; } // + public uint Info { get; set; } // + public uint Red { get; set; } // + public uint Green { get; set; } // + public uint Yellow { get; set; } // + public uint Blue { get; set; } // + public uint ChapMinus { get; set; } + public uint ChapPlus { get; set; } + public uint FFwd { get; set; } // + public uint Pause { get; set; } // + public uint Play { get; set; } // + public uint Record { get; set; } + public uint Rewind { get; set; } // + public uint Stop { get; set; } // + + public uint PowerOn { get; set; } // + public uint PowerOff { get; set; } // + public uint PowerToggle { get; set; } // + + public uint HasKeypadAccessoryButton1 { get; set; } + public uint HasKeypadAccessoryButton2 { get; set; } + + public uint KeypadAccessoryButton1Press { get; set; } + public uint KeypadAccessoryButton2Press { get; set; } + + + public uint HasDvr { get; set; } + public uint HasPresets { get; set; } + public uint HasNumeric { get; set; } + public uint HasDpad { get; set; } + + + #endregion + + #region Analogs + + #endregion + + #region Strings + public uint Name { get; set; } + public uint LoadPresets { get; set; } + public uint KeypadAccessoryButton1Label { get; set; } + public uint KeypadAccessoryButton2Label { get; set; } + + #endregion + + public SetTopBoxControllerJoinMap() + { + PowerOn = 1; + PowerOff = 2; + PowerToggle = 3; + + HasDpad = 4; + Up = 4; + Down = 5; + Left = 6; + Right = 7; + Select = 8; + Menu = 9; + Exit = 10; + + HasNumeric = 11; + Digit0 = 11; + Digit1 = 12; + Digit2 = 13; + Digit3 = 14; + Digit4 = 15; + Digit5 = 16; + Digit6 = 17; + Digit7 = 18; + Digit8 = 19; + Digit9 = 20; + Dash = 21; + KeypadEnter = 22; + ChannelUp = 23; + ChannelDown = 24; + LastChannel = 25; + + Guide = 26; + Info = 27; + Red = 28; + Green = 29; + Yellow = 30; + Blue = 31; + + HasDvr = 32; + DvrList = 32; + Play = 33; + Pause = 34; + Stop = 35; + FFwd = 36; + Rewind = 37; + ChapPlus = 38; + ChapMinus = 39; + Replay = 40; + Record = 41; + HasKeypadAccessoryButton1 = 42; + KeypadAccessoryButton1Press = 42; + HasKeypadAccessoryButton2 = 43; + KeypadAccessoryButton2Press = 43; + + Name = 1; + KeypadAccessoryButton1Label = 42; + KeypadAccessoryButton2Label = 43; + + LoadPresets = 50; + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + PowerOn += joinOffset; + PowerOff += joinOffset; + PowerToggle += joinOffset; + + HasDpad += joinOffset; + Up += joinOffset; + Down += joinOffset; + Left += joinOffset; + Right += joinOffset; + Select += joinOffset; + Menu += joinOffset; + Exit += joinOffset; + + HasNumeric += joinOffset; + Digit0 += joinOffset; + Digit1 += joinOffset; + Digit2 += joinOffset; + Digit3 += joinOffset; + Digit4 += joinOffset; + Digit5 += joinOffset; + Digit6 += joinOffset; + Digit7 += joinOffset; + Digit8 += joinOffset; + Digit9 += joinOffset; + Dash += joinOffset; + KeypadEnter += joinOffset; + ChannelUp += joinOffset; + ChannelDown += joinOffset; + LastChannel += joinOffset; + + Guide += joinOffset; + Info += joinOffset; + Red += joinOffset; + Green += joinOffset; + Yellow += joinOffset; + Blue += joinOffset; + + HasDvr += joinOffset; + DvrList += joinOffset; + Play += joinOffset; + Pause += joinOffset; + Stop += joinOffset; + FFwd += joinOffset; + Rewind += joinOffset; + ChapPlus += joinOffset; + ChapMinus += joinOffset; + Replay += joinOffset; + Record += joinOffset; + HasKeypadAccessoryButton1 += joinOffset; + KeypadAccessoryButton1Press += joinOffset; + HasKeypadAccessoryButton2 += joinOffset; + KeypadAccessoryButton2Press += joinOffset; + + Name += joinOffset; + KeypadAccessoryButton1Label += joinOffset; + KeypadAccessoryButton2Label += joinOffset; + + LoadPresets += joinOffset; + } + + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/StatusSignControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/StatusSignControllerJoinMap.cs new file mode 100644 index 00000000..7efd049b --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/StatusSignControllerJoinMap.cs @@ -0,0 +1,49 @@ +using System.Linq; +using Crestron.SimplSharp.Reflection; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class StatusSignControllerJoinMap:JoinMapBase + { + public uint IsOnline { get; set; } + public uint Name { get; set; } + public uint RedLed { get; set; } + public uint GreenLed { get; set; } + public uint BlueLed { get; set; } + public uint RedControl { get; set; } + public uint GreenControl { get; set; } + public uint BlueControl { get; set; } + + public StatusSignControllerJoinMap() + { + //digital + IsOnline = 1; + RedControl = 2; + GreenControl = 3; + BlueControl = 4; + + //Analog + RedLed = 2; + GreenLed = 3; + BlueLed = 4; + + //string + Name = 1; + + + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + var properties = + GetType().GetCType().GetProperties().Where(p => p.PropertyType == typeof (uint)).ToList(); + + foreach (var propertyInfo in properties) + { + propertyInfo.SetValue(this, (uint) propertyInfo.GetValue(this, null) + joinOffset, null); + } + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SystemMonitorJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SystemMonitorJoinMap.cs new file mode 100644 index 00000000..b2fd3dfd --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SystemMonitorJoinMap.cs @@ -0,0 +1,225 @@ +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class SystemMonitorJoinMap : JoinMapBase + { + /// + /// Offset to indicate where the range of iterated program joins will start + /// + public uint ProgramStartJoin { get; set; } + + /// + /// Offset to indicate where the range of iterated Ethernet joins will start + /// + public uint EthernetStartJoin { get; set; } + + /// + /// Offset between each program join set + /// + public uint ProgramOffsetJoin { get; set; } + + /// + /// Offset between each Ethernet Interface join set + /// + public uint EthernetOffsetJoin { get; set; } + + #region Digitals + /// + /// Range Sets and reports whether the corresponding program slot is started + /// + public uint ProgramStart { get; set; } + /// + /// Range Sets and reports whether the corresponding program slot is stopped + /// + public uint ProgramStop { get; set; } + /// + /// Range Sets and reports whether the corresponding program is registered + /// + public uint ProgramRegister { get; set; } + /// + /// Range Sets and reports whether the corresponding program is unregistered + /// + public uint ProgramUnregister { get; set; } + #endregion + + #region Analogs + /// + /// Sets and reports the time zone + /// + public uint TimeZone { get; set; } + #endregion + + #region Serials + /// + /// Reports the time zone name + /// + public uint TimeZoneName { get; set; } + /// + /// Reports the IO Controller Version + /// + public uint IOControllerVersion { get; set; } + /// + /// Reports the SNMP App Version + /// + public uint SnmpAppVersion { get; set; } + /// + /// Reports the BACnet App Version + /// + public uint BACnetAppVersion { get; set; } + /// + /// Reports the firmware version + /// + public uint ControllerVersion { get; set; } + + /// + /// Reports the name of the corresponding program + /// + public uint ProgramName { get; set; } + /// + /// Reports the compile time of the corresponding program + /// + public uint ProgramCompiledTime { get; set; } + /// + /// Reports the Crestron Database version of the corresponding program + /// + public uint ProgramCrestronDatabaseVersion { get; set; } + /// + /// Reports the Environment Version of the corresponding program + /// + public uint ProgramEnvironmentVersion { get; set; } + /// + /// Serialized JSON output that aggregates the program info of the corresponding program + /// + public uint AggregatedProgramInfo { get; set; } + /// + /// Reports the controller serial number + /// + public uint SerialNumber { get; set; } + /// + /// Reports the controller model + /// + public uint Model { get; set; } + /// + /// Reports the Host name set on the corresponding interface + /// + public uint HostName { get; set; } + /// + /// Reports the Current IP address set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned address. + /// + public uint CurrentIpAddress { get; set; } + /// + /// Reporst the Current Default Gateway set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned gateway + /// + public uint CurrentDefaultGateway { get; set; } + /// + /// Reports the Current Subnet Mask set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned subnet mask + /// + public uint CurrentSubnetMask { get; set; } + /// + /// Reports the Static IP address set on the corresponding interface. If DHCP is disabled, this will match the Current IP address + /// + public uint StaticIpAddress { get; set; } + /// + /// Reporst the Static Default Gateway set on the corresponding interface. If DHCP is disabled, this will match the Current gateway + /// + public uint StaticDefaultGateway { get; set; } + /// + /// Reports the Current Subnet Mask set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned subnet mask + /// + public uint StaticSubnetMask { get; set; } + /// + /// Reports the current DomainFeedback on the corresponding interface + /// + public uint Domain { get; set; } + /// + /// Reports the current DNS Servers on the corresponding interface + /// + public uint DnsServer { get; set; } + /// + /// Reports the MAC Address of the corresponding interface + /// + public uint MacAddress { get; set; } + /// + /// Reports the DHCP Status of the corresponding interface + /// + public uint DhcpStatus { get; set; } + + /// + /// Reports the current uptime. Updated in 5 minute intervals. + /// + public uint Uptime { get; set; } + + /// + /// Reports the date of the last boot + /// + public uint LastBoot { get; set; } + #endregion + + public SystemMonitorJoinMap() + { + TimeZone = 1; + + TimeZoneName = 1; + IOControllerVersion = 2; + SnmpAppVersion = 3; + BACnetAppVersion = 4; + ControllerVersion = 5; + SerialNumber = 6; + Model = 7; + Uptime = 8; + LastBoot = 9; + + + ProgramStartJoin = 10; + + ProgramOffsetJoin = 5; + + // Offset in groups of 5 joins + ProgramStart = 1; + ProgramStop = 2; + ProgramRegister = 3; + ProgramUnregister = 4; + + ProgramName = 1; + ProgramCompiledTime = 2; + ProgramCrestronDatabaseVersion = 3; + ProgramEnvironmentVersion = 4; + AggregatedProgramInfo = 5; + + EthernetStartJoin = 75; + + EthernetOffsetJoin = 15; + + // Offset in groups of 15 + HostName = 1; + CurrentIpAddress = 2; + CurrentSubnetMask = 3; + CurrentDefaultGateway = 4; + StaticIpAddress = 5; + StaticSubnetMask = 6; + StaticDefaultGateway = 7; + Domain = 8; + DnsServer = 9; + MacAddress = 10; + DhcpStatus = 11; + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + TimeZone = TimeZone + joinOffset; + + TimeZoneName = TimeZoneName + joinOffset; + IOControllerVersion = IOControllerVersion + joinOffset; + SnmpAppVersion = SnmpAppVersion + joinOffset; + BACnetAppVersion = BACnetAppVersion + joinOffset; + ControllerVersion = ControllerVersion + joinOffset; + + // Sets the initial join value where the iterated program joins will begin + ProgramStartJoin = ProgramStartJoin + joinOffset; + EthernetStartJoin = EthernetStartJoin + joinOffset; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs index 3673a384..904bfc74 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs @@ -39,5 +39,25 @@ namespace PepperDash.Essentials.Core.Config return SourceLists[key]; } + + /// + /// Checks Devices for an item with a Key that matches and returns it if found. Otherwise, retunes null + /// + /// Key of desired device + /// + public DeviceConfig GetDeviceForKey(string key) + { + if (string.IsNullOrEmpty(key)) + return null; + + var deviceConfig = Devices.FirstOrDefault(d => d.Key.Equals(key)); + + if (deviceConfig != null) + return deviceConfig; + else + { + return null; + } + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/CecPortController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/CecPortController.cs index a2493e3c..1ab38d89 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/CecPortController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/CecPortController.cs @@ -20,6 +20,17 @@ namespace PepperDash.Essentials.Core ICec Port; + public CecPortController(string key, Func postActivationFunc, + EssentialsControlPropertiesConfig config):base(key) + { + AddPostActivationAction(() => + { + Port = postActivationFunc(config); + + Port.StreamCec.CecChange += StreamCec_CecChange; + }); + } + public CecPortController(string key, ICec port) : base(key) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/ComPortController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/ComPortController.cs index a5a5b14f..3fbfb43d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/ComPortController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/ComPortController.cs @@ -21,6 +21,19 @@ namespace PepperDash.Essentials.Core ComPort Port; ComPort.ComPortSpec Spec; + public ComPortController(string key, Func postActivationFunc, + ComPort.ComPortSpec spec, EssentialsControlPropertiesConfig config) : base(key) + { + Spec = spec; + + AddPostActivationAction(() => + { + Port = postActivationFunc(config); + + RegisterAndConfigureComPort(); + }); + } + public ComPortController(string key, ComPort port, ComPort.ComPortSpec spec) : base(key) { @@ -34,27 +47,31 @@ namespace PepperDash.Essentials.Core Spec = spec; //IsConnected = new BoolFeedback(CommonBoolCue.IsConnected, () => true); - if (Port.Parent is CrestronControlSystem) - { - - - var result = Port.Register(); - if (result != eDeviceRegistrationUnRegistrationResponse.Success) - { - Debug.Console(0, this, "ERROR: Cannot register Com port: {0}", result); - return; // false - } - } - var specResult = Port.SetComPortSpec(Spec); - if (specResult != 0) - { - Debug.Console(0, this, "WARNING: Cannot set comspec"); - return; // false - } - Port.SerialDataReceived += new ComPortDataReceivedEvent(Port_SerialDataReceived); + RegisterAndConfigureComPort(); } - ~ComPortController() + private void RegisterAndConfigureComPort() + { + if (Port.Parent is CrestronControlSystem) + { + var result = Port.Register(); + if (result != eDeviceRegistrationUnRegistrationResponse.Success) + { + Debug.Console(0, this, "ERROR: Cannot register Com port: {0}", result); + return; // false + } + } + + var specResult = Port.SetComPortSpec(Spec); + if (specResult != 0) + { + Debug.Console(0, this, "WARNING: Cannot set comspec"); + return; + } + Port.SerialDataReceived += Port_SerialDataReceived; + } + + ~ComPortController() { Port.SerialDataReceived -= Port_SerialDataReceived; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/CommFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/CommFactory.cs index 23aea272..94110fd7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/CommFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/CommFactory.cs @@ -48,10 +48,10 @@ namespace PepperDash.Essentials.Core switch (controlConfig.Method) { case eControlMethod.Com: - comm = new ComPortController(deviceConfig.Key + "-com", GetComPort(controlConfig), controlConfig.ComParams); + comm = new ComPortController(deviceConfig.Key + "-com", GetComPort, controlConfig.ComParams, controlConfig); break; case eControlMethod.Cec: - comm = new CecPortController(deviceConfig.Key + "-cec", GetCecPort(controlConfig)); + comm = new CecPortController(deviceConfig.Key + "-cec", GetCecPort, controlConfig); break; case eControlMethod.IR: break; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/ConsoleCommMockDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/ConsoleCommMockDevice.cs index d833aafa..f360e52b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/ConsoleCommMockDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/ConsoleCommMockDevice.cs @@ -5,10 +5,12 @@ using System.Text; using Crestron.SimplSharp; using PepperDash.Core; +using PepperDash.Essentials.Core.Config; + namespace PepperDash.Essentials.Core { - public class ConsoleCommMockDevice : Device, ICommunicationMonitor + public class ConsoleCommMockDevice : EssentialsDevice, ICommunicationMonitor { public IBasicCommunication Communication { get; private set; } public CommunicationGather PortGather { get; private set; } @@ -71,4 +73,21 @@ namespace PepperDash.Essentials.Core } } + public class ConsoleCommMockDeviceFactory : EssentialsDeviceFactory + { + public ConsoleCommMockDeviceFactory() + { + TypeNames = new List() { "commmock" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Comm Mock Device"); + var comm = CommFactory.CreateCommForDevice(dc); + var props = Newtonsoft.Json.JsonConvert.DeserializeObject( + dc.Properties.ToString()); + return new ConsoleCommMockDevice(dc.Key, dc.Name, props, comm); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/GenericComm.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/GenericComm.cs index 1998f62e..41438832 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/GenericComm.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Comm and IR/GenericComm.cs @@ -1,12 +1,11 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - +using Crestron.SimplSharp.CrestronSockets; +using Crestron.SimplSharpPro.DeviceSupport; using Newtonsoft.Json; using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Devices; using PepperDash.Essentials.Core.Config; @@ -16,8 +15,8 @@ namespace PepperDash.Essentials.Core /// /// Serves as a generic wrapper class for all styles of IBasicCommuncation ports /// - public class - GenericComm : ReconfigurableDevice + [Description("Generic communication wrapper class for any IBasicCommunication type")] + public class GenericComm : ReconfigurableBridgableDevice { EssentialsControlPropertiesConfig PropertiesConfig; @@ -29,6 +28,13 @@ namespace PepperDash.Essentials.Core PropertiesConfig = CommFactory.GetControlPropertiesConfig(config); CommPort = CommFactory.CreateCommForDevice(config); + + } + + public static IKeyed BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Generic Comm Device"); + return new GenericComm(dc); } public void SetPortConfig(string portConfig) @@ -37,7 +43,7 @@ namespace PepperDash.Essentials.Core try { PropertiesConfig = JsonConvert.DeserializeObject - (portConfig.ToString()); + (portConfig); } catch (Exception e) { @@ -51,6 +57,69 @@ namespace PepperDash.Essentials.Core ConfigWriter.UpdateDeviceConfig(config); } - - } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new IBasicCommunicationJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + joinMap.OffsetJoinNumbers(joinStart); + + if (CommPort == null) + { + Debug.Console(1, this, "Unable to link device '{0}'. CommPort is null", Key); + return; + } + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + // this is a permanent event handler. This cannot be -= from event + CommPort.TextReceived += (s, a) => + { + Debug.Console(2, this, "RX: {0}", a.Text); + trilist.SetString(joinMap.TextReceived, a.Text); + }; + trilist.SetStringSigAction(joinMap.SendText, s => CommPort.SendText(s)); + trilist.SetStringSigAction(joinMap.SetPortConfig, SetPortConfig); + + + var sComm = this as ISocketStatus; + if (sComm == null) return; + sComm.ConnectionChange += (s, a) => + { + trilist.SetUshort(joinMap.Status, (ushort)(a.Client.ClientStatus)); + trilist.SetBool(joinMap.Connected, a.Client.ClientStatus == + SocketStatus.SOCKET_STATUS_CONNECTED); + }; + + trilist.SetBoolSigAction(joinMap.Connect, b => + { + if (b) + { + sComm.Connect(); + } + else + { + sComm.Disconnect(); + } + }); + } + } + + public class GenericCommFactory : EssentialsDeviceFactory + { + public GenericCommFactory() + { + TypeNames = new List() { "genericComm" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Generic Comm Device"); + return new GenericComm(dc); + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs index 0a288944..b3fc7d89 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs @@ -64,16 +64,23 @@ namespace PepperDash.Essentials.Core.Config if (configFiles != null) { + Debug.Console(2, "{0} config files found matching pattern", configFiles.Length); + if (configFiles.Length > 1) { Debug.Console(0, Debug.ErrorLogLevel.Error, "****Error: Multiple Portal Configuration files present. Please ensure only a single file exists and reset program.****"); return false; } - else + else if (configFiles.Length == 1) { Debug.Console(0, Debug.ErrorLogLevel.Notice, "Found Portal config file: '{0}'", filePath); } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "No config file found."); + return false; + } } else { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigWriter.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigWriter.cs index 1cd7b93e..cb361d28 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigWriter.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigWriter.cs @@ -19,7 +19,8 @@ namespace PepperDash.Essentials.Core.Config public const long WriteTimeout = 30000; - public static CTimer WriteTimer; + public static CTimer WriteTimer; + static CCriticalSection fileLock = new CCriticalSection(); /// /// Updates the config properties of a device @@ -127,8 +128,6 @@ namespace PepperDash.Essentials.Core.Config Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file"); - var fileLock = new CCriticalSection(); - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath); try diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/C2nRts/C2nRthsController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/C2nRts/C2nRthsController.cs index 865acd1c..0bc48d80 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/C2nRts/C2nRthsController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/C2nRts/C2nRthsController.cs @@ -1,14 +1,19 @@ -using System; +using System.Collections.Generic; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.GeneralIO; +using Newtonsoft.Json; using PepperDash.Core; -using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; + namespace PepperDash.Essentials.Core.CrestronIO { - public class C2nRthsController:CrestronGenericBaseDevice + [Description("Wrapper class for the C2N-RTHS sensor")] + public class C2nRthsController : CrestronGenericBridgeableBaseDevice { - private C2nRths _device; + private readonly C2nRths _device; public IntFeedback TemperatureFeedback { get; private set; } public IntFeedback HumidityFeedback { get; private set; } @@ -20,7 +25,7 @@ namespace PepperDash.Essentials.Core.CrestronIO TemperatureFeedback = new IntFeedback(() => _device.TemperatureFeedback.UShortValue); HumidityFeedback = new IntFeedback(() => _device.HumidityFeedback.UShortValue); - _device.BaseEvent += DeviceOnBaseEvent; + if (_device != null) _device.BaseEvent += DeviceOnBaseEvent; } private void DeviceOnBaseEvent(GenericBase device, BaseEventArgs args) @@ -40,5 +45,46 @@ namespace PepperDash.Essentials.Core.CrestronIO { _device.TemperatureFormat.BoolValue = setToC; } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new C2nRthsControllerJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + + trilist.SetBoolSigAction(joinMap.TemperatureFormat, SetTemperatureFormat); + + IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + TemperatureFeedback.LinkInputSig(trilist.UShortInput[joinMap.Temperature]); + HumidityFeedback.LinkInputSig(trilist.UShortInput[joinMap.Humidity]); + + trilist.StringInput[joinMap.Name].StringValue = Name; + } + } + + public class C2nRthsControllerFactory : EssentialsDeviceFactory + { + public C2nRthsControllerFactory() + { + TypeNames = new List() { "c2nrths" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new C2N-RTHS Device"); + + var control = CommFactory.GetControlPropertiesConfig(dc); + var cresnetId = control.CresnetIdInt; + + return new C2nRthsController(dc.Key, dc.Name, new C2nRths(cresnetId, Global.ControlSystem)); + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/CenIoDigIn104Controller.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/CenIoDigIn104Controller.cs index 6bdfc25c..5112f3aa 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/CenIoDigIn104Controller.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/CenIoDigIn104Controller.cs @@ -5,6 +5,8 @@ using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.GeneralIO; +using PepperDash.Essentials.Core.Config; + using PepperDash.Core; @@ -13,7 +15,8 @@ namespace PepperDash.Essentials.Core /// /// Wrapper class for CEN-IO-DIGIN-104 digital input module /// - public class CenIoDigIn104Controller : Device, IDigitalInputPorts + [Description("Wrapper class for the CEN-IO-DIGIN-104 diginal input module")] + public class CenIoDigIn104Controller : EssentialsDevice, IDigitalInputPorts { public CenIoDi104 Di104 { get; private set; } @@ -37,4 +40,23 @@ namespace PepperDash.Essentials.Core #endregion } + + public class CenIoDigIn104ControllerFactory : EssentialsDeviceFactory + { + public CenIoDigIn104ControllerFactory() + { + TypeNames = new List() { "ceniodigin104" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new CEN-DIGIN-104 Device"); + + var control = CommFactory.GetControlPropertiesConfig(dc); + var ipid = control.IpIdInt; + + return new CenIoDigIn104Controller(dc.Key, dc.Name, new Crestron.SimplSharpPro.GeneralIO.CenIoDi104(ipid, Global.ControlSystem)); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericDigitalInputDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericDigitalInputDevice.cs index 3c1849f9..3d3383e9 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericDigitalInputDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericDigitalInputDevice.cs @@ -4,12 +4,16 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; - +using Crestron.SimplSharpPro.DeviceSupport; +using Newtonsoft.Json; using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; + namespace PepperDash.Essentials.Core.CrestronIO { - public class GenericDigitalInputDevice : Device, IDigitalInput + public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput { public DigitalInput InputPort { get; private set; } @@ -30,7 +34,7 @@ namespace PepperDash.Essentials.Core.CrestronIO InputPort = inputPort; - InputPort.StateChange += new DigitalInputEventHandler(InputPort_StateChange); + InputPort.StateChange += InputPort_StateChange; } @@ -39,5 +43,120 @@ namespace PepperDash.Essentials.Core.CrestronIO InputStateFeedback.FireUpdate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new IDigitalInputJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + try + { + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + // Link feedback for input state + InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState]); + } + catch (Exception e) + { + Debug.Console(1, this, "Unable to link device '{0}'. Input is null", Key); + Debug.Console(1, this, "Error: {0}", e); + } + } } + + public class GenericDigitalInputDeviceFactory : EssentialsDeviceFactory + { + public GenericDigitalInputDeviceFactory() + { + TypeNames = new List() { "digitalinput" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Digtal Input Device"); + + var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); + + IDigitalInputPorts portDevice; + + if (props.PortDeviceKey == "processor") + portDevice = Global.ControlSystem as IDigitalInputPorts; + else + portDevice = DeviceManager.GetDeviceForKey(props.PortDeviceKey) as IDigitalInputPorts; + + if (portDevice == null) + Debug.Console(0, "ERROR: Unable to add digital input device with key '{0}'. Port Device does not support digital inputs", dc.Key); + else + { + var cs = (portDevice as CrestronControlSystem); + if (cs == null) + { + Debug.Console(0, "ERROR: Port device for [{0}] is not control system", props.PortDeviceKey); + return null; + } + + if (cs.SupportsVersiport) + { + Debug.Console(1, "Attempting to add Digital Input device to Versiport port '{0}'", props.PortNumber); + + if (props.PortNumber > cs.NumberOfVersiPorts) + { + Debug.Console(0, "WARNING: Cannot add Vesiport {0} on {1}. Out of range", + props.PortNumber, props.PortDeviceKey); + return null; + } + + Versiport vp = cs.VersiPorts[props.PortNumber]; + + if (!vp.Registered) + { + var regSuccess = vp.Register(); + if (regSuccess == eDeviceRegistrationUnRegistrationResponse.Success) + { + Debug.Console(1, "Successfully Created Digital Input Device on Versiport"); + return new GenericVersiportDigitalInputDevice(dc.Key, vp, props); + } + else + { + Debug.Console(0, "WARNING: Attempt to register versiport {0} on device with key '{1}' failed: {2}", + props.PortNumber, props.PortDeviceKey, regSuccess); + return null; + } + } + } + else if (cs.SupportsDigitalInput) + { + Debug.Console(1, "Attempting to add Digital Input device to Digital Input port '{0}'", props.PortNumber); + + if (props.PortNumber > cs.NumberOfDigitalInputPorts) + { + Debug.Console(0, "WARNING: Cannot register DIO port {0} on {1}. Out of range", + props.PortNumber, props.PortDeviceKey); + return null; + } + + DigitalInput digitalInput = cs.DigitalInputPorts[props.PortNumber]; + + if (!digitalInput.Registered) + { + if (digitalInput.Register() == eDeviceRegistrationUnRegistrationResponse.Success) + { + Debug.Console(1, "Successfully Created Digital Input Device on Digital Input"); + return new GenericDigitalInputDevice(dc.Key, digitalInput); + } + else + Debug.Console(0, "WARNING: Attempt to register digital input {0} on device with key '{1}' failed.", + props.PortNumber, props.PortDeviceKey); + } + } + } + return null; + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericVersiportInputDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericVersiportInputDevice.cs index 4c5359b9..90ff4fa0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericVersiportInputDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericVersiportInputDevice.cs @@ -12,7 +12,7 @@ namespace PepperDash.Essentials.Core.CrestronIO /// /// Represents a generic digital input deviced tied to a versiport /// - public class GenericVersiportDigitalInputDevice : Device, IDigitalInput + public class GenericVersiportDigitalInputDevice : EssentialsDevice, IDigitalInput { public Versiport InputPort { get; private set; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs index 4786cb2b..aac9de44 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs @@ -4,15 +4,18 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; - +using Crestron.SimplSharpPro.DeviceSupport; +using Newtonsoft.Json; using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.Core.CrestronIO { /// /// Represents a generic device controlled by relays /// - public class GenericRelayDevice : Device, ISwitchedOutput + public class GenericRelayDevice : EssentialsBridgeableDevice, ISwitchedOutput { public Relay RelayOutput { get; private set; } @@ -65,5 +68,107 @@ namespace PepperDash.Essentials.Core.CrestronIO } #endregion + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new GenericRelayControllerJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + if (RelayOutput == null) + { + Debug.Console(1, this, "Unable to link device '{0}'. Relay is null", Key); + return; + } + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + trilist.SetBoolSigAction(joinMap.Relay, b => + { + if (b) + CloseRelay(); + else + OpenRelay(); + }); + + // feedback for relay state + + OutputIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Relay]); + } } + + public class GenericRelayDeviceFactory : EssentialsDeviceFactory + { + public GenericRelayDeviceFactory() + { + TypeNames = new List() { "relayoutput" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Generic Relay Device"); + + var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); + var key = dc.Key; + + IRelayPorts portDevice; + + if (props.PortDeviceKey == "processor") + portDevice = Global.ControlSystem as IRelayPorts; + else + portDevice = DeviceManager.GetDeviceForKey(props.PortDeviceKey) as IRelayPorts; + + if (portDevice == null) + Debug.Console(0, "Unable to add relay device with key '{0}'. Port Device does not support relays", key); + else + { + var cs = (portDevice as CrestronControlSystem); + + if (cs != null) + { + // The relay is on a control system processor + if (!cs.SupportsRelay || props.PortNumber > cs.NumberOfRelayPorts) + { + Debug.Console(0, "Port Device: {0} does not support relays or does not have enough relays"); + return null; + } + } + else + { + // The relay is on another device type + + if (props.PortNumber > portDevice.NumberOfRelayPorts) + { + Debug.Console(0, "Port Device: {0} does not have enough relays"); + return null; + } + } + + Relay relay = portDevice.RelayPorts[props.PortNumber]; + + if (!relay.Registered) + { + if (relay.Register() == eDeviceRegistrationUnRegistrationResponse.Success) + return new GenericRelayDevice(key, relay); + else + Debug.Console(0, "Attempt to register relay {0} on device with key '{1}' failed.", props.PortNumber, props.PortDeviceKey); + } + else + { + return new GenericRelayDevice(key, relay); + } + + // Future: Check if portDevice is 3-series card or other non control system that supports versiports + } + + return null; + + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/StatusSign/StatusSignController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/StatusSign/StatusSignController.cs index b83eae37..ca679bce 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/StatusSign/StatusSignController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/StatusSign/StatusSignController.cs @@ -1,14 +1,19 @@ using System; +using System.Collections.Generic; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.GeneralIO; +using Newtonsoft.Json; using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.Core.CrestronIO { - public class StatusSignController:CrestronGenericBaseDevice + [Description("Wrapper class for the Crestron StatusSign device")] + public class StatusSignController : CrestronGenericBridgeableBaseDevice { - private StatusSign _device; + private readonly StatusSign _device; public BoolFeedback RedLedEnabledFeedback { get; private set; } public BoolFeedback GreenLedEnabledFeedback { get; private set; } @@ -45,7 +50,7 @@ namespace PepperDash.Essentials.Core.CrestronIO BlueLedBrightnessFeedback = new IntFeedback(() => (int) _device.Leds[(uint) StatusSign.Led.eLedColor.Blue].BrightnessFeedback); - _device.BaseEvent += _device_BaseEvent; + if (_device != null) _device.BaseEvent += _device_BaseEvent; } void _device_BaseEvent(GenericBase device, BaseEventArgs args) @@ -103,5 +108,75 @@ namespace PepperDash.Essentials.Core.CrestronIO Debug.Console(1, this, "Error converting value to Blue LED brightness. value: {0}", blue); } } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new StatusSignControllerJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + trilist.SetBoolSigAction(joinMap.RedControl, b => EnableControl(trilist, joinMap, this)); + trilist.SetBoolSigAction(joinMap.GreenControl, b => EnableControl(trilist, joinMap, this)); + trilist.SetBoolSigAction(joinMap.BlueControl, b => EnableControl(trilist, joinMap, this)); + + trilist.SetUShortSigAction(joinMap.RedLed, u => SetColor(trilist, joinMap, this)); + trilist.SetUShortSigAction(joinMap.GreenLed, u => SetColor(trilist, joinMap, this)); + trilist.SetUShortSigAction(joinMap.BlueLed, u => SetColor(trilist, joinMap, this)); + + trilist.StringInput[joinMap.Name].StringValue = Name; + + IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + RedLedEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RedControl]); + BlueLedEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.BlueControl]); + GreenLedEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.GreenControl]); + + RedLedBrightnessFeedback.LinkInputSig(trilist.UShortInput[joinMap.RedLed]); + BlueLedBrightnessFeedback.LinkInputSig(trilist.UShortInput[joinMap.BlueLed]); + GreenLedBrightnessFeedback.LinkInputSig(trilist.UShortInput[joinMap.GreenLed]); + } + + private static void EnableControl(BasicTriList triList, StatusSignControllerJoinMap joinMap, + StatusSignController device) + { + var redEnable = triList.BooleanOutput[joinMap.RedControl].BoolValue; + var greenEnable = triList.BooleanOutput[joinMap.GreenControl].BoolValue; + var blueEnable = triList.BooleanOutput[joinMap.BlueControl].BoolValue; + device.EnableLedControl(redEnable, greenEnable, blueEnable); + } + + private static void SetColor(BasicTriList triList, StatusSignControllerJoinMap joinMap, + StatusSignController device) + { + var redBrightness = triList.UShortOutput[joinMap.RedLed].UShortValue; + var greenBrightness = triList.UShortOutput[joinMap.GreenLed].UShortValue; + var blueBrightness = triList.UShortOutput[joinMap.BlueLed].UShortValue; + + device.SetColor(redBrightness, greenBrightness, blueBrightness); + } + } + + public class StatusSignControllerFactory : EssentialsDeviceFactory + { + public StatusSignControllerFactory() + { + TypeNames = new List() { "statussign" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new StatusSign Device"); + + var control = CommFactory.GetControlPropertiesConfig(dc); + var cresnetId = control.CresnetIdInt; + + return new StatusSignController(dc.Key, dc.Name, new StatusSign(cresnetId, Global.ControlSystem)); + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs index 6d6a5fb4..7866075f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs @@ -1,19 +1,15 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; +using System.Linq; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; - using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Core { /// /// A bridge class to cover the basic features of GenericBase hardware /// - public class CrestronGenericBaseDevice : Device, IOnline, IHasFeedback, ICommunicationMonitor, IUsageTracking + public abstract class CrestronGenericBaseDevice : EssentialsDevice, IOnline, IHasFeedback, ICommunicationMonitor, IUsageTracking { public virtual GenericBase Hardware { get; protected set; } @@ -32,7 +28,7 @@ namespace PepperDash.Essentials.Core /// public bool PreventRegistration { get; protected set; } - public CrestronGenericBaseDevice(string key, string name, GenericBase hardware) + protected CrestronGenericBaseDevice(string key, string name, GenericBase hardware) : base(key, name) { Feedbacks = new FeedbackCollection(); @@ -40,13 +36,7 @@ namespace PepperDash.Essentials.Core Hardware = hardware; IsOnline = new BoolFeedback("IsOnlineFeedback", () => Hardware.IsOnline); IsRegistered = new BoolFeedback("IsRegistered", () => Hardware.Registered); - IpConnectionsText = new StringFeedback("IpConnectionsText", () => - { - if (Hardware.ConnectedIpList != null) - return string.Join(",", Hardware.ConnectedIpList.Select(cip => cip.DeviceIpAddress).ToArray()); - else - return string.Empty; - }); + IpConnectionsText = new StringFeedback("IpConnectionsText", () => Hardware.ConnectedIpList != null ? string.Join(",", Hardware.ConnectedIpList.Select(cip => cip.DeviceIpAddress).ToArray()) : string.Empty); AddToFeedbackList(IsOnline, IpConnectionsText); CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, hardware, 120000, 300000); @@ -78,7 +68,7 @@ namespace PepperDash.Essentials.Core f.FireUpdate(); } - Hardware.OnlineStatusChange += new OnlineStatusChangeEventHandler(Hardware_OnlineStatusChange); + Hardware.OnlineStatusChange += Hardware_OnlineStatusChange; CommunicationMonitor.Start(); return true; @@ -99,8 +89,8 @@ namespace PepperDash.Essentials.Core return success; } - - /// + + /// /// Adds feedback(s) to the list /// /// @@ -108,12 +98,11 @@ namespace PepperDash.Essentials.Core { foreach (var f in newFbs) { - if (f != null) + if (f == null) continue; + + if (!Feedbacks.Contains(f)) { - if (!Feedbacks.Contains(f)) - { - Feedbacks.Add(f); - } + Feedbacks.Add(f); } } } @@ -140,6 +129,17 @@ namespace PepperDash.Essentials.Core #endregion } + public abstract class CrestronGenericBridgeableBaseDevice : CrestronGenericBaseDevice, IBridgeAdvanced + { + protected CrestronGenericBridgeableBaseDevice(string key, string name, GenericBase hardware) : base(key, name, hardware) + { + } + + + public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge); + } + + //*********************************************************************************** public class CrestronGenericBaseDeviceEventIds { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsBridgeableDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsBridgeableDevice.cs new file mode 100644 index 00000000..0812ca4e --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsBridgeableDevice.cs @@ -0,0 +1,18 @@ +using Crestron.SimplSharpPro.DeviceSupport; +using PepperDash.Essentials.Core.Bridges; + +namespace PepperDash.Essentials.Core +{ + public abstract class EssentialsBridgeableDevice:EssentialsDevice, IBridgeAdvanced + { + protected EssentialsBridgeableDevice(string key) : base(key) + { + } + + protected EssentialsBridgeableDevice(string key, string name) : base(key, name) + { + } + + public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge); + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs new file mode 100644 index 00000000..410c7a48 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharp.Reflection; + +using PepperDash.Core; +using PepperDash.Essentials.Core.Config; + +namespace PepperDash.Essentials.Core +{ + /// + /// Defines the basic needs for an EssentialsDevice to enable it to be build by an IDeviceFactory class + /// + [Description("The base Essentials Device Class")] + public abstract class EssentialsDevice : Device + { + protected EssentialsDevice(string key) + : base(key) + { + + } + + protected EssentialsDevice(string key, string name) + : base(key, name) + { + + } + } + + [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)] + public class DescriptionAttribute : Attribute + { + private string _Description; + + public DescriptionAttribute(string description) + { + Debug.Console(2, "Setting Description: {0}", description); + _Description = description; + } + + public string Description + { + get { return _Description; } + } + } + + [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)] + public class ConfigSnippetAttribute : Attribute + { + private string _ConfigSnippet; + + public ConfigSnippetAttribute(string configSnippet) + { + Debug.Console(2, "Setting Description {0}", configSnippet); + _ConfigSnippet = configSnippet; + } + + public string ConfigSnippet + { + get { return _ConfigSnippet; } + } + } + + /// + /// Devices the basic needs for a Device Factory + /// + public abstract class EssentialsDeviceFactory : IDeviceFactory where T:EssentialsDevice + { + #region IDeviceFactory Members + + /// + /// A list of strings that can be used in the type property of a DeviceConfig object to build an instance of this device + /// + public List TypeNames { get; protected set; } + + /// + /// Loads an item to the DeviceFactory.FactoryMethods dictionary for each entry in the TypeNames list + /// + public void LoadTypeFactories() + { + foreach (var typeName in TypeNames) + { + Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName); + var attributes = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[]; + string description = attributes[0].Description; + DeviceFactory.AddFactoryForType(typeName.ToLower(), description, typeof(T), BuildDevice); + } + } + + /// + /// The method that will build the device + /// + /// The device config + /// An instance of the device + public abstract EssentialsDevice BuildDevice(DeviceConfig dc); + + #endregion + } + + /// + /// Devices the basic needs for a Device Factory + /// + public abstract class EssentialsPluginDeviceFactory : EssentialsDeviceFactory, IPluginDeviceFactory where T : EssentialsDevice + { + /// + /// Specifies the minimum version of Essentials required for a plugin to run. Must use the format Major.Minor.Build (ex. "1.4.33") + /// + public string MinimumEssentialsFrameworkVersion { get; protected set; } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PC/InRoomPc.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PC/InRoomPc.cs index 9a13106f..03e884f0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PC/InRoomPc.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PC/InRoomPc.cs @@ -4,6 +4,7 @@ using System.Linq; using Crestron.SimplSharpPro; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Routing; using PepperDash.Core; @@ -12,7 +13,7 @@ namespace PepperDash.Essentials.Core.Devices /// /// This DVD class should cover most IR, one-way DVD and Bluray fuctions /// - public class InRoomPc : Device, IHasFeedback, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking + public class InRoomPc : EssentialsDevice, IHasFeedback, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking { public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } } public string IconName { get; set; } @@ -63,4 +64,19 @@ namespace PepperDash.Essentials.Core.Devices #endregion } + + public class InRoomPcFactory : EssentialsDeviceFactory + { + public InRoomPcFactory() + { + TypeNames = new List() { "inroompc" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new InRoomPc Device"); + return new InRoomPc(dc.Key, dc.Name); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PC/Laptop.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PC/Laptop.cs index a1a8b30b..a2864d77 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PC/Laptop.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PC/Laptop.cs @@ -4,6 +4,7 @@ using System.Linq; using Crestron.SimplSharpPro; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Routing; using PepperDash.Core; @@ -12,7 +13,7 @@ namespace PepperDash.Essentials.Core.Devices /// /// This DVD class should cover most IR, one-way DVD and Bluray fuctions /// - public class Laptop : Device, IHasFeedback, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking + public class Laptop : EssentialsDevice, IHasFeedback, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking { public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } } public string IconName { get; set; } @@ -63,4 +64,18 @@ namespace PepperDash.Essentials.Core.Devices #endregion } + + public class LaptopFactory : EssentialsDeviceFactory + { + public LaptopFactory() + { + TypeNames = new List() { "laptop" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Laptop Device"); + return new Core.Devices.Laptop(dc.Key, dc.Name); + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs index 3acfcac0..7b4f1c99 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs @@ -3,8 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; - +using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.Core.Devices @@ -12,13 +13,13 @@ namespace PepperDash.Essentials.Core.Devices /// /// /// - public abstract class ReconfigurableDevice : Device + public abstract class ReconfigurableDevice : EssentialsDevice { public event EventHandler ConfigChanged; public DeviceConfig Config { get; private set; } - public ReconfigurableDevice(DeviceConfig config) + protected ReconfigurableDevice(DeviceConfig config) : base(config.Key) { SetNameHelper(config); @@ -60,4 +61,13 @@ namespace PepperDash.Essentials.Core.Devices ConfigWriter.UpdateDeviceConfig(config); } } + + public abstract class ReconfigurableBridgableDevice : ReconfigurableDevice, IBridgeAdvanced + { + protected ReconfigurableBridgableDevice(DeviceConfig config) : base(config) + { + } + + public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge); + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/SourceListItem.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/SourceListItem.cs index efa2b2ad..601d75a7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/SourceListItem.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/SourceListItem.cs @@ -67,36 +67,68 @@ namespace PepperDash.Essentials.Core [JsonProperty("name")] public string Name { get; set; } + /// + /// Specifies and icon for the source list item + /// [JsonProperty("icon")] public string Icon { get; set; } + /// + /// Alternate icon + /// [JsonProperty("altIcon")] public string AltIcon { get; set; } + /// + /// Indicates if the item should be included in the source list + /// [JsonProperty("includeInSourceList")] public bool IncludeInSourceList { get; set; } + /// + /// Used to specify the order of the items in the source list when displayed + /// [JsonProperty("order")] public int Order { get; set; } + /// + /// The key of the device for volume control + /// [JsonProperty("volumeControlKey")] public string VolumeControlKey { get; set; } + /// + /// The type of source list item + /// [JsonProperty("type")] [JsonConverter(typeof(StringEnumConverter))] public eSourceListItemType Type { get; set; } + /// + /// The list of routes to execute for this source list item + /// [JsonProperty("routeList")] public List RouteList { get; set; } + /// + /// Indicates if this source should be disabled for sharing to the far end call participants via codec content + /// [JsonProperty("disableCodecSharing")] public bool DisableCodecSharing { get; set; } + /// + /// Indicates if this source should be disabled for routing to a shared output + /// [JsonProperty("disableRoutedSharing")] public bool DisableRoutedSharing { get; set; } [JsonProperty("destinations")] public List Destinations { get; set; } + /// + /// A means to reference a source list for this source item, in the event that this source has an input that can have sources routed to it + /// + [JsonProperty("sourceListKey")] + public string SourceListKey { get; set; } public SourceListItem() { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/BasicIrDisplay.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/BasicIrDisplay.cs index 3ffd0bf4..fd83f2a2 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/BasicIrDisplay.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/BasicIrDisplay.cs @@ -8,11 +8,13 @@ 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; namespace PepperDash.Essentials.Core { - public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IPower, IWarmingCooling + public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IBridgeAdvanced { public IrOutputPortController IrPort { get; private set; } public ushort IrPulseTime { get; set; } @@ -201,5 +203,33 @@ namespace PepperDash.Essentials.Core } #endregion + + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge); + } } + + public class BasicIrDisplayFactory : EssentialsDeviceFactory + { + public BasicIrDisplayFactory() + { + TypeNames = new List() { "basicirdisplay" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new BasicIrDisplay Device"); + var ir = IRPortHelper.GetIrPort(dc.Properties); + if (ir != null) + { + var display = new BasicIrDisplay(dc.Key, dc.Name, ir.Port, ir.FileName); + display.IrPulseTime = 200; // Set default pulse time for IR commands. + return display; + } + + return null; + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs index 98659ab2..cf317f40 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs @@ -4,11 +4,13 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; - +using Newtonsoft.Json; using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Core @@ -16,7 +18,7 @@ namespace PepperDash.Essentials.Core /// /// /// - public abstract class DisplayBase : Device, IHasFeedback, IRoutingSinkWithSwitching, IPower, IWarmingCooling, IUsageTracking + public abstract class DisplayBase : EssentialsDevice, IHasFeedback, IRoutingSinkWithSwitching, IPower, IWarmingCooling, IUsageTracking { public event SourceInfoChangeHandler CurrentSourceChange; @@ -71,7 +73,7 @@ namespace PepperDash.Essentials.Core #endregion - public DisplayBase(string key, string name) + protected DisplayBase(string key, string name) : base(key, name) { PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc); @@ -113,6 +115,132 @@ namespace PepperDash.Essentials.Core public abstract void ExecuteSwitch(object selector); + protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey, + EiscApiAdvanced bridge) + { + var inputNumber = 0; + var inputKeys = new List(); + + var joinMap = new DisplayControllerJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + Debug.Console(0, "Linking to Display: {0}", displayDevice.Name); + + trilist.StringInput[joinMap.Name].StringValue = displayDevice.Name; + + var commMonitor = displayDevice as ICommunicationMonitor; + if (commMonitor != null) + { + commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + } + + var inputNumberFeedback = new IntFeedback(() => inputNumber); + + // Two way feedbacks + var twoWayDisplay = displayDevice as TwoWayDisplayBase; + + if (twoWayDisplay != null) + { + trilist.SetBool(joinMap.IsTwoWayDisplay, true); + + twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => Debug.Console(0, "CurrentInputFeedback_OutputChange {0}", a.StringValue); + + + inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect]); + } + + // Power Off + trilist.SetSigTrueAction(joinMap.PowerOff, () => + { + inputNumber = 102; + inputNumberFeedback.FireUpdate(); + displayDevice.PowerOff(); + }); + + displayDevice.PowerIsOnFeedback.OutputChange += (o, a) => + { + if (!a.BoolValue) + { + inputNumber = 102; + inputNumberFeedback.FireUpdate(); + + } + else + { + inputNumber = 0; + inputNumberFeedback.FireUpdate(); + } + }; + + displayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff]); + + // PowerOn + trilist.SetSigTrueAction(joinMap.PowerOn, () => + { + inputNumber = 0; + inputNumberFeedback.FireUpdate(); + displayDevice.PowerOn(); + }); + + + displayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn]); + + var count = 1; + foreach (var input in displayDevice.InputPorts) + { + inputKeys.Add(input.Key); + var tempKey = inputKeys.ElementAt(count - 1); + trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset + count), () => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector)); + Debug.Console(2, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}", joinMap.InputSelectOffset + count, displayDevice.InputPorts[tempKey].Key.ToString()); + trilist.StringInput[(ushort)(joinMap.InputNamesOffset + count)].StringValue = input.Key.ToString(); + count++; + } + + Debug.Console(2, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect); + trilist.SetUShortSigAction(joinMap.InputSelect, (a) => + { + if (a == 0) + { + displayDevice.PowerOff(); + inputNumber = 0; + } + else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber) + { + displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector); + inputNumber = a; + } + else if (a == 102) + { + displayDevice.PowerToggle(); + + } + if (twoWayDisplay != null) + inputNumberFeedback.FireUpdate(); + }); + + + var volumeDisplay = displayDevice as IBasicVolumeControls; + if (volumeDisplay == null) return; + + trilist.SetBoolSigAction(joinMap.VolumeUp, volumeDisplay.VolumeUp); + trilist.SetBoolSigAction(joinMap.VolumeDown, volumeDisplay.VolumeDown); + trilist.SetSigTrueAction(joinMap.VolumeMute, volumeDisplay.MuteToggle); + + var volumeDisplayWithFeedback = volumeDisplay as IBasicVolumeWithFeedback; + + if (volumeDisplayWithFeedback == null) return; + + trilist.SetUShortSigAction(joinMap.VolumeLevel, volumeDisplayWithFeedback.SetVolume); + volumeDisplayWithFeedback.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel]); + volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMute]); + } } /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/MockDisplay.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/MockDisplay.cs index bf728e8a..dcdba6d8 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/MockDisplay.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/MockDisplay.cs @@ -4,20 +4,22 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Routing; - +using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.Core { /// /// /// - public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback + public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, IBridgeAdvanced { public RoutingInputPort HdmiIn1 { get; private set; } @@ -174,5 +176,25 @@ namespace PepperDash.Essentials.Core } #endregion + + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge); + } } + + public class MockDisplayFactory : EssentialsDeviceFactory + { + public MockDisplayFactory() + { + TypeNames = new List() { "mockdisplay" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Mock Display Device"); + return new MockDisplay(dc.Key, dc.Name); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs index c07bc010..1904867d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs @@ -5,6 +5,7 @@ using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.GeneralIO; +using Crestron.SimplSharp.Reflection; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; @@ -13,26 +14,77 @@ using PepperDash.Essentials.Core.Touchpanels; namespace PepperDash.Essentials.Core { + public class DeviceFactoryWrapper + { + public CType CType { get; set; } + public string Description { get; set; } + public Func FactoryMethod { get; set; } + + public DeviceFactoryWrapper() + { + CType = null; + Description = "Not Available"; + } + } + public class DeviceFactory { + public DeviceFactory() + { + var assy = Assembly.GetExecutingAssembly(); + PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy); + + var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract); + + if (types != null) + { + foreach (var type in types) + { + try + { + var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); + factory.LoadTypeFactories(); + } + catch (Exception e) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name); + } + } + } + } + /// /// A dictionary of factory methods, keyed by config types, added by plugins. /// These methods are looked up and called by GetDevice in this class. /// - static Dictionary> FactoryMethods = - new Dictionary>(StringComparer.OrdinalIgnoreCase); + static Dictionary FactoryMethods = + new Dictionary(StringComparer.OrdinalIgnoreCase); /// /// Adds a plugin factory method /// /// /// - public static void AddFactoryForType(string type, Func method) + public static void AddFactoryForType(string typeName, Func method) { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", type); - DeviceFactory.FactoryMethods.Add(type, method); + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); + DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method}); } + public static void AddFactoryForType(string typeName, string description, CType cType, Func method) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); + + if(FactoryMethods.ContainsKey(typeName)) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to add type: '{0}'. Already exists in DeviceFactory", typeName); + return; + } + + var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method }; + DeviceFactory.FactoryMethods.Add(typeName, wrapper); + } + /// /// The factory method for Core "things". Also iterates the Factory methods that have /// been loaded from plugins @@ -48,43 +100,50 @@ namespace PepperDash.Essentials.Core var typeName = dc.Type.ToLower(); - // Check for types that have been added by plugin dlls. if (FactoryMethods.ContainsKey(typeName)) { Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from plugin", dc.Type); - return FactoryMethods[typeName](dc); + return FactoryMethods[typeName].FactoryMethod(dc); } - // Check "core" types - if (typeName == "genericcomm") - { - Debug.Console(1, "Factory Attempting to create new Generic Comm Device"); - return new GenericComm(dc); - } - if (typeName == "ceniodigin104") - { - var control = CommFactory.GetControlPropertiesConfig(dc); - var ipid = control.IpIdInt; - - return new CenIoDigIn104Controller(key, name, new Crestron.SimplSharpPro.GeneralIO.CenIoDi104(ipid, Global.ControlSystem)); - } - if (typeName == "statussign") - { - var control = CommFactory.GetControlPropertiesConfig(dc); - var cresnetId = control.CresnetIdInt; - - return new StatusSignController(key, name, new StatusSign(cresnetId, Global.ControlSystem)); - } - if (typeName == "c2nrths") - { - var control = CommFactory.GetControlPropertiesConfig(dc); - var cresnetId = control.CresnetIdInt; - - return new C2nRthsController(key, name, new C2nRths(cresnetId, Global.ControlSystem)); - } - return null; } + + /// + /// Prints the type names and associated metadata from the FactoryMethods collection. + /// + /// + public static void GetDeviceFactoryTypes(string filter) + { + Dictionary types = new Dictionary(); + + if (!string.IsNullOrEmpty(filter)) + { + types = FactoryMethods.Where(k => k.Key.Contains(filter)).ToDictionary(k => k.Key, k => k.Value); + } + else + { + types = FactoryMethods; + } + + Debug.Console(0, "Device Types:"); + + foreach (var type in types.OrderBy(t => t.Key)) + { + var description = type.Value.Description; + var cType = "Not Specified by Plugin"; + + if(type.Value.CType != null) + { + cType = type.Value.CType.FullName; + } + + Debug.Console(0, + @"Type: '{0}' + CType: '{1}' + Description: {2}", type.Key, cType, description); + } + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/IDeviceFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/IDeviceFactory.cs new file mode 100644 index 00000000..91e073f2 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/IDeviceFactory.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharp.Reflection; + +using PepperDash.Core; +using PepperDash.Essentials.Core.Config; + +namespace PepperDash.Essentials.Core +{ + /// + /// Defines a class that is capable of loading device types + /// + public interface IDeviceFactory + { + /// + /// Loads all the types to the DeviceFactory + /// + void LoadTypeFactories(); + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolFeedback.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolFeedback.cs index 60a09df8..f46b4767 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolFeedback.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolFeedback.cs @@ -34,18 +34,34 @@ namespace PepperDash.Essentials.Core List LinkedCrestronFeedbacks = new List(); + /// + /// Creates the feedback with the Func as described. + /// + /// + /// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge, + /// it will NOT reflect an actual value from a device until has been called + /// + /// Delegate to invoke when this feedback needs to be updated public BoolFeedback(Func valueFunc) : this(null, valueFunc) { } + /// + /// Creates the feedback with the Func as described. + /// + /// + /// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge, + /// it will NOT reflect an actual value from a device until has been called + /// + /// Key to find this Feedback + /// Delegate to invoke when this feedback needs to be updated public BoolFeedback(string key, Func valueFunc) : base(key) { ValueFunc = valueFunc; } - public override void FireUpdate() { bool newValue = InTestMode ? TestValue : ValueFunc.Invoke(); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/IntFeedback.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/IntFeedback.cs index 4a278148..25390c2c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/IntFeedback.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/IntFeedback.cs @@ -23,11 +23,28 @@ namespace PepperDash.Essentials.Core Func ValueFunc; List LinkedInputSigs = new List(); + /// + /// Creates the feedback with the Func as described. + /// + /// + /// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge, + /// it will NOT reflect an actual value from a device until has been called + /// + /// Delegate to invoke when this feedback needs to be updated public IntFeedback(Func valueFunc) : this(null, valueFunc) { } + /// + /// Creates the feedback with the Func as described. + /// + /// + /// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge, + /// it will NOT reflect an actual value from a device until has been called + /// + /// Key to find this Feedback + /// Delegate to invoke when this feedback needs to be updated public IntFeedback(string key, Func valueFunc) : base(key) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/StringFeedback.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/StringFeedback.cs index b02c02f0..56251a2e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/StringFeedback.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/StringFeedback.cs @@ -7,6 +7,7 @@ using Crestron.SimplSharpPro; namespace PepperDash.Essentials.Core { + public class StringFeedback : Feedback { public override string StringValue { get { return _StringValue; } } // ValueFunc.Invoke(); } } @@ -18,16 +19,33 @@ namespace PepperDash.Essentials.Core public string TestValue { get; private set; } /// - /// Evalutated on FireUpdate + /// Evaluated on FireUpdate /// public Func ValueFunc { get; private set; } List LinkedInputSigs = new List(); + /// + /// Creates the feedback with the Func as described. + /// + /// + /// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge, + /// it will NOT reflect an actual value from a device until has been called + /// + /// Delegate to invoke when this feedback needs to be updated public StringFeedback(Func valueFunc) : this(null, valueFunc) { } + /// + /// Creates the feedback with the Func as described. + /// + /// + /// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge, + /// it will NOT reflect an actual value from a device until has been called + /// + /// Key to find this Feedback + /// Delegate to invoke when this feedback needs to be updated public StringFeedback(string key, Func valueFunc) : base(key) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index 00edd9bd..1134f3e2 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -332,7 +332,7 @@ namespace PepperDash.Essentials.Core.Fusion FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsRoomBase).PowerOnToDefaultOrLastSource); - FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as IRunRouteAction).RunRouteAction("roomOff")); + FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as IRunRouteAction).RunRouteAction("roomOff", Room.SourceListKey)); // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig); FusionRoom.ErrorMessage.InputSig.StringValue = "3: 7 Errors: This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;"; @@ -1086,7 +1086,7 @@ namespace PepperDash.Essentials.Core.Fusion SourceToFeedbackSigs.Add(pSrc, sigD.InputSig); // And respond to selection in Fusion - sigD.OutputSig.SetSigFalseAction(() => (Room as IRunRouteAction).RunRouteAction(routeKey)); + sigD.OutputSig.SetSigFalseAction(() => (Room as IRunRouteAction).RunRouteAction(routeKey, Room.SourceListKey)); } catch (Exception) { @@ -1288,7 +1288,7 @@ namespace PepperDash.Essentials.Core.Fusion // Current Source var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig); - defaultDisplaySourceNone.OutputSig.UserObject = new Action(b => { if (!b) (Room as IRunRouteAction).RunRouteAction("roomOff"); }); ; + defaultDisplaySourceNone.OutputSig.UserObject = new Action(b => { if (!b) (Room as IRunRouteAction).RunRouteAction("roomOff", Room.SourceListKey); }); ; } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs index 4ef68066..2f3e1823 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs @@ -98,25 +98,47 @@ namespace PepperDash.Essentials.Core { Debug.Console(2, "Comparing running version '{0}' to minimum version '{1}'", AssemblyVersion, minimumVersion); - var runtimeVersion = Regex.Match(AssemblyVersion, @"^(\d*).(\d*).(\d*)$"); + if (String.IsNullOrEmpty(minimumVersion)) + { + Debug.Console(0,"Plugin does not specify a minimum version. Loading plugin may not work as expected. Proceeding with loading plugin"); + return true; + } + + var runtimeVersion = Regex.Match(AssemblyVersion, @"^(\d*).(\d*).(\d*).*"); var runtimeVersionMajor = Int16.Parse(runtimeVersion.Groups[1].Value); var runtimeVersionMinor = Int16.Parse(runtimeVersion.Groups[2].Value); var runtimeVersionBuild = Int16.Parse(runtimeVersion.Groups[3].Value); - // Check for beta build version - if (runtimeVersionMajor == 0) + var runtimeVer = new Version(runtimeVersionMajor, runtimeVersionMinor, runtimeVersionBuild); + + Version minimumVer; + try { - Debug.Console(2, "Running Beta Build. Bypassing Dependency Check."); - return true; + minimumVer = new Version(minimumVersion); + } + catch + { + Debug.Console(2, "unable to parse minimum version {0}. Bypassing plugin load.", minimumVersion); + return false; } + + // Check for beta build version + if (runtimeVer.Major != 0) + { + return runtimeVer.CompareTo(minimumVer) >= 0; + } + + Debug.Console(2, "Running Local Build. Bypassing Dependency Check."); + return true; + + /* var minVersion = Regex.Match(minimumVersion, @"^(\d*).(\d*).(\d*)$"); if(!minVersion.Success) { - Debug.Console(2, "minimumVersion String does not match format xx.yy.zz"); - return false; + } var minVersionMajor = Int16.Parse(minVersion.Groups[1].Value); @@ -135,6 +157,7 @@ namespace PepperDash.Essentials.Core return false; return true; + */ } static Global() diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs index 2d7bfc51..8f792659 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using Crestron.SimplSharp; +using Crestron.SimplSharp.Reflection; +using PepperDash.Core; using PepperDash.Essentials.Core.Config; +using Newtonsoft.Json; + namespace PepperDash.Essentials.Core { public static class JoinMapHelper @@ -15,25 +17,41 @@ namespace PepperDash.Essentials.Core /// /// /// - public static string GetJoinMapForDevice(string joinMapKey) + public static string GetSerializedJoinMapForDevice(string joinMapKey) { if (string.IsNullOrEmpty(joinMapKey)) return null; var joinMap = ConfigReader.ConfigObject.JoinMaps[joinMapKey]; - if (joinMap != null) - { - return joinMap; - } - else - return null; + return joinMap; } + + /// + /// Attempts to find a custom join map by key and returns it deserialized if found + /// + /// + /// + public static Dictionary TryGetJoinMapAdvancedForDevice(string joinMapKey) + { + if (string.IsNullOrEmpty(joinMapKey)) + return null; + + var joinMapSerialzed = ConfigReader.ConfigObject.JoinMaps[joinMapKey]; + + if (joinMapSerialzed == null) return null; + + var joinMapData = JsonConvert.DeserializeObject>(joinMapSerialzed); + + return joinMapData; + } + } /// /// Base class for join maps /// + [Obsolete("This is being deprecated in favor of JoinMapBaseAdvanced")] public abstract class JoinMapBase { /// @@ -42,8 +60,407 @@ namespace PepperDash.Essentials.Core /// public abstract void OffsetJoinNumbers(uint joinStart); + /// + /// The collection of joins and associated metadata + /// + public Dictionary Joins = new Dictionary(); + + /// + /// Prints the join information to console + /// + public void PrintJoinMapInfo() + { + Debug.Console(0, "{0}:\n", GetType().Name); + + // Get the joins of each type and print them + Debug.Console(0, "Digitals:"); + var digitals = Joins.Where(j => (j.Value.JoinType & eJoinType.Digital) == eJoinType.Digital).ToDictionary(j => j.Key, j => j.Value); + Debug.Console(2, "Found {0} Digital Joins", digitals.Count); + PrintJoinList(GetSortedJoins(digitals)); + + Debug.Console(0, "Analogs:"); + var analogs = Joins.Where(j => (j.Value.JoinType & eJoinType.Analog) == eJoinType.Analog).ToDictionary(j => j.Key, j => j.Value); + Debug.Console(2, "Found {0} Analog Joins", analogs.Count); + PrintJoinList(GetSortedJoins(analogs)); + + Debug.Console(0, "Serials:"); + var serials = Joins.Where(j => (j.Value.JoinType & eJoinType.Serial) == eJoinType.Serial).ToDictionary(j => j.Key, j => j.Value); + Debug.Console(2, "Found {0} Serial Joins", serials.Count); + PrintJoinList(GetSortedJoins(serials)); + + } + + /// + /// Returns a sorted list by JoinNumber + /// + /// + /// + List> GetSortedJoins(Dictionary joins) + { + var sortedJoins = joins.ToList(); + + sortedJoins.Sort((pair1, pair2) => pair1.Value.JoinNumber.CompareTo(pair2.Value.JoinNumber)); + + return sortedJoins; + } + + void PrintJoinList(List> joins) + { + foreach (var join in joins) + { + Debug.Console(0, + @"Join Number: {0} | Label: '{1}' | JoinSpan: '{2}' | Type: '{3}' | Capabilities: '{4}'", + join.Value.JoinNumber, + join.Value.Label, + join.Value.JoinSpan, + join.Value.JoinType.ToString(), + join.Value.JoinCapabilities.ToString()); + } + } + + /// + /// Returns the join number for the join with the specified key + /// + /// + /// + public uint GetJoinForKey(string key) + { + return Joins.ContainsKey(key) ? Joins[key].JoinNumber : 0; + } + + /// + /// Returns the join span for the join with the specified key + /// + /// + /// + public uint GetJoinSpanForKey(string key) + { + return Joins.ContainsKey(key) ? Joins[key].JoinSpan : 0; + } + } + + /// + /// Base class for join maps + /// + public abstract class JoinMapBaseAdvanced + { + protected uint JoinOffset; + + /// + /// The collection of joins and associated metadata + /// + public Dictionary Joins { get; private set; } + + protected JoinMapBaseAdvanced(uint joinStart) + { + Joins = new Dictionary(); + + JoinOffset = joinStart - 1; + } + + protected JoinMapBaseAdvanced(uint joinStart, Type type):this(joinStart) + { + AddJoins(type); + } + + protected void AddJoins(Type type) + { + // Add all the JoinDataComplete properties to the Joins Dictionary and pass in the offset + //Joins = this.GetType() + // .GetCType() + // .GetFields(BindingFlags.Public | BindingFlags.Instance) + // .Where(field => field.IsDefined(typeof(JoinNameAttribute), true)) + // .Select(field => (JoinDataComplete)field.GetValue(this)) + // .ToDictionary(join => join.GetNameAttribute(), join => + // { + // join.SetJoinOffset(_joinOffset); + // return join; + // }); + + //type = this.GetType(); <- this wasn't working because 'this' was always the base class, never the derived class + var fields = + type.GetCType() + .GetFields(BindingFlags.Public | BindingFlags.Instance) + .Where(f => f.IsDefined(typeof (JoinNameAttribute), true)); + + foreach (var field in fields) + { + var childClass = Convert.ChangeType(this, type, null); + + var value = field.GetValue(childClass) as JoinDataComplete; //this here is JoinMapBaseAdvanced, not the child class. JoinMapBaseAdvanced has no fields. + + if (value == null) + { + Debug.Console(0, "Unable to caset base class to {0}", type.Name); + continue; + } + + value.SetJoinOffset(JoinOffset); + + var joinName = value.GetNameAttribute(field); + + if (String.IsNullOrEmpty(joinName)) continue; + + Joins.Add(joinName, value); + } + + + PrintJoinMapInfo(); + } + + /// + /// Prints the join information to console + /// + public void PrintJoinMapInfo() + { + Debug.Console(0, "{0}:\n", GetType().Name); + + // Get the joins of each type and print them + Debug.Console(0, "Digitals:"); + var digitals = Joins.Where(j => (j.Value.Metadata.JoinType & eJoinType.Digital) == eJoinType.Digital).ToDictionary(j => j.Key, j => j.Value); + Debug.Console(2, "Found {0} Digital Joins", digitals.Count); + PrintJoinList(GetSortedJoins(digitals)); + + Debug.Console(0, "Analogs:"); + var analogs = Joins.Where(j => (j.Value.Metadata.JoinType & eJoinType.Analog) == eJoinType.Analog).ToDictionary(j => j.Key, j => j.Value); + Debug.Console(2, "Found {0} Analog Joins", analogs.Count); + PrintJoinList(GetSortedJoins(analogs)); + + Debug.Console(0, "Serials:"); + var serials = Joins.Where(j => (j.Value.Metadata.JoinType & eJoinType.Serial) == eJoinType.Serial).ToDictionary(j => j.Key, j => j.Value); + Debug.Console(2, "Found {0} Serial Joins", serials.Count); + PrintJoinList(GetSortedJoins(serials)); + + } + + /// + /// Returns a sorted list by JoinNumber + /// + /// + /// + List> GetSortedJoins(Dictionary joins) + { + var sortedJoins = joins.ToList(); + + sortedJoins.Sort((pair1, pair2) => pair1.Value.JoinNumber.CompareTo(pair2.Value.JoinNumber)); + + return sortedJoins; + } + + void PrintJoinList(List> joins) + { + foreach (var join in joins) + { + Debug.Console(0, + @"Join Number: {0} | JoinSpan: '{1}' | Label: '{2}' | Type: '{3}' | Capabilities: '{4}'", + join.Value.JoinNumber, + join.Value.JoinSpan, + join.Value.Metadata.Label, + join.Value.Metadata.JoinType.ToString(), + join.Value.Metadata.JoinCapabilities.ToString()); + } + } + + /// + /// Attempts to find the matching key for the custom join and if found overwrites the default JoinData with the custom + /// + /// + public void SetCustomJoinData(Dictionary joinData) + { + foreach (var customJoinData in joinData) + { + var join = Joins[customJoinData.Key]; + + if (join != null) + { + join.SetCustomJoinData(customJoinData.Value); + } + else + { + Debug.Console(2, "No mathcing key found in join map for: '{0}'", customJoinData.Key); + } + } + + PrintJoinMapInfo(); + } + + ///// + ///// Returns the join number for the join with the specified key + ///// + ///// + ///// + //public uint GetJoinForKey(string key) + //{ + // return Joins.ContainsKey(key) ? Joins[key].JoinNumber : 0; + //} + + + ///// + ///// Returns the join span for the join with the specified key + ///// + ///// + ///// + //public uint GetJoinSpanForKey(string key) + //{ + // return Joins.ContainsKey(key) ? Joins[key].JoinSpan : 0; + //} + } + + /// + /// Read = Provides feedback to SIMPL + /// Write = Responds to sig values from SIMPL + /// + [Flags] + public enum eJoinCapabilities + { + None = 0, + ToSIMPL = 1, + FromSIMPL = 2, + ToFromSIMPL = ToSIMPL | FromSIMPL + } + + [Flags] + public enum eJoinType + { + None = 0, + Digital = 1, + Analog = 2, + Serial = 4, + DigitalAnalog = Digital | Analog, + DigitalSerial = Digital | Serial, + AnalogSerial = Analog | Serial, + DigitalAnalogSerial = Digital | Analog | Serial + } + + /// + /// Metadata describing the join + /// + public class JoinMetadata + { + /// + /// Join number (based on join offset value) + /// + [JsonProperty("joinNumber")] + [Obsolete] + public uint JoinNumber { get; set; } + /// + /// Join range span. If join indicates the start of a range of joins, this indicated the maximum number of joins in the range + /// + [Obsolete] + [JsonProperty("joinSpan")] + public uint JoinSpan { get; set; } + + /// + /// A label for the join to better describe it's usage + /// + [JsonProperty("label")] + public string Label { get; set; } + /// + /// Signal type(s) + /// + [JsonProperty("joinType")] + public eJoinType JoinType { get; set; } + /// + /// Indicates whether the join is read and/or write + /// + [JsonProperty("joinCapabilities")] + public eJoinCapabilities JoinCapabilities { get; set; } + /// + /// Indicates a set of valid values (particularly if this translates to an enum + /// + [JsonProperty("validValues")] + public string[] ValidValues { get; set; } } + /// + /// Data describing the join. Can be + /// + public class JoinData + { + /// + /// Join number (based on join offset value) + /// + [JsonProperty("joinNumber")] + public uint JoinNumber { get; set; } + /// + /// Join range span. If join indicates the start of a range of joins, this indicated the maximum number of joins in the range + /// + [JsonProperty("joinSpan")] + public uint JoinSpan { get; set; } + } + /// + /// A class to aggregate the JoinData and JoinMetadata for a join + /// + public class JoinDataComplete + { + private uint _joinOffset; + + private JoinData _data; + public JoinMetadata Metadata { get; set; } + + public JoinDataComplete(JoinData data, JoinMetadata metadata) + { + _data = data; + Metadata = metadata; + } + + /// + /// Sets the join offset value + /// + /// + public void SetJoinOffset(uint joinOffset) + { + _joinOffset = joinOffset; + } + + /// + /// The join number (including the offset) + /// + public uint JoinNumber + { + get { return _data.JoinNumber+ _joinOffset; } + set { _data.JoinNumber = value; } + } + + public uint JoinSpan + { + get { return _data.JoinSpan; } + } + + public void SetCustomJoinData(JoinData customJoinData) + { + _data = customJoinData; + } + + public string GetNameAttribute(MemberInfo memberInfo) + { + var name = string.Empty; + var attribute = (JoinNameAttribute)CAttribute.GetCustomAttribute(memberInfo, typeof(JoinNameAttribute)); + + if (attribute == null) return name; + + name = attribute.Name; + Debug.Console(2, "JoinName Attribute value: {0}", name); + return name; + } + } + + [AttributeUsage(AttributeTargets.All)] + public class JoinNameAttribute : Attribute + { + private string _Name; + + public JoinNameAttribute(string name) + { + Debug.Console(2, "Setting Attribute Name: {0}", name); + _Name = name; + } + + public string Name + { + get { return _Name; } + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs index af779c16..c22745c0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs @@ -4,12 +4,14 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; - +using Crestron.SimplSharpPro.DeviceSupport; +using Newtonsoft.Json; using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Core.Lighting { - public abstract class LightingBase : Device, ILightingScenes + public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes { #region ILightingScenes Members @@ -23,8 +25,7 @@ namespace PepperDash.Essentials.Core.Lighting #endregion - - public LightingBase(string key, string name) + protected LightingBase(string key, string name) : base(key, name) { LightingScenes = new List(); @@ -69,6 +70,41 @@ namespace PepperDash.Essentials.Core.Lighting } } + protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart, + string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new GenericLightingJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + Debug.Console(0, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString()); + + // GenericLighitng Actions & FeedBack + trilist.SetUShortSigAction(joinMap.SelectScene, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u])); + + var sceneIndex = 1; + foreach (var scene in lightingDevice.LightingScenes) + { + var tempIndex = sceneIndex - 1; + trilist.SetSigTrueAction((uint)(joinMap.LightingSceneOffset + sceneIndex), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[tempIndex])); + scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.LightingSceneOffset + sceneIndex)]); + trilist.StringInput[(uint)(joinMap.LightingSceneOffset + sceneIndex)].StringValue = scene.Name; + trilist.BooleanInput[(uint)(joinMap.ButtonVisibilityOffset + sceneIndex)].BoolValue = true; + sceneIndex++; + } + + + + return joinMap; + } + } public class LightingScene diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Microphone Privacy/MicrophonePrivacyController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Microphone Privacy/MicrophonePrivacyController.cs index e238c40e..ece2c65f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Microphone Privacy/MicrophonePrivacyController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Microphone Privacy/MicrophonePrivacyController.cs @@ -6,6 +6,7 @@ using Crestron.SimplSharp; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.CrestronIO; @@ -15,7 +16,7 @@ namespace PepperDash.Essentials.Core.Privacy /// Used for applications where one or more microphones with momentary contact closure outputs are used to /// toggle the privacy state of the room. Privacy state feedback is represented /// - public class MicrophonePrivacyController : Device + public class MicrophonePrivacyController : EssentialsDevice { MicrophonePrivacyControllerConfig Config; @@ -225,4 +226,21 @@ namespace PepperDash.Essentials.Core.Privacy } } } + + public class MicrophonePrivacyControllerFactory : EssentialsDeviceFactory + { + public MicrophonePrivacyControllerFactory() + { + TypeNames = new List() { "microphoneprivacycontroller" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new MIcrophonePrivacyController Device"); + var props = Newtonsoft.Json.JsonConvert.DeserializeObject(dc.Properties.ToString()); + + return new Core.Privacy.MicrophonePrivacyController(dc.Key, props); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs index 4cc245e0..3f791467 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs @@ -1,15 +1,12 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.Diagnostics; - using PepperDash.Core; -using PepperDash.Essentials.Core; - using Newtonsoft.Json; using Newtonsoft.Json.Converters; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Core.Monitoring { @@ -17,20 +14,34 @@ namespace PepperDash.Essentials.Core.Monitoring /// Wrapper for the static SystemMonitor class to extend functionality and provide external access /// to SystemMonitor via APIs /// - public class SystemMonitorController : Device + public class SystemMonitorController : EssentialsBridgeableDevice { + private const long UptimePollTime = 300000; + private CTimer _uptimePollTimer; + + private string _uptime; + private string _lastStart; + public event EventHandler SystemMonitorPropertiesChanged; public Dictionary ProgramStatusFeedbackCollection; + public Dictionary EthernetStatusFeedbackCollection; - public IntFeedback TimeZoneFeedback { get; set; } - public StringFeedback TimeZoneTextFeedback { get; set; } + public IntFeedback TimeZoneFeedback { get; protected set; } + public StringFeedback TimeZoneTextFeedback { get; protected set; } + + public StringFeedback IoControllerVersionFeedback { get; protected set; } + public StringFeedback SnmpVersionFeedback { get; protected set; } + public StringFeedback BaCnetAppVersionFeedback { get; protected set; } + public StringFeedback ControllerVersionFeedback { get; protected set; } + + //new feedbacks. Issue #50 + public StringFeedback SerialNumberFeedback { get; protected set; } + public StringFeedback ModelFeedback { get; set; } + + public StringFeedback UptimeFeedback { get; set; } + public StringFeedback LastStartFeedback { get; set; } - public StringFeedback IOControllerVersionFeedback { get; set; } - public StringFeedback SnmpVersionFeedback { get; set; } - public StringFeedback BACnetAppVersionFeedback { get; set; } - public StringFeedback ControllerVersionFeedback { get; set; } - public SystemMonitorController(string key) : base(key) { @@ -38,21 +49,18 @@ namespace PepperDash.Essentials.Core.Monitoring SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true; - //CrestronConsole.AddNewConsoleCommand(RefreshSystemMonitorData, "RefreshSystemMonitor", "Refreshes System Monitor Feedbacks", ConsoleAccessLevelEnum.AccessOperator); + TimeZoneFeedback = new IntFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneNumber); + TimeZoneTextFeedback = new StringFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneName); - TimeZoneFeedback = new IntFeedback(new Func( () => SystemMonitor.TimeZoneInformation.TimeZoneNumber)); - TimeZoneTextFeedback = new StringFeedback(new Func( () => SystemMonitor.TimeZoneInformation.TimeZoneName)); + IoControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.IOPVersion); + SnmpVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.SNMPVersion); + BaCnetAppVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.BACNetVersion); + ControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.ControlSystemVersion); - IOControllerVersionFeedback = new StringFeedback(new Func( () => SystemMonitor.VersionInformation.IOPVersion)); - SnmpVersionFeedback = new StringFeedback(new Func( () => SystemMonitor.VersionInformation.SNMPVersion)); - BACnetAppVersionFeedback = new StringFeedback(new Func( () => SystemMonitor.VersionInformation.BACNetVersion)); - ControllerVersionFeedback = new StringFeedback(new Func( () => SystemMonitor.VersionInformation.ControlSystemVersion)); - - //var status = string.Format("System Monitor Status: \r TimeZone: {0}\rTimeZoneText: {1}\rIOControllerVersion: {2}\rSnmpAppVersionFeedback: {3}\rBACnetAppVersionFeedback: {4}\rControllerVersionFeedback: {5}", - // SystemMonitor.TimeZoneInformation.TimeZoneNumber, SystemMonitor.TimeZoneInformation.TimeZoneName, SystemMonitor.VersionInformation.IOPVersion, SystemMonitor.VersionInformation.SNMPVersion, - // SystemMonitor.VersionInformation.BACNetVersion, SystemMonitor.VersionInformation.ControlSystemVersion); - - //Debug.Console(1, this, status); + SerialNumberFeedback = new StringFeedback(() => CrestronEnvironment.SystemInfo.SerialNumber); + ModelFeedback = new StringFeedback(() => InitialParametersClass.ControllerPromptName); + UptimeFeedback = new StringFeedback(() => _uptime); + LastStartFeedback = new StringFeedback(()=> _lastStart); ProgramStatusFeedbackCollection = new Dictionary(); @@ -62,47 +70,231 @@ namespace PepperDash.Essentials.Core.Monitoring ProgramStatusFeedbackCollection.Add(prog.Number, program); } - SystemMonitor.ProgramChange += new ProgramStateChangeEventHandler(SystemMonitor_ProgramChange); - SystemMonitor.TimeZoneInformation.TimeZoneChange += new TimeZoneChangeEventHandler(TimeZoneInformation_TimeZoneChange); + CreateEthernetStatusFeedbacks(); + UpdateEthernetStatusFeeedbacks(); + + _uptimePollTimer = new CTimer(PollUptime,null,0, UptimePollTime); + + SystemMonitor.ProgramChange += SystemMonitor_ProgramChange; + SystemMonitor.TimeZoneInformation.TimeZoneChange += TimeZoneInformation_TimeZoneChange; + CrestronEnvironment.EthernetEventHandler += CrestronEnvironmentOnEthernetEventHandler; + CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironmentOnProgramStatusEventHandler; + } + + private void CrestronEnvironmentOnProgramStatusEventHandler(eProgramStatusEventType programEventType) + { + if (programEventType != eProgramStatusEventType.Stopping) return; + + _uptimePollTimer.Stop(); + _uptimePollTimer.Dispose(); + _uptimePollTimer = null; + } + + private void PollUptime(object obj) + { + var consoleResponse = string.Empty; + + CrestronConsole.SendControlSystemCommand("uptime", ref consoleResponse); + + ParseUptime(consoleResponse); + + UptimeFeedback.FireUpdate(); + LastStartFeedback.FireUpdate(); + } + + private void ParseUptime(string response) + { + var splitString = response.Trim().Split('\r', '\n'); + + var lastStartRaw = splitString[2]; + var lastStartIndex = lastStartRaw.IndexOf(':'); + + _lastStart = lastStartRaw.Substring(lastStartIndex + 1).Trim(); + + var uptimeRaw = splitString[0]; + + var forIndex = uptimeRaw.IndexOf("for", StringComparison.Ordinal); + + //4 => "for " to get what's on the right + _uptime = uptimeRaw.Substring(forIndex + 4); + } + + private void CrestronEnvironmentOnEthernetEventHandler(EthernetEventArgs ethernetEventArgs) + { + if (ethernetEventArgs.EthernetEventType != eEthernetEventType.LinkUp) return; + + foreach (var fb in EthernetStatusFeedbackCollection) + { + fb.Value.UpdateEthernetStatus(); + } + } + + private void CreateEthernetStatusFeedbacks() + { + EthernetStatusFeedbackCollection = new Dictionary(); + + Debug.Console(2, "Creating {0} EthernetStatusFeedbacks", InitialParametersClass.NumberOfEthernetInterfaces); + + for (short i = 0; i < InitialParametersClass.NumberOfEthernetInterfaces; i++) + { + Debug.Console(2, "Creating EthernetStatusFeedback for Interface {0}", i); + var ethernetInterface = new EthernetStatusFeedbacks(i); + EthernetStatusFeedbackCollection.Add(i, ethernetInterface); + } + } + + private void UpdateEthernetStatusFeeedbacks() + { + foreach (var iface in EthernetStatusFeedbackCollection) + { + iface.Value.CurrentIpAddressFeedback.FireUpdate(); + iface.Value.CurrentSubnetMaskFeedback.FireUpdate(); + iface.Value.CurrentDefaultGatewayFeedback.FireUpdate(); + iface.Value.StaticIpAddressFeedback.FireUpdate(); + iface.Value.StaticSubnetMaskFeedback.FireUpdate(); + iface.Value.StaticDefaultGatewayFeedback.FireUpdate(); + iface.Value.HostNameFeedback.FireUpdate(); + iface.Value.DnsServerFeedback.FireUpdate(); + iface.Value.DomainFeedback.FireUpdate(); + iface.Value.DhcpStatusFeedback.FireUpdate(); + iface.Value.MacAddressFeedback.FireUpdate(); + } } /// /// Gets data in separate thread /// - /// - void RefreshSystemMonitorData(string command) + private void RefreshSystemMonitorData() { // this takes a while, launch a new thread - CrestronInvoke.BeginInvoke((o) => - { - TimeZoneFeedback.FireUpdate(); - TimeZoneTextFeedback.FireUpdate(); - IOControllerVersionFeedback.FireUpdate(); - SnmpVersionFeedback.FireUpdate(); - BACnetAppVersionFeedback.FireUpdate(); - ControllerVersionFeedback.FireUpdate(); - - OnSystemMonitorPropertiesChanged(); - } - ); + CrestronInvoke.BeginInvoke(UpdateFeedback); } - void OnSystemMonitorPropertiesChanged() + private void UpdateFeedback(object o) + { + TimeZoneFeedback.FireUpdate(); + TimeZoneTextFeedback.FireUpdate(); + IoControllerVersionFeedback.FireUpdate(); + SnmpVersionFeedback.FireUpdate(); + BaCnetAppVersionFeedback.FireUpdate(); + ControllerVersionFeedback.FireUpdate(); + SerialNumberFeedback.FireUpdate(); + ModelFeedback.FireUpdate(); + + OnSystemMonitorPropertiesChanged(); + } + + private void OnSystemMonitorPropertiesChanged() { var handler = SystemMonitorPropertiesChanged; if (handler != null) { - handler(this, new EventArgs()); + handler(this, new EventArgs()); } } public override bool CustomActivate() { - RefreshSystemMonitorData(null); + RefreshSystemMonitorData(); return base.CustomActivate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new SystemMonitorJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + Debug.Console(2, this, "Linking API starting at join: {0}", joinStart); + + TimeZoneFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeZone]); + TimeZoneTextFeedback.LinkInputSig(trilist.StringInput[joinMap.TimeZoneName]); + + IoControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.IOControllerVersion]); + SnmpVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.SnmpAppVersion]); + BaCnetAppVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.BACnetAppVersion]); + ControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.ControllerVersion]); + SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumber]); + ModelFeedback.LinkInputSig(trilist.StringInput[joinMap.Model]); + UptimeFeedback.LinkInputSig(trilist.StringInput[joinMap.Uptime]); + LastStartFeedback.LinkInputSig(trilist.StringInput[joinMap.LastBoot]); + + // iterate the program status feedback collection and map all the joins + LinkProgramInfoJoins(this, trilist, joinMap); + + LinkEthernetInfoJoins(this, trilist, joinMap); + } + + private static void LinkEthernetInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, SystemMonitorJoinMap joinMap) + { + var ethernetSlotJoinStart = joinMap.EthernetStartJoin; + + foreach (var fb in systemMonitorController.EthernetStatusFeedbackCollection) + { + fb.Value.CurrentIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentIpAddress]); + fb.Value.CurrentSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentSubnetMask]); + fb.Value.CurrentDefaultGatewayFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentDefaultGateway]); + fb.Value.StaticIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticIpAddress]); + fb.Value.StaticSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticSubnetMask]); + fb.Value.StaticDefaultGatewayFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticDefaultGateway]); + fb.Value.HostNameFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.HostName]); + fb.Value.MacAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.MacAddress]); + fb.Value.DomainFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.Domain]); + fb.Value.DnsServerFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DnsServer]); + fb.Value.DhcpStatusFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DhcpStatus]); + + ethernetSlotJoinStart += joinMap.EthernetOffsetJoin; + } + } + + private static void LinkProgramInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, + SystemMonitorJoinMap joinMap) + { + var programSlotJoinStart = joinMap.ProgramStartJoin; + + foreach (var p in systemMonitorController.ProgramStatusFeedbackCollection) + { + var programNumber = p.Value.Program.Number; + + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart, + b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Start); + p.Value.ProgramStartedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStart]); + + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop, + b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Stop); + p.Value.ProgramStoppedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStop]); + + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister, + b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register); + p.Value.ProgramRegisteredFeedback.LinkInputSig( + trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramRegister]); + + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister, + b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister); + p.Value.ProgramUnregisteredFeedback.LinkInputSig( + trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramUnregister]); + + p.Value.ProgramNameFeedback.LinkInputSig(trilist.StringInput[programSlotJoinStart + joinMap.ProgramName]); + p.Value.ProgramCompileTimeFeedback.LinkInputSig( + trilist.StringInput[programSlotJoinStart + joinMap.ProgramCompiledTime]); + p.Value.CrestronDataBaseVersionFeedback.LinkInputSig( + trilist.StringInput[programSlotJoinStart + joinMap.ProgramCrestronDatabaseVersion]); + p.Value.EnvironmentVersionFeedback.LinkInputSig( + trilist.StringInput[programSlotJoinStart + joinMap.ProgramEnvironmentVersion]); + p.Value.AggregatedProgramInfoFeedback.LinkInputSig( + trilist.StringInput[programSlotJoinStart + joinMap.AggregatedProgramInfo]); + + programSlotJoinStart = programSlotJoinStart + joinMap.ProgramOffsetJoin; + } + } + //// Sets the time zone //public void SetTimeZone(int timeZone) //{ @@ -114,46 +306,41 @@ namespace PepperDash.Essentials.Core.Monitoring /// /// /// - void SystemMonitor_ProgramChange(Program sender, ProgramEventArgs args) + private void SystemMonitor_ProgramChange(Program sender, ProgramEventArgs args) { Debug.Console(2, this, "Program Change Detected for slot: {0}", sender.Number); Debug.Console(2, this, "Event Type: {0}", args.EventType); var program = ProgramStatusFeedbackCollection[sender.Number]; - if (args.EventType == eProgramChangeEventType.OperatingState) + switch (args.EventType) { - program.ProgramStartedFeedback.FireUpdate(); - program.ProgramStoppedFeedback.FireUpdate(); - - program.ProgramInfo.OperatingState = args.OperatingState; - - //program.GetProgramInfo(); - - if (args.OperatingState == eProgramOperatingState.Start) - program.GetProgramInfo(); - else - { - program.AggregatedProgramInfoFeedback.FireUpdate(); - program.OnProgramInfoChanged(); - } + case eProgramChangeEventType.OperatingState: + program.ProgramStartedFeedback.FireUpdate(); + program.ProgramStoppedFeedback.FireUpdate(); + program.ProgramInfo.OperatingState = args.OperatingState; + if (args.OperatingState == eProgramOperatingState.Start) + program.GetProgramInfo(); + else + { + program.AggregatedProgramInfoFeedback.FireUpdate(); + program.OnProgramInfoChanged(); + } + break; + case eProgramChangeEventType.RegistrationState: + program.ProgramRegisteredFeedback.FireUpdate(); + program.ProgramUnregisteredFeedback.FireUpdate(); + program.ProgramInfo.RegistrationState = args.RegistrationState; + program.GetProgramInfo(); + break; } - else if (args.EventType == eProgramChangeEventType.RegistrationState) - { - program.ProgramRegisteredFeedback.FireUpdate(); - program.ProgramUnregisteredFeedback.FireUpdate(); - - program.ProgramInfo.RegistrationState = args.RegistrationState; - - program.GetProgramInfo(); - } } /// /// Responds to time zone changes and updates the appropriate feedbacks /// /// - void TimeZoneInformation_TimeZoneChange(TimeZoneEventArgs args) + private void TimeZoneInformation_TimeZoneChange(TimeZoneEventArgs args) { Debug.Console(2, this, "Time Zone Change Detected."); TimeZoneFeedback.FireUpdate(); @@ -162,6 +349,121 @@ namespace PepperDash.Essentials.Core.Monitoring OnSystemMonitorPropertiesChanged(); } + public class EthernetStatusFeedbacks + { + public StringFeedback HostNameFeedback { get; protected set; } + public StringFeedback DnsServerFeedback { get; protected set; } + public StringFeedback DomainFeedback { get; protected set; } + public StringFeedback MacAddressFeedback { get; protected set; } + public StringFeedback DhcpStatusFeedback { get; protected set; } + + public StringFeedback CurrentIpAddressFeedback { get; protected set; } + public StringFeedback CurrentSubnetMaskFeedback { get; protected set; } + public StringFeedback CurrentDefaultGatewayFeedback { get; protected set; } + + public StringFeedback StaticIpAddressFeedback { get; protected set; } + public StringFeedback StaticSubnetMaskFeedback { get; protected set; } + public StringFeedback StaticDefaultGatewayFeedback { get; protected set; } + + public EthernetStatusFeedbacks(short adapterIndex) + { + Debug.Console(2, "Ethernet Information for interface {0}", adapterIndex); + Debug.Console(2, "Adapter Index: {1} Hostname: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Current IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Current Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Current Router: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Static IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPADDRESS, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Static Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPMASK, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Static Router: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_ROUTER, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} DNS Servers: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} DHCP State: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Domain Name: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} MAC Address: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex), adapterIndex); + HostNameFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex)); + + CurrentIpAddressFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex)); + CurrentDefaultGatewayFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex)); + CurrentSubnetMaskFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex)); + StaticIpAddressFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex)); + StaticDefaultGatewayFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex)); + StaticSubnetMaskFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex)); + DomainFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex)); + DnsServerFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex)); + MacAddressFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex)); + + DhcpStatusFeedback = new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex)); + } + + public void UpdateEthernetStatus() + { + HostNameFeedback.FireUpdate(); + CurrentIpAddressFeedback.FireUpdate(); + CurrentSubnetMaskFeedback.FireUpdate(); + CurrentDefaultGatewayFeedback.FireUpdate(); + StaticIpAddressFeedback.FireUpdate(); + StaticSubnetMaskFeedback.FireUpdate(); + StaticDefaultGatewayFeedback.FireUpdate(); + DomainFeedback.FireUpdate(); + DnsServerFeedback.FireUpdate(); + MacAddressFeedback.FireUpdate(); + DhcpStatusFeedback.FireUpdate(); + } + } + public class ProgramStatusFeedbacks { @@ -192,17 +494,19 @@ namespace PepperDash.Essentials.Core.Monitoring ProgramInfo.OperatingState = Program.OperatingState; ProgramInfo.RegistrationState = Program.RegistrationState; - ProgramStartedFeedback = new BoolFeedback(new Func( () => Program.OperatingState == eProgramOperatingState.Start)); - ProgramStoppedFeedback = new BoolFeedback(new Func( () => Program.OperatingState == eProgramOperatingState.Stop)); - ProgramRegisteredFeedback = new BoolFeedback(new Func( () => Program.RegistrationState == eProgramRegistrationState.Register)); - ProgramUnregisteredFeedback = new BoolFeedback(new Func( () => Program.RegistrationState == eProgramRegistrationState.Unregister)); + ProgramStartedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Start); + ProgramStoppedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Stop); + ProgramRegisteredFeedback = + new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Register); + ProgramUnregisteredFeedback = + new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Unregister); - ProgramNameFeedback = new StringFeedback(new Func(() => ProgramInfo.ProgramFile)); - ProgramCompileTimeFeedback = new StringFeedback(new Func(() => ProgramInfo.CompileTime)); - CrestronDataBaseVersionFeedback = new StringFeedback(new Func(() => ProgramInfo.CrestronDB)); - EnvironmentVersionFeedback = new StringFeedback(new Func(() => ProgramInfo.Environment)); + ProgramNameFeedback = new StringFeedback(() => ProgramInfo.ProgramFile); + ProgramCompileTimeFeedback = new StringFeedback(() => ProgramInfo.CompileTime); + CrestronDataBaseVersionFeedback = new StringFeedback(() => ProgramInfo.CrestronDb); + EnvironmentVersionFeedback = new StringFeedback(() => ProgramInfo.Environment); - AggregatedProgramInfoFeedback = new StringFeedback(new Func(() => JsonConvert.SerializeObject(ProgramInfo))); + AggregatedProgramInfoFeedback = new StringFeedback(() => JsonConvert.SerializeObject(ProgramInfo)); GetProgramInfo(); } @@ -212,74 +516,99 @@ namespace PepperDash.Essentials.Core.Monitoring /// public void GetProgramInfo() { - CrestronInvoke.BeginInvoke((o) => + CrestronInvoke.BeginInvoke(GetProgramInfo); + } + + private void GetProgramInfo(object o) + { + Debug.Console(2, "Attempting to get program info for slot: {0}", Program.Number); + + string response = null; + + if (Program.RegistrationState == eProgramRegistrationState.Unregister || Program.OperatingState == eProgramOperatingState.Stop) { - Debug.Console(2, "Attempting to get program info for slot: {0}", Program.Number); + Debug.Console(2, "Program {0} not registered. Setting default values for program information.", + Program.Number); - string response = null; - - var success = CrestronConsole.SendControlSystemCommand(string.Format("progcomments:{0}", Program.Number), ref response); - - if (success) + ProgramInfo = new ProgramInfo(Program.Number) { - //Debug.Console(2, "Progcomments Response: \r{0}", response); + OperatingState = Program.OperatingState, + RegistrationState = Program.RegistrationState + }; - if (!response.ToLower().Contains("bad or incomplete")) - { - // Shared properteis - ProgramInfo.ProgramFile = ParseConsoleData(response, "Program File", ": ", "\n"); - ProgramInfo.CompilerRevision = ParseConsoleData(response, "Compiler Rev", ": ", "\n"); - ProgramInfo.CompileTime = ParseConsoleData(response, "Compiled On", ": ", "\n"); - ProgramInfo.Include4Dat = ParseConsoleData(response, "Include4.dat", ": ", "\n"); + return; + } + var success = CrestronConsole.SendControlSystemCommand( + string.Format("progcomments:{0}", Program.Number), ref response); + if (!success) + { + Debug.Console(2, "Progcomments Attempt Unsuccessful for slot: {0}", Program.Number); + UpdateFeedbacks(); + return; + } - if (ProgramInfo.ProgramFile.Contains(".dll")) - { - // SSP Program - ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ": ", "\n"); - ProgramInfo.ApplicationName = ParseConsoleData(response, "Application Name", ": ", "\n"); - ProgramInfo.ProgramTool = ParseConsoleData(response, "Program Tool", ": ", "\n"); - ProgramInfo.MinFirmwareVersion = ParseConsoleData(response, "Min Firmware Version", ": ", "\n"); - ProgramInfo.PlugInVersion = ParseConsoleData(response, "PlugInVersion", ": ", "\n"); - } - else if (ProgramInfo.ProgramFile.Contains(".smw")) - { - // SIMPL Windows Program - ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ":", "\n"); - ProgramInfo.SystemName = ParseConsoleData(response, "System Name", ": ", "\n"); - ProgramInfo.CrestronDB = ParseConsoleData(response, "CrestronDB", ": ", "\n"); - ProgramInfo.Environment = ParseConsoleData(response, "Source Env", ": ", "\n"); - ProgramInfo.Programmer = ParseConsoleData(response, "Programmer", ": ", "\n"); + if (response.ToLower().Contains("bad or incomplete")) + { + Debug.Console(2, + "Program in slot {0} not running. Setting default ProgramInfo for slot: {0}", + Program.Number); - } - //Debug.Console(2, "ProgramInfo: \r{0}", JsonConvert.SerializeObject(ProgramInfo)); - } - else - { - Debug.Console(2, "Bad or incomplete console command response. Initializing ProgramInfo for slot: {0}", Program.Number); - - // Assume no valid program info. Constructing a new object will wipe all properties - ProgramInfo = new ProgramInfo(Program.Number); - - ProgramInfo.OperatingState = Program.OperatingState; - ProgramInfo.RegistrationState = Program.RegistrationState; - } - } - else + // Assume no valid program info. Constructing a new object will wipe all properties + ProgramInfo = new ProgramInfo(Program.Number) { - Debug.Console(2, "Progcomments Attempt Unsuccessful for slot: {0}", Program.Number); - } + OperatingState = Program.OperatingState, + RegistrationState = Program.RegistrationState + }; - ProgramNameFeedback.FireUpdate(); - ProgramCompileTimeFeedback.FireUpdate(); - CrestronDataBaseVersionFeedback.FireUpdate(); - EnvironmentVersionFeedback.FireUpdate(); + UpdateFeedbacks(); - AggregatedProgramInfoFeedback.FireUpdate(); + return; + } - OnProgramInfoChanged(); - }); + + // Shared properteis + ProgramInfo.ProgramFile = ParseConsoleData(response, "Program File", ": ", "\n"); + ProgramInfo.CompilerRevision = ParseConsoleData(response, "Compiler Rev", ": ", "\n"); + ProgramInfo.CompileTime = ParseConsoleData(response, "Compiled On", ": ", "\n"); + ProgramInfo.Include4Dat = ParseConsoleData(response, "Include4.dat", ": ", "\n"); + + + if (ProgramInfo.ProgramFile.Contains(".dll")) + { + // SSP Program + ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ": ", "\n"); + ProgramInfo.ApplicationName = ParseConsoleData(response, "Application Name", ": ", "\n"); + ProgramInfo.ProgramTool = ParseConsoleData(response, "Program Tool", ": ", "\n"); + ProgramInfo.MinFirmwareVersion = ParseConsoleData(response, "Min Firmware Version", ": ", + "\n"); + ProgramInfo.PlugInVersion = ParseConsoleData(response, "PlugInVersion", ": ", "\n"); + } + else if (ProgramInfo.ProgramFile.Contains(".smw")) + { + // SIMPL Windows Program + ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ":", "\n"); + ProgramInfo.SystemName = ParseConsoleData(response, "System Name", ": ", "\n"); + ProgramInfo.CrestronDb = ParseConsoleData(response, "CrestronDB", ": ", "\n"); + ProgramInfo.Environment = ParseConsoleData(response, "Source Env", ": ", "\n"); + ProgramInfo.Programmer = ParseConsoleData(response, "Programmer", ": ", "\n"); + } + Debug.Console(2, "Program info for slot {0} successfully updated", Program.Number); + + UpdateFeedbacks(); + } + + private void UpdateFeedbacks() + { + ProgramNameFeedback.FireUpdate(); + ProgramCompileTimeFeedback.FireUpdate(); + CrestronDataBaseVersionFeedback.FireUpdate(); + EnvironmentVersionFeedback.FireUpdate(); + + AggregatedProgramInfoFeedback.FireUpdate(); + + OnProgramInfoChanged(); } public void OnProgramInfoChanged() @@ -294,30 +623,28 @@ namespace PepperDash.Essentials.Core.Monitoring private string ParseConsoleData(string data, string line, string startString, string endString) { - string outputData = ""; + var outputData = ""; - if (data.Length > 0) + if (data.Length <= 0) return outputData; + + try { - try - { - - //Debug.Console(2, "ParseConsoleData Data: {0}, Line {1}, startStirng {2}, endString {3}", data, line, startString, endString); - var linePosition = data.IndexOf(line); - var startPosition = data.IndexOf(startString, linePosition) + startString.Length; - var endPosition = data.IndexOf(endString, startPosition); - outputData = data.Substring(startPosition, endPosition - startPosition).Trim(); - //Debug.Console(2, "ParseConsoleData Return: {0}", outputData); - } - catch (Exception e) - { - Debug.Console(1, "Error Parsing Console Data:\r{0}", e); - } + //Debug.Console(2, "ParseConsoleData Data: {0}, Line {1}, startStirng {2}, endString {3}", data, line, startString, endString); + var linePosition = data.IndexOf(line, StringComparison.Ordinal); + var startPosition = data.IndexOf(startString, linePosition, StringComparison.Ordinal) + + startString.Length; + var endPosition = data.IndexOf(endString, startPosition, StringComparison.Ordinal); + outputData = data.Substring(startPosition, endPosition - startPosition).Trim(); + //Debug.Console(2, "ParseConsoleData Return: {0}", outputData); + } + catch (Exception e) + { + Debug.Console(1, "Error Parsing Console Data:\r{0}", e); } return outputData; } } - } /// @@ -330,32 +657,39 @@ namespace PepperDash.Essentials.Core.Monitoring [JsonProperty("programNumber")] public uint ProgramNumber { get; private set; } - [JsonConverter(typeof(StringEnumConverter))] + [JsonConverter(typeof (StringEnumConverter))] [JsonProperty("operatingState")] public eProgramOperatingState OperatingState { get; set; } - [JsonConverter(typeof(StringEnumConverter))] + [JsonConverter(typeof (StringEnumConverter))] [JsonProperty("registrationState")] public eProgramRegistrationState RegistrationState { get; set; } [JsonProperty("programFile")] public string ProgramFile { get; set; } + [JsonProperty("friendlyName")] public string FriendlyName { get; set; } + [JsonProperty("compilerRevision")] public string CompilerRevision { get; set; } + [JsonProperty("compileTime")] public string CompileTime { get; set; } + [JsonProperty("include4Dat")] public string Include4Dat { get; set; } // SIMPL Windows properties [JsonProperty("systemName")] public string SystemName { get; set; } + [JsonProperty("crestronDb")] - public string CrestronDB { get; set; } + public string CrestronDb { get; set; } + [JsonProperty("environment")] public string Environment { get; set; } + [JsonProperty("programmer")] public string Programmer { get; set; } @@ -363,10 +697,13 @@ namespace PepperDash.Essentials.Core.Monitoring // SSP Properties [JsonProperty("applicationName")] public string ApplicationName { get; set; } + [JsonProperty("programTool")] public string ProgramTool { get; set; } + [JsonProperty("minFirmwareVersion")] public string MinFirmwareVersion { get; set; } + [JsonProperty("plugInVersion")] public string PlugInVersion { get; set; } @@ -381,7 +718,7 @@ namespace PepperDash.Essentials.Core.Monitoring Include4Dat = ""; SystemName = ""; - CrestronDB = ""; + CrestronDb = ""; Environment = ""; Programmer = ""; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index b3377a70..e7a5a8ac 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -111,6 +111,29 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -132,11 +155,14 @@ + + + @@ -156,6 +182,9 @@ + + + diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/IPluginDeviceConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/IPluginDeviceConfig.cs deleted file mode 100644 index 7ac894c6..00000000 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/IPluginDeviceConfig.cs +++ /dev/null @@ -1,11 +0,0 @@ -using PepperDash.Core; -using PepperDash.Essentials.Core.Config; - -namespace PepperDash.Essentials.Core.Plugins -{ - public interface IPluginDeviceConfig - { - string MinimumEssentialsFrameworkVersion { get; } - IKeyed BuildDevice(DeviceConfig dc); - } -} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/IPluginDeviceFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/IPluginDeviceFactory.cs new file mode 100644 index 00000000..ff979599 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/IPluginDeviceFactory.cs @@ -0,0 +1,19 @@ +using PepperDash.Core; + + +namespace PepperDash.Essentials.Core +{ + /// + /// Defines a class that is capable of loading custom plugin device types + /// + public interface IPluginDeviceFactory : IDeviceFactory + { + /// + /// Required to define the minimum version for Essentials in the format xx.yy.zz + /// + string MinimumEssentialsFrameworkVersion { get; } + + } + + +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginEntrypointAttribute.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginEntrypointAttribute.cs deleted file mode 100644 index f802211f..00000000 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginEntrypointAttribute.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace PepperDash.Essentials.Core.Plugins -{ - [AttributeUsage(AttributeTargets.Class)] - public sealed class PluginEntryPointAttribute : Attribute - { - private readonly string _uniqueKey; - - public string UniqueKey { - get { return _uniqueKey; } - } - - public PluginEntryPointAttribute(string key) - { - _uniqueKey = key; - } - } -} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs new file mode 100644 index 00000000..5c66ab8f --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs @@ -0,0 +1,519 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharp.CrestronIO; +using Crestron.SimplSharp.Reflection; + +using PepperDash.Core; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials +{ + /// + /// Deals with loading plugins at runtime + /// + public static class PluginLoader + { + /// + /// The complete list of loaded assemblies. Includes Essentials Framework assemblies and plugins + /// + public static List LoadedAssemblies { get; private set; } + + /// + /// The list of assemblies loaded from the plugins folder + /// + static List LoadedPluginFolderAssemblies; + + /// + /// The directory to look in for .cplz plugin packages + /// + static string _pluginDirectory = Global.FilePathPrefix + "plugins"; + + /// + /// The directory where plugins will be moved to and loaded from + /// + static string _loadedPluginsDirectoryPath = _pluginDirectory + Global.DirectorySeparator + "loadedAssemblies"; + + // The temp directory where .cplz archives will be unzipped to + static string _tempDirectory = _pluginDirectory + Global.DirectorySeparator + "temp"; + + + static PluginLoader() + { + LoadedAssemblies = new List(); + LoadedPluginFolderAssemblies = new List(); + } + + /// + /// Retrieves all the loaded assemblies from the program directory + /// + public static void AddProgramAssemblies() + { + Debug.Console(2, "Getting Assemblies loaded with Essentials"); + // Get the loaded assembly filenames + var appDi = new DirectoryInfo(Global.ApplicationDirectoryPathPrefix); + var assemblyFiles = appDi.GetFiles("*.dll"); + + Debug.Console(2, "Found {0} Assemblies", assemblyFiles.Length); + + foreach (var fi in assemblyFiles) + { + string version = string.Empty; + Assembly assembly = null; + + switch (fi.Name) + { + case ("PepperDashEssentials.dll"): + { + version = Global.AssemblyVersion; + break; + } + case ("PepperDash_Essentials_Core.dll"): + { + version = Global.AssemblyVersion; + break; + } + case ("PepperDash_Essentials_DM.dll"): + { + version = Global.AssemblyVersion; + break; + } + case ("Essentials Devices Common.dll"): + { + version = Global.AssemblyVersion; + break; + } + case ("PepperDash_Core.dll"): + { + version = PepperDash.Core.Debug.PepperDashCoreVersion; + break; + } + } + + LoadedAssemblies.Add(new LoadedAssembly(fi.Name, version, assembly)); + } + + if (Debug.Level > 1) + { + Debug.Console(2, "Loaded Assemblies:"); + + foreach (var assembly in LoadedAssemblies) + { + Debug.Console(2, "Assembly: {0}", assembly.Name); + } + } + } + + + public static void SetEssentialsAssembly(string name, Assembly assembly) + { + var loadedAssembly = LoadedAssemblies.FirstOrDefault(la => la.Name.Equals(name)); + + if (loadedAssembly != null) + { + loadedAssembly.SetAssembly(assembly); + } + } + + /// + /// Loads an assembly via Reflection and adds it to the list of loaded assemblies + /// + /// + static LoadedAssembly LoadAssembly(string filePath) + { + Debug.Console(2, "Attempting to load {0}", filePath); + var assembly = Assembly.LoadFrom(filePath); + if (assembly != null) + { + var assyVersion = GetAssemblyVersion(assembly); + + var loadedAssembly = new LoadedAssembly(assembly.GetName().Name, assyVersion, assembly); + LoadedAssemblies.Add(loadedAssembly); + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loaded assembly '{0}', version {1}", loadedAssembly.Name, loadedAssembly.Version); + return loadedAssembly; + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to load assembly: '{0}'", filePath); + } + + return null; + + } + + /// + /// Attempts to get the assembly informational version and if not possible gets the version + /// + /// + /// + static string GetAssemblyVersion(Assembly assembly) + { + var ver = assembly.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false); + if (ver != null && ver.Length > 0) + { + // Get the AssemblyInformationalVersion + AssemblyInformationalVersionAttribute verAttribute = ver[0] as AssemblyInformationalVersionAttribute; + return verAttribute.InformationalVersion; + } + else + { + // Get the AssemblyVersion + var version = assembly.GetName().Version; + var verStr = string.Format("{0}.{1}.{2}.{3}", version.Major, version.Minor, version.Build, version.Revision); + return verStr; + } + } + + /// + /// Checks if the filename matches an already loaded assembly file's name + /// + /// + /// True if file already matches loaded assembly file. + public static bool CheckIfAssemblyLoaded(string name) + { + Debug.Console(2, "Checking if assembly: {0} is loaded...", name); + var loadedAssembly = LoadedAssemblies.FirstOrDefault(s => s.Name.Equals(name)); + + if (loadedAssembly != null) + { + Debug.Console(2, "Assembly already loaded."); + return true; + } + else + { + Debug.Console(2, "Assembly not loaded."); + return false; + } + } + + /// + /// Used by console command to report the currently loaded assemblies and versions + /// + /// + public static void ReportAssemblyVersions(string command) + { + Debug.Console(0, "Loaded Assemblies:"); + foreach (var assembly in LoadedAssemblies) + { + Debug.Console(0, "{0} Version: {1}", assembly.Name, assembly.Version); + } + } + + /// + /// Moves any .dll assemblies not already loaded from the plugins folder to loadedPlugins folder + /// + static void MoveDllAssemblies() + { + Debug.Console(0, "Looking for .dll assemblies from plugins folder..."); + + var pluginDi = new DirectoryInfo(_pluginDirectory); + var pluginFiles = pluginDi.GetFiles("*.dll"); + + if (pluginFiles.Length > 0) + { + if (!Directory.Exists(_loadedPluginsDirectoryPath)) + { + Directory.CreateDirectory(_loadedPluginsDirectoryPath); + } + } + + foreach (var pluginFile in pluginFiles) + { + try + { + Debug.Console(0, "Found .dll: {0}", pluginFile.Name); + + if (!CheckIfAssemblyLoaded(pluginFile.Name)) + { + string filePath = string.Empty; + + filePath = _loadedPluginsDirectoryPath + Global.DirectorySeparator + pluginFile.Name; + + // Check if there is a previous file in the loadedPlugins directory and delete + if (File.Exists(filePath)) + { + Debug.Console(0, "Found existing file in loadedPlugins: {0} Deleting and moving new file to replace it", filePath); + File.Delete(filePath); + } + + // Move the file + File.Move(pluginFile.FullName, filePath); + Debug.Console(2, "Moved {0} to {1}", pluginFile.FullName, filePath); + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Skipping assembly: {0}. There is already an assembly with that name loaded.", pluginFile.FullName); + } + } + catch (Exception e) + { + Debug.Console(2, "Error with plugin file {0} . Exception: {1}", pluginFile.FullName, e); + continue; //catching any load issues and continuing. There will be exceptions loading Crestron .dlls from the cplz Probably should do something different here + } + } + + Debug.Console(0, "Done with .dll assemblies"); + } + + /// + /// Unzips each .cplz archive into the temp directory and moves any unloaded files into loadedPlugins + /// + static void UnzipAndMoveCplzArchives() + { + Debug.Console(0, "Looking for .cplz archives from plugins folder..."); + var di = new DirectoryInfo(_pluginDirectory); + var zFiles = di.GetFiles("*.cplz"); + + if (zFiles.Length > 0) + { + if (!Directory.Exists(_loadedPluginsDirectoryPath)) + { + Directory.CreateDirectory(_loadedPluginsDirectoryPath); + } + } + + foreach (var zfi in zFiles) + { + Directory.CreateDirectory(_tempDirectory); + var tempDi = new DirectoryInfo(_tempDirectory); + + Debug.Console(0, "Found cplz: {0}. Unzipping into temp plugins directory", zfi.Name); + var result = CrestronZIP.Unzip(zfi.FullName, tempDi.FullName); + Debug.Console(0, "UnZip Result: {0}", result.ToString()); + + var tempFiles = tempDi.GetFiles("*.dll"); + foreach (var tempFile in tempFiles) + { + try + { + if (!CheckIfAssemblyLoaded(tempFile.Name)) + { + string filePath = string.Empty; + + filePath = _loadedPluginsDirectoryPath + Global.DirectorySeparator + tempFile.Name; + + // Check if there is a previous file in the loadedPlugins directory and delete + if (File.Exists(filePath)) + { + Debug.Console(0, "Found existing file in loadedPlugins: {0} Deleting and moving new file to replace it", filePath); + File.Delete(filePath); + } + + // Move the file + File.Move(tempFile.FullName, filePath); + Debug.Console(2, "Moved {0} to {1}", tempFile.FullName, filePath); + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Skipping assembly: {0}. There is already an assembly with that name loaded.", tempFile.FullName); + } + } + catch (Exception e) + { + Debug.Console(2, "Assembly {0} is not a custom assembly. Exception: {1}", tempFile.FullName, e); + continue; //catching any load issues and continuing. There will be exceptions loading Crestron .dlls from the cplz Probably should do something different here + } + } + + // Delete the .cplz and the temp directory + Directory.Delete(_tempDirectory, true); + zfi.Delete(); + } + + Debug.Console(0, "Done with .cplz archives"); + } + + /// + /// Attempts to load the assemblies from the loadedPlugins folder + /// + static void LoadPluginAssemblies() + { + Debug.Console(0, "Loading assemblies from loadedPlugins folder..."); + var pluginDi = new DirectoryInfo(_loadedPluginsDirectoryPath); + var pluginFiles = pluginDi.GetFiles("*.dll"); + + Debug.Console(2, "Found {0} plugin assemblies to load", pluginFiles.Length); + + foreach (var pluginFile in pluginFiles) + { + var loadedAssembly = LoadAssembly(pluginFile.FullName); + + LoadedPluginFolderAssemblies.Add(loadedAssembly); + } + + Debug.Console(0, "All Plugins Loaded."); + } + + /// + /// Iterate the loaded assemblies and try to call the LoadPlugin method + /// + static void LoadCustomPluginTypes() + { + Debug.Console(0, "Loading Custom Plugin Types..."); + foreach (var loadedAssembly in LoadedPluginFolderAssemblies) + { + // iteratate this assembly's classes, looking for "LoadPlugin()" methods + try + { + var assy = loadedAssembly.Assembly; + var types = assy.GetTypes(); + foreach (var type in types) + { + try + { + if (typeof(IPluginDeviceFactory).IsAssignableFrom(type)) + { + var plugin = (IPluginDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); + LoadCustomPlugin(plugin, loadedAssembly); + } + else + { + var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static); + var loadPlugin = methods.FirstOrDefault(m => m.Name.Equals("LoadPlugin")); + if (loadPlugin != null) + { + LoadCustomLegacyPlugin(type, loadPlugin, loadedAssembly); + } + } + } + catch (Exception e) + { + Debug.Console(2, "Load Plugin not found. {0}.{2} is not a plugin factory. Exception: {1}", + loadedAssembly.Name, e, type.Name); + continue; + } + + } + } + catch (Exception e) + { + Debug.Console(2, "Error Loading Assembly: {0} Exception: (1) ", loadedAssembly.Name, e); + continue; + } + } + // plugin dll will be loaded. Any classes in plugin should have a static constructor + // that registers that class with the Core.DeviceFactory + Debug.Console(0, "Done Loading Custom Plugin Types."); + } + + /// + /// Loads a + /// + /// + static void LoadCustomPlugin(IPluginDeviceFactory plugin, LoadedAssembly loadedAssembly) + { + var passed = Global.IsRunningMinimumVersionOrHigher(plugin.MinimumEssentialsFrameworkVersion); + + if (!passed) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", plugin.MinimumEssentialsFrameworkVersion); + return; + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Passed plugin passed dependency check (required version {0})", plugin.MinimumEssentialsFrameworkVersion); + } + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading plugin: {0}", loadedAssembly.Name); + plugin.LoadTypeFactories(); + } + + /// + /// Loads a a custom plugin via the legacy method + /// + /// + /// + static void LoadCustomLegacyPlugin(CType type, MethodInfo loadPlugin, LoadedAssembly loadedAssembly) + { + Debug.Console(2, "LoadPlugin method found in {0}", type.Name); + + var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static); + + var minimumVersion = fields.FirstOrDefault(p => p.Name.Equals("MinimumEssentialsFrameworkVersion")); + if (minimumVersion != null) + { + Debug.Console(2, "MinimumEssentialsFrameworkVersion found"); + + var minimumVersionString = minimumVersion.GetValue(null) as string; + + if (!string.IsNullOrEmpty(minimumVersionString)) + { + var passed = Global.IsRunningMinimumVersionOrHigher(minimumVersionString); + + if (!passed) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", minimumVersionString); + return; + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Passed plugin passed dependency check (required version {0})", minimumVersionString); + } + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion found but not set. Loading plugin, but your mileage may vary."); + } + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion not found. Loading plugin, but your mileage may vary."); + } + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading legacy plugin: {0}", loadedAssembly.Name); + loadPlugin.Invoke(null, null); + + } + + /// + /// Loads plugins + /// + public static void LoadPlugins() + { + if (Directory.Exists(_pluginDirectory)) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Plugins directory found, checking for plugins"); + + // Deal with any .dll files + MoveDllAssemblies(); + + // Deal with any .cplz files + UnzipAndMoveCplzArchives(); + + if (Directory.Exists(_loadedPluginsDirectoryPath)) + { + // Load the assemblies from the loadedPlugins folder into the AppDomain + LoadPluginAssemblies(); + + // Load the types from any custom plugin assemblies + LoadCustomPluginTypes(); + } + } + } + + } + + /// + /// Represents an assembly loaded at runtime and it's associated metadata + /// + public class LoadedAssembly + { + public string Name { get; private set; } + public string Version { get; private set; } + public Assembly Assembly { get; private set; } + + public LoadedAssembly(string name, string version, Assembly assembly) + { + Name = name; + Version = version; + Assembly = assembly; + } + + public void SetAssembly(Assembly assembly) + { + Assembly = assembly; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/PresetBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/PresetBase.cs new file mode 100644 index 00000000..76ffbbc3 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/PresetBase.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Core.Presets +{ + public class PresetBase + { + [JsonProperty("id")] + public int ID { get; set; } + /// + /// Used to store the name of the preset + /// + [JsonProperty("description")] + public string Description { get; set; } + /// + /// Indicates if the preset is defined(stored) in the codec + /// + [JsonProperty("defined")] + public bool Defined { get; set; } + /// + /// Indicates if the preset has the capability to be defined + /// + [JsonProperty("isDefinable")] + public bool IsDefinable { get; set; } + + public PresetBase(int id, string description, bool def, bool isDef) + { + ID = id; + Description = description; + Defined = def; + IsDefinable = isDef; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs index fcb04420..11debb03 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs @@ -522,4 +522,19 @@ namespace PepperDash.Essentials.Core [JsonProperty("enableSaturday")] public bool EnableSaturday { get; set; } } + + public class RoomOnToDefaultSourceWhenOccupiedFactory : EssentialsDeviceFactory + { + public RoomOnToDefaultSourceWhenOccupiedFactory() + { + TypeNames = new List() { "roomonwhenoccupancydetectedfeature" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new RoomOnToDefaultSourceWhenOccupied Device"); + return new RoomOnToDefaultSourceWhenOccupied(dc); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs index 7781f468..bb57941e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs @@ -173,6 +173,8 @@ namespace PepperDash.Essentials.Core RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownPromptSeconds; else if (mode == eVacancyMode.InInitialVacancy) RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownSeconds; + else if (mode == eVacancyMode.InShutdownWarning) + RoomVacancyShutdownTimer.SecondsToCount = 60; VacancyMode = mode; RoomVacancyShutdownTimer.Start(); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs index 36f390c3..1743bdaa 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs @@ -35,9 +35,10 @@ namespace PepperDash.Essentials.Core /// public interface IRunRouteAction { - void RunRouteAction(string routeKey); + void RunRouteAction(string routeKey, string sourceListKey); + + void RunRouteAction(string routeKey, string sourceListKey, Action successCallback); - void RunRouteAction(string routeKey, Action successCallback); } /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/IRoutingInputsExtensions.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/IRoutingInputsExtensions.cs deleted file mode 100644 index ad4a3458..00000000 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/IRoutingInputsExtensions.cs +++ /dev/null @@ -1,300 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.DM; - -using PepperDash.Core; - - -namespace PepperDash.Essentials.Core -{ - /// - /// - /// - public static class IRoutingInputsExtensions - { - /// - /// Gets any existing route for a destination, clears it, and then - /// - public static void ReleaseAndMakeRoute(this IRoutingInputs destination, IRoutingOutputs source, eRoutingSignalType signalType) - { - var sw = new Stopwatch(); - sw.Start(); - - destination.ReleaseRoute(); - - if (source == null) return; - var newRoute = destination.GetRouteToSource(source, signalType); - if (newRoute == null) return; - RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(newRoute); - Debug.Console(2, destination, "Executing new route"); - newRoute.ExecuteRoutes(); - sw.Stop(); - Debug.Console(2, destination, "Route took {0} ms", sw.ElapsedMilliseconds); - } - - /// - /// Will release the existing route on the destination - /// - /// - /// - public static void ReleaseRoute(this IRoutingInputs destination) - { - var current = RouteDescriptorCollection.DefaultCollection.RemoveRouteDescriptor(destination); - if (current != null) - { - Debug.Console(2, destination, "Releasing current route: {0}", current.Source.Key); - current.ReleaseRoutes(); - } - } - - - /// - /// - /// - /// - /// - /// - /// - public static RouteDescriptor GetRouteToSource(this IRoutingInputs destination, IRoutingOutputs source, eRoutingSignalType signalType) - { - var routeTable = new RouteDescriptor (source, destination, signalType); - - Debug.Console(0, destination, "Attempting to build source route from {0}***", source.Key); - if (!destination.GetRouteToSource(source, null, null, signalType, 0, routeTable)) - routeTable = null; - - Debug.Console(0, destination, "Route{0} discovered ***", routeTable == null ? " NOT" : ""); - return routeTable; - } - - /// - /// The recursive part of this. Will stop on each device, search its inputs for the - /// desired source and if not found, invoke this function for the each input port - /// hoping to find the source. - /// - /// - /// - /// - /// - /// - /// - /// - /// true if source is hit - static bool GetRouteToSource(this IRoutingInputs destination, IRoutingOutputs source, - RoutingOutputPort onSuccessOutputPort, List alreadyCheckedDevices, - eRoutingSignalType signalType, int cycle, RouteDescriptor routeTable) - { - cycle++; - Debug.Console(0, destination, "SelectInput-cycle {1}. Finding {2} route back to {0}", source.Key, cycle, signalType); - var destDevInputTies = TieLineCollection.Default.Where(t => - t.DestinationPort.ParentDevice == destination && (t.Type == signalType || t.Type == eRoutingSignalType.AudioVideo)); - - // find a direct tie - var directTie = destDevInputTies.FirstOrDefault( - t => !(t.SourcePort.ParentDevice is IRoutingInputsOutputs) - && t.DestinationPort.ParentDevice == destination - && t.SourcePort.ParentDevice == source); - RoutingInputPort inputPort = null; - if (directTie != null) // Found a tie directly to the source - { - Debug.Console(0, destination, "Found direct tie to {0}**", source.Key); - inputPort = directTie.DestinationPort; - } - else // no direct-connect. Walk back devices. - { - Debug.Console(0, destination, "is not directly connected to {0}. Walking down tie lines", source.Key); - - // No direct tie? Run back out on the inputs' attached devices... - // Only the ones that are routing devices - var attachedMidpoints = destDevInputTies.Where(t => t.SourcePort.ParentDevice is IRoutingInputsOutputs); - foreach (var inputTieToTry in attachedMidpoints) - { - Debug.Console(0, destination, "Trying to find route on {0}", inputTieToTry.SourcePort.ParentDevice.Key); - var upstreamDeviceOutputPort = inputTieToTry.SourcePort; - var upstreamRoutingDevice = upstreamDeviceOutputPort.ParentDevice as IRoutingInputsOutputs; - // Check if this previous device has already been walked - if (!(alreadyCheckedDevices != null && alreadyCheckedDevices.Contains(upstreamRoutingDevice))) - { - // haven't seen this device yet. Do it. Pass the output port to the next - // level to enable switching on success - var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort, - alreadyCheckedDevices, signalType, cycle, routeTable); - if (upstreamRoutingSuccess) - { - Debug.Console(0, destination, "Upstream device route found"); - inputPort = inputTieToTry.DestinationPort; - break; // Stop looping the inputs in this cycle - } - } - } - } - - // we have a route on corresponding inputPort. *** Do the route *** - if (inputPort != null) - { - Debug.Console(0, destination, "adding route:"); - if (onSuccessOutputPort == null) - { - // it's a sink device - routeTable.Routes.Add(new RouteSwitchDescriptor(inputPort)); - } - else if (destination is IRouting) - { - routeTable.Routes.Add(new RouteSwitchDescriptor (onSuccessOutputPort, inputPort)); - } - else // device is merely IRoutingInputOutputs - Debug.Console(0, destination, " No routing. Passthrough device"); - Debug.Console(0, destination, "Exiting cycle {0}", cycle); - return true; - } - - if(alreadyCheckedDevices == null) - alreadyCheckedDevices = new List(); - alreadyCheckedDevices.Add(destination as IRoutingInputsOutputs); - - Debug.Console(0, destination, "No route found to {0}", source.Key); - return false; - } - } - - - - - - // MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE - - - /// - /// A collection of routes - typically the global DefaultCollection is used - /// - public class RouteDescriptorCollection - { - public static RouteDescriptorCollection DefaultCollection - { - get - { - if (_DefaultCollection == null) - _DefaultCollection = new RouteDescriptorCollection(); - return _DefaultCollection; - } - } - static RouteDescriptorCollection _DefaultCollection; - - List RouteDescriptors = new List(); - - public void AddRouteDescriptor(RouteDescriptor descriptor) - { - if (RouteDescriptors.Any(t => t.Destination == descriptor.Destination)) - { - Debug.Console(1, descriptor.Destination, - "Route to [{0}] already exists in global routes table", descriptor.Source.Key); - return; - } - RouteDescriptors.Add(descriptor); - } - - public RouteDescriptor GetRouteDescriptorForDestination(IRoutingInputs destination) - { - return RouteDescriptors.FirstOrDefault(rd => rd.Destination == destination); - } - - /// - /// Returns the RouteDescriptor for a given destination and removes it from collection. - /// Returns null if no route with the provided destination exists. - /// - public RouteDescriptor RemoveRouteDescriptor(IRoutingInputs destination) - { - var descr = GetRouteDescriptorForDestination(destination); - if (descr != null) - RouteDescriptors.Remove(descr); - return descr; - } - } - - /// - /// Represents an collection of individual route steps between Source and Destination - /// - public class RouteDescriptor - { - public IRoutingInputs Destination { get; private set; } - public IRoutingOutputs Source { get; private set; } - public eRoutingSignalType SignalType { get; private set; } - public List Routes { get; private set; } - - - public RouteDescriptor(IRoutingOutputs source, IRoutingInputs destination, eRoutingSignalType signalType) - { - Destination = destination; - Source = source; - SignalType = signalType; - Routes = new List(); - } - - public void ExecuteRoutes() - { - foreach (var route in Routes) - { - Debug.Console(2, route.ToString()); - if (route.SwitchingDevice is IRoutingSinkWithSwitching) - (route.SwitchingDevice as IRoutingSinkWithSwitching).ExecuteSwitch(route.InputPort.Selector); - else if (route.SwitchingDevice is IRouting) - { - (route.SwitchingDevice as IRouting).ExecuteSwitch(route.InputPort.Selector, route.OutputPort.Selector, SignalType); - route.OutputPort.InUseTracker.AddUser(Destination, "destination"); - } - } - } - - public void ReleaseRoutes() - { - foreach (var route in Routes) - { - if (route.SwitchingDevice is IRouting) - { - // Pull the route from the port. Whatever is watching the output's in use tracker is - // responsible for responding appropriately. - route.OutputPort.InUseTracker.RemoveUser(Destination, "destination"); - } - } - } - - public override string ToString() - { - var routesText = Routes.Select(r => r.ToString()).ToArray(); - return string.Format("Route table from {0} to {1}:\r{2}", Source.Key, Destination.Key, string.Join("\r", routesText)); - } - } - - /// - /// Represents an individual link for a route - /// - public class RouteSwitchDescriptor - { - public IRoutingInputs SwitchingDevice { get { return InputPort.ParentDevice; } } - public RoutingOutputPort OutputPort { get; set; } - public RoutingInputPort InputPort { get; set; } - - public RouteSwitchDescriptor(RoutingInputPort inputPort) - { - InputPort = inputPort; - } - - public RouteSwitchDescriptor(RoutingOutputPort outputPort, RoutingInputPort inputPort) - { - InputPort = inputPort; - OutputPort = outputPort; - } - - public override string ToString() - { - if(OutputPort == null) // IRoutingSink - return string.Format("{0} switches to input '{1}'", SwitchingDevice.Key, InputPort.Selector); - - return string.Format("{0} switches output '{1}' to input '{2}'", SwitchingDevice.Key, OutputPort.Selector, InputPort.Selector); - } - } -} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/RoutingInterfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/RoutingInterfaces.cs deleted file mode 100644 index 352a35dc..00000000 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/RoutingInterfaces.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.DM; - -using PepperDash.Core; - - -namespace PepperDash.Essentials.Core -{ - //******************************************************************************************* - // Interfaces - - public interface IRoutingInputs : IKeyed - { - RoutingPortCollection InputPorts { get; } - } - - public interface IRoutingOutputs : IKeyed - { - RoutingPortCollection OutputPorts { get; } - } - - /// - /// For fixed-source endpoint devices - /// - public interface IRoutingSinkNoSwitching : IRoutingInputs - { - - } - - public interface IRoutingSinkWithSwitching : IRoutingSinkNoSwitching - { - //void ClearRoute(); - void ExecuteSwitch(object inputSelector); - } - - /// - /// For devices like RMCs, baluns, other devices with no switching. - /// - public interface IRoutingInputsOutputs : IRoutingInputs, IRoutingOutputs - { - } - - public interface IRouting : IRoutingInputsOutputs - { - //void ClearRoute(object outputSelector); - void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType); - } - - public interface IRoutingSource : IRoutingOutputs - { - } -} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/RoutingPort.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/RoutingPort.cs deleted file mode 100644 index e2a026ab..00000000 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/RoutingPort.cs +++ /dev/null @@ -1,144 +0,0 @@ -using System; -using System.Collections.Generic; - -using PepperDash.Core; - - -namespace PepperDash.Essentials.Core -{ - /// - /// Base class for RoutingInput and Output ports - /// - public abstract class RoutingPort : IKeyed - { - public string Key { get; private set; } - public eRoutingSignalType Type { get; private set; } - public eRoutingPortConnectionType ConnectionType { get; private set; } - public readonly object Selector; - public bool IsInternal { get; private set; } - - public RoutingPort(string key, eRoutingSignalType type, eRoutingPortConnectionType connType, object selector, bool isInternal) - { - Key = key; - Type = type; - ConnectionType = connType; - Selector = selector; - IsInternal = IsInternal; - } - } - - public enum eRoutingSignalType - { - Audio, - Video, - AudioVideo - } - - public enum eRoutingPortConnectionType - { - None, BackplaneOnly, Hdmi, Rgb, Vga, LineAudio, DigitalAudio, Sdi, Composite, Component, DmCat, DmMmFiber, DmSmFiber - } - - /// - /// Basic RoutingInput with no statuses. - /// - public class RoutingInputPort : RoutingPort - { - /// - /// The IRoutingInputs object this lives on - /// - public IRoutingInputs ParentDevice { get; private set; } - - /// - /// Constructor for a basic RoutingInputPort - /// - /// An object used to refer to this port in the IRouting device's ExecuteSwitch method. - /// May be string, number, whatever - /// The IRoutingInputs object this lives on - public RoutingInputPort(string key, eRoutingSignalType type, eRoutingPortConnectionType connType, - object selector, IRoutingInputs parent) - : this (key, type, connType, selector, parent, false) - { - } - - /// - /// Constructor for a virtual routing input port that lives inside a device. For example - /// the ports that link a DM card to a DM matrix bus - /// - /// true for internal ports - public RoutingInputPort(string key, eRoutingSignalType type, eRoutingPortConnectionType connType, - object selector, IRoutingInputs parent, bool isInternal) - : base(key, type, connType, selector, isInternal) - { - if (parent == null) - throw new ArgumentNullException("parent"); - ParentDevice = parent; - } - - } - - /// - /// A RoutingInputPort for devices like DM-TX and DM input cards. - /// Will provide video statistics on connected signals - /// - public class RoutingInputPortWithVideoStatuses : RoutingInputPort - { - /// - /// Video statuses attached to this port - /// - public VideoStatusOutputs VideoStatus { get; private set; } - - /// - /// Constructor - /// - /// An object used to refer to this port in the IRouting device's ExecuteSwitch method. - /// May be string, number, whatever - /// The IRoutingInputs object this lives on - /// A VideoStatusFuncsWrapper used to assign the callback funcs that will get - /// the values for the various stats - public RoutingInputPortWithVideoStatuses(string key, - eRoutingSignalType type, eRoutingPortConnectionType connType, object selector, - IRoutingInputs parent, VideoStatusFuncsWrapper funcs) : - base(key, type, connType, selector, parent) - { - VideoStatus = new VideoStatusOutputs(funcs); - } - } - - public class RoutingOutputPort : RoutingPort - { - /// - /// The IRoutingOutputs object this port lives on - /// - public IRoutingOutputs ParentDevice { get; private set; } - - public InUseTracking InUseTracker { get; private set; } - - - /// - /// - /// An object used to refer to this port in the IRouting device's ExecuteSwitch method. - /// May be string, number, whatever - /// The IRoutingOutputs object this port lives on - public RoutingOutputPort(string key, eRoutingSignalType type, eRoutingPortConnectionType connType, - object selector, IRoutingOutputs parent) - : this(key, type, connType, selector, parent, false) - { - } - - public RoutingOutputPort(string key, eRoutingSignalType type, eRoutingPortConnectionType connType, - object selector, IRoutingOutputs parent, bool isInternal) - : base(key, type, connType, selector, isInternal) - { - if (parent == null) - throw new ArgumentNullException("parent"); - ParentDevice = parent; - InUseTracker = new InUseTracking(); - } - - public override string ToString() - { - return ParentDevice.Key + ":" + Key; - } - } -} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/RoutingPortCollection.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/RoutingPortCollection.cs deleted file mode 100644 index ba972ab7..00000000 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/RoutingPortCollection.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -using PepperDash.Core; - - -namespace PepperDash.Essentials.Core -{ - /// - /// Basically a List , with an indexer to find ports by key name - /// - public class RoutingPortCollection : List where T: RoutingPort - { - /// - /// Case-insensitive port lookup linked to ports' keys - /// - public T this[string key] - { - get - { - return this.FirstOrDefault(i => i.Key.Equals(key, StringComparison.OrdinalIgnoreCase)); - } - } - } -} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/TieLine.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/TieLine.cs deleted file mode 100644 index 6a89d2de..00000000 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing-CHECK REMOVE/TieLine.cs +++ /dev/null @@ -1,142 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.DM; - -using PepperDash.Core; - -namespace PepperDash.Essentials.Core -{ - public class TieLine - { - public RoutingOutputPort SourcePort { get; private set; } - public RoutingInputPort DestinationPort { get; private set; } - public int InUseCount { get { return DestinationUsingThis.Count; } } - - /// - /// Gets the type of this tie line. Will either be the type of the desination port - /// or the type of OverrideType when it is set. - /// - public eRoutingSignalType Type - { - get - { - if (OverrideType.HasValue) return OverrideType.Value; - return DestinationPort.Type; - } - } - - /// - /// Use this to override the Type property for the destination port. For example, - /// when the tie line is type AudioVideo, and the signal flow should be limited to - /// Audio-only or Video only, changing this type will alter the signal paths - /// available to the routing algorithm without affecting the actual Type - /// of the destination port. - /// - public eRoutingSignalType? OverrideType { get; set; } - - List DestinationUsingThis = new List(); - - /// - /// For tie lines that represent internal links, like from cards to the matrix in a DM. - /// This property is true if SourcePort and DestinationPort IsInternal - /// property are both true - /// - public bool IsInternal { get { return SourcePort.IsInternal && DestinationPort.IsInternal; } } - public bool TypeMismatch { get { return SourcePort.Type != DestinationPort.Type; } } - public bool ConnectionTypeMismatch { get { return SourcePort.ConnectionType != DestinationPort.ConnectionType; } } - public string TypeMismatchNote { get; set; } - - /// - /// - /// - /// - /// - public TieLine(RoutingOutputPort sourcePort, RoutingInputPort destinationPort) - { - if (sourcePort == null || destinationPort == null) - throw new ArgumentNullException("source or destination port"); - SourcePort = sourcePort; - DestinationPort = destinationPort; - } - - /// - /// Creates a tie line with an overriding Type. See help for OverrideType property for info - /// - /// The signal type to limit the link to. Overrides DestinationPort.Type - public TieLine(RoutingOutputPort sourcePort, RoutingInputPort destinationPort, eRoutingSignalType overrideType) : - this(sourcePort, destinationPort) - { - OverrideType = overrideType; - } - - public static TieLine TieLineFromStrings(string sourceKey, string sourcePortKey, string destinationKey, string destinationPortKey) - { - var sourceDev = DeviceManager.GetDeviceForKey(sourceKey) as IRoutingOutputs; - if (sourceDev == null) - { - Debug.Console(1, "WARNING: Cannot create tie line, routable source '{0}' not found", sourceKey); - return null; - } - var destDev = DeviceManager.GetDeviceForKey(destinationKey) as IRoutingInputs; - if (destDev == null) - { - Debug.Console(1, "WARNING: Cannot create tie line, routable destination '{0}' not found", destinationKey); - return null; - } - var sourcePort = sourceDev.OutputPorts[sourcePortKey]; - if (sourcePort == null) - { - Debug.Console(1, "WARNING: Cannot create tie line. Source '{0}' does not contain port '{1}'", sourceKey, sourcePortKey); - return null; - } - var destPort = destDev.InputPorts[destinationPortKey]; - if (destPort == null) - { - Debug.Console(1, "WARNING: Cannot create tie line. Destination '{0}' does not contain port '{1}'", destinationKey, destinationPortKey); - return null; - } - - return new TieLine(sourcePort, destPort); - } - - /// - /// Will link up video status from supporting inputs to connected outputs - /// - public void Activate() - { - // Now does nothing - } - - public void Deactivate() - { - // Now does nothing - } - - public override string ToString() - { - return string.Format("Tie line: [{0}]{1} --> [{2}]{3}", SourcePort.ParentDevice.Key, SourcePort.Key, - DestinationPort.ParentDevice.Key, DestinationPort.Key); - } - } - - - //******************************************************************************** - - public class TieLineCollection : List - { - public static TieLineCollection Default - { - get - { - if (_Default == null) - _Default = new TieLineCollection(); - return _Default; - } - } - static TieLineCollection _Default; - } -} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/ShadeBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/ShadeBase.cs index 636a5440..d30b716a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/ShadeBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/ShadeBase.cs @@ -12,7 +12,7 @@ namespace PepperDash.Essentials.Core.Shades /// /// Base class for a shade device /// - public abstract class ShadeBase : Device, IShadesOpenClose + public abstract class ShadeBase : EssentialsDevice, IShadesOpenClose { public ShadeBase(string key, string name) : base(key, name) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/ShadeController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/ShadeController.cs index b226af05..fc50f631 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/ShadeController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/ShadeController.cs @@ -5,13 +5,14 @@ using System.Text; using Crestron.SimplSharp; using PepperDash.Core; +using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.Core.Shades { /// /// Class that contains the shades to be controlled in a room /// - public class ShadeController : Device, IShades + public class ShadeController : EssentialsDevice, IShades { ShadeControllerConfigProperties Config; @@ -55,4 +56,21 @@ namespace PepperDash.Essentials.Core.Shades public string Key { get; set; } } } + + public class ShadeControllerFactory : EssentialsDeviceFactory + { + public ShadeControllerFactory() + { + TypeNames = new List() { "shadecontroller" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new ShadeController Device"); + var props = Newtonsoft.Json.JsonConvert.DeserializeObject(dc.Properties.ToString()); + + return new Core.Shades.ShadeController(dc.Key, dc.Name, props); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs index 6c648a29..c9a5f605 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs @@ -28,7 +28,6 @@ namespace PepperDash.Essentials.Core.Touchpanels _Touchpanel.ButtonStateChange += new Crestron.SimplSharpPro.DeviceSupport.ButtonEventHandler(_Touchpanel_ButtonStateChange); - AddPostActivationAction(() => { // Link up the button feedbacks to the specified BoolFeedbacks @@ -40,7 +39,7 @@ namespace PepperDash.Essentials.Core.Touchpanels { var bKey = button.Key.ToLower(); - var feedback = device.GetFeedbackProperty(feedbackConfig.BoolFeedbackName); + var feedback = device.GetFeedbackProperty(feedbackConfig.FeedbackName); var bFeedback = feedback as BoolFeedback; var iFeedback = feedback as IntFeedback; @@ -72,7 +71,7 @@ namespace PepperDash.Essentials.Core.Touchpanels } else { - Debug.Console(1, this, "Unable to get BoolFeedback with name: {0} from device: {1}", feedbackConfig.BoolFeedbackName, device.Key); + Debug.Console(1, this, "Unable to get BoolFeedback with name: {0} from device: {1}", feedbackConfig.FeedbackName, device.Key); } } else @@ -140,6 +139,6 @@ namespace PepperDash.Essentials.Core.Touchpanels public class KeypadButtonFeedback { public string DeviceKey { get; set; } - public string BoolFeedbackName { get; set; } + public string FeedbackName { get; set; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/AirMedia/AirMediaController.cs b/essentials-framework/Essentials DM/Essentials_DM/AirMedia/AirMediaController.cs index 28358a51..8823ae75 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/AirMedia/AirMediaController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/AirMedia/AirMediaController.cs @@ -1,220 +1,288 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; -using Crestron.DeviceSupport.Support; -using Crestron.SimplSharpPro.DM; -using Crestron.SimplSharpPro.DM.AirMedia; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; - -namespace PepperDash.Essentials.DM.AirMedia -{ - public class AirMediaController : CrestronGenericBaseDevice, IRoutingInputsOutputs, IIROutputPorts, IComPorts - { - public AmX00 AirMedia { get; private set; } - - public DeviceConfig DeviceConfig { get; private set; } - - AirMediaPropertiesConfig PropertiesConfig; - - public RoutingPortCollection InputPorts { get; private set; } - - public RoutingPortCollection OutputPorts { get; private set; } - - public BoolFeedback IsInSessionFeedback { get; private set; } - public IntFeedback ErrorFeedback { get; private set; } - public IntFeedback NumberOfUsersConnectedFeedback { get; set; } - public IntFeedback LoginCodeFeedback { get; set; } - public StringFeedback ConnectionAddressFeedback { get; set; } - public StringFeedback HostnameFeedback { get; set; } - public IntFeedback VideoOutFeedback { get; private set; } - public BoolFeedback HdmiVideoSyncDetectedFeedback { get; private set; } - public StringFeedback SerialNumberFeedback { get; private set; } - public BoolFeedback AutomaticInputRoutingEnabledFeedback { get; private set; } - - public AirMediaController(string key, string name, AmX00 device, DeviceConfig dc, AirMediaPropertiesConfig props) - :base(key, name, device) - { - AirMedia = device; - - DeviceConfig = dc; - +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; +using Crestron.DeviceSupport.Support; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DM; +using Crestron.SimplSharpPro.DM.AirMedia; +using Newtonsoft.Json; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; + +namespace PepperDash.Essentials.DM.AirMedia +{ + public class AirMediaController : CrestronGenericBridgeableBaseDevice, IRoutingInputsOutputs, IIROutputPorts, IComPorts + { + public AmX00 AirMedia { get; private set; } + + public DeviceConfig DeviceConfig { get; private set; } + + AirMediaPropertiesConfig PropertiesConfig; + + public RoutingPortCollection InputPorts { get; private set; } + + public RoutingPortCollection OutputPorts { get; private set; } + + public BoolFeedback IsInSessionFeedback { get; private set; } + public IntFeedback ErrorFeedback { get; private set; } + public IntFeedback NumberOfUsersConnectedFeedback { get; set; } + public IntFeedback LoginCodeFeedback { get; set; } + public StringFeedback ConnectionAddressFeedback { get; set; } + public StringFeedback HostnameFeedback { get; set; } + public IntFeedback VideoOutFeedback { get; private set; } + public BoolFeedback HdmiVideoSyncDetectedFeedback { get; private set; } + public StringFeedback SerialNumberFeedback { get; private set; } + public BoolFeedback AutomaticInputRoutingEnabledFeedback { get; private set; } + + public AirMediaController(string key, string name, AmX00 device, DeviceConfig dc, AirMediaPropertiesConfig props) + :base(key, name, device) + { + AirMedia = device; + + DeviceConfig = dc; + PropertiesConfig = props; InputPorts = new RoutingPortCollection(); - OutputPorts = new RoutingPortCollection(); - - InputPorts.Add(new RoutingInputPort(DmPortName.Osd, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.None, new Action(SelectPinPointUxLandingPage), this)); - - InputPorts.Add(new RoutingInputPort(DmPortName.AirMediaIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Streaming, new Action(SelectAirMedia), this)); - - InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, new Action(SelectHdmiIn), this)); - - InputPorts.Add(new RoutingInputPort(DmPortName.AirBoardIn, eRoutingSignalType.Video, - eRoutingPortConnectionType.None, new Action(SelectAirboardIn), this)); - - if (AirMedia is Am300) - { - InputPorts.Add(new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmCat, new Action(SelectDmIn), this)); - } - - AirMedia.AirMedia.AirMediaChange += new Crestron.SimplSharpPro.DeviceSupport.GenericEventHandler(AirMedia_AirMediaChange); - - IsInSessionFeedback = new BoolFeedback( new Func(() => AirMedia.AirMedia.StatusFeedback.UShortValue == 0 )); - ErrorFeedback = new IntFeedback(new Func(() => AirMedia.AirMedia.ErrorFeedback.UShortValue)); - NumberOfUsersConnectedFeedback = new IntFeedback(new Func(() => AirMedia.AirMedia.NumberOfUsersConnectedFeedback.UShortValue)); - LoginCodeFeedback = new IntFeedback(new Func(() => AirMedia.AirMedia.LoginCodeFeedback.UShortValue)); - ConnectionAddressFeedback = new StringFeedback(new Func(() => AirMedia.AirMedia.ConnectionAddressFeedback.StringValue)); - HostnameFeedback = new StringFeedback(new Func(() => AirMedia.AirMedia.HostNameFeedback.StringValue)); - - // TODO: Figure out if we can actually get the TSID/Serial - SerialNumberFeedback = new StringFeedback(new Func(() => "unknown")); - - AirMedia.DisplayControl.DisplayControlChange += new Crestron.SimplSharpPro.DeviceSupport.GenericEventHandler(DisplayControl_DisplayControlChange); - - VideoOutFeedback = new IntFeedback(new Func(() => Convert.ToInt16(AirMedia.DisplayControl.VideoOutFeedback))); - AutomaticInputRoutingEnabledFeedback = new BoolFeedback(new Func(() => AirMedia.DisplayControl.EnableAutomaticRoutingFeedback.BoolValue)); - - AirMedia.HdmiIn.StreamChange += new Crestron.SimplSharpPro.DeviceSupport.StreamEventHandler(HdmiIn_StreamChange); - - HdmiVideoSyncDetectedFeedback = new BoolFeedback(new Func(() => AirMedia.HdmiIn.SyncDetectedFeedback.BoolValue)); - } - - public override bool CustomActivate() - { - if (PropertiesConfig.AutoSwitchingEnabled) - AirMedia.DisplayControl.EnableAutomaticRouting(); - else - AirMedia.DisplayControl.DisableAutomaticRouting(); - - return base.CustomActivate(); - } - - void AirMedia_AirMediaChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args) - { - if (args.EventId == AirMediaInputSlot.AirMediaStatusFeedbackEventId) - IsInSessionFeedback.FireUpdate(); - else if (args.EventId == AirMediaInputSlot.AirMediaErrorFeedbackEventId) - ErrorFeedback.FireUpdate(); - else if (args.EventId == AirMediaInputSlot.AirMediaNumberOfUserConnectedEventId) - NumberOfUsersConnectedFeedback.FireUpdate(); - else if (args.EventId == AirMediaInputSlot.AirMediaLoginCodeEventId) - LoginCodeFeedback.FireUpdate(); - else if (args.EventId == AirMediaInputSlot.AirMediaConnectionAddressFeedbackEventId) - ConnectionAddressFeedback.FireUpdate(); - else if (args.EventId == AirMediaInputSlot.AirMediaHostNameFeedbackEventId) - HostnameFeedback.FireUpdate(); - } - - void DisplayControl_DisplayControlChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args) - { - if (args.EventId == AmX00.VideoOutFeedbackEventId) - VideoOutFeedback.FireUpdate(); - else if (args.EventId == AmX00.EnableAutomaticRoutingFeedbackEventId) - AutomaticInputRoutingEnabledFeedback.FireUpdate(); - } - - void HdmiIn_StreamChange(Crestron.SimplSharpPro.DeviceSupport.Stream stream, Crestron.SimplSharpPro.DeviceSupport.StreamEventArgs args) - { - if (args.EventId == DMInputEventIds.SourceSyncEventId) - HdmiVideoSyncDetectedFeedback.FireUpdate(); - } - - /// - /// Sets the VideoOut source ( 0 = PinpointUX, 1 = AirMedia, 2 = HDMI, 3 = DM, 4 = Airboard ) - /// - /// source number - public void SelectVideoOut(uint source) - { - AirMedia.DisplayControl.VideoOut = (AmX00DisplayControl.eAirMediaX00VideoSource)source; - } - - /// - /// Selects the PinPointUXLandingPage input - /// - public void SelectPinPointUxLandingPage() - { - AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.PinPointUxLandingPage; - } - - /// - /// Selects the AirMedia input - /// - public void SelectAirMedia() - { - AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.AirMedia; - } - - /// - /// Selects the DM input - /// - public void SelectDmIn() - { - AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.HDMI; - } - - /// - /// Selects the HDMI INput - /// - public void SelectHdmiIn() - { - AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.DM; - } - - public void SelectAirboardIn() - { - AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.AirBoard; - } - - /// - /// Reboots the device - /// - public void RebootDevice() - { - AirMedia.AirMedia.DeviceReboot(); - } - - #region IIROutputPorts Members - - public CrestronCollection IROutputPorts - { - get { return AirMedia.IROutputPorts; } - } - - public int NumberOfIROutputPorts - { - get { return AirMedia.NumberOfIROutputPorts; } - } - - - - #endregion - - - - #region IComPorts Members - - public CrestronCollection ComPorts - { - get { return AirMedia.ComPorts; } - } - - public int NumberOfComPorts - { - get { return AirMedia.NumberOfComPorts; } - } - - #endregion - - - } + OutputPorts = new RoutingPortCollection(); + + InputPorts.Add(new RoutingInputPort(DmPortName.Osd, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.None, new Action(SelectPinPointUxLandingPage), this)); + + InputPorts.Add(new RoutingInputPort(DmPortName.AirMediaIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Streaming, new Action(SelectAirMedia), this)); + + InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, new Action(SelectHdmiIn), this)); + + InputPorts.Add(new RoutingInputPort(DmPortName.AirBoardIn, eRoutingSignalType.Video, + eRoutingPortConnectionType.None, new Action(SelectAirboardIn), this)); + + if (AirMedia is Am300) + { + InputPorts.Add(new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmCat, new Action(SelectDmIn), this)); + } + + AirMedia.AirMedia.AirMediaChange += new Crestron.SimplSharpPro.DeviceSupport.GenericEventHandler(AirMedia_AirMediaChange); + + IsInSessionFeedback = new BoolFeedback( new Func(() => AirMedia.AirMedia.StatusFeedback.UShortValue == 0 )); + ErrorFeedback = new IntFeedback(new Func(() => AirMedia.AirMedia.ErrorFeedback.UShortValue)); + NumberOfUsersConnectedFeedback = new IntFeedback(new Func(() => AirMedia.AirMedia.NumberOfUsersConnectedFeedback.UShortValue)); + LoginCodeFeedback = new IntFeedback(new Func(() => AirMedia.AirMedia.LoginCodeFeedback.UShortValue)); + ConnectionAddressFeedback = new StringFeedback(new Func(() => AirMedia.AirMedia.ConnectionAddressFeedback.StringValue)); + HostnameFeedback = new StringFeedback(new Func(() => AirMedia.AirMedia.HostNameFeedback.StringValue)); + + // TODO: Figure out if we can actually get the TSID/Serial + SerialNumberFeedback = new StringFeedback(new Func(() => "unknown")); + + AirMedia.DisplayControl.DisplayControlChange += new Crestron.SimplSharpPro.DeviceSupport.GenericEventHandler(DisplayControl_DisplayControlChange); + + VideoOutFeedback = new IntFeedback(new Func(() => Convert.ToInt16(AirMedia.DisplayControl.VideoOutFeedback))); + AutomaticInputRoutingEnabledFeedback = new BoolFeedback(new Func(() => AirMedia.DisplayControl.EnableAutomaticRoutingFeedback.BoolValue)); + + AirMedia.HdmiIn.StreamChange += new Crestron.SimplSharpPro.DeviceSupport.StreamEventHandler(HdmiIn_StreamChange); + + HdmiVideoSyncDetectedFeedback = new BoolFeedback(new Func(() => AirMedia.HdmiIn.SyncDetectedFeedback.BoolValue)); + } + + public override bool CustomActivate() + { + if (PropertiesConfig.AutoSwitchingEnabled) + AirMedia.DisplayControl.EnableAutomaticRouting(); + else + AirMedia.DisplayControl.DisableAutomaticRouting(); + + return base.CustomActivate(); + } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new AirMediaControllerJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + Debug.Console(0, "Linking to Airmedia: {0}", Name); + + trilist.StringInput[joinMap.Name].StringValue = Name; + + var commMonitor = this as ICommunicationMonitor; + + commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + + IsInSessionFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsInSession]); + HdmiVideoSyncDetectedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.HdmiVideoSync]); + + trilist.SetSigTrueAction(joinMap.AutomaticInputRoutingEnabled, AirMedia.DisplayControl.EnableAutomaticRouting); + trilist.SetSigFalseAction(joinMap.AutomaticInputRoutingEnabled, AirMedia.DisplayControl.DisableAutomaticRouting); + AutomaticInputRoutingEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AutomaticInputRoutingEnabled]); + + trilist.SetUShortSigAction(joinMap.VideoOut, (u) => SelectVideoOut(u)); + + VideoOutFeedback.LinkInputSig(trilist.UShortInput[joinMap.VideoOut]); + ErrorFeedback.LinkInputSig(trilist.UShortInput[joinMap.ErrorFB]); + NumberOfUsersConnectedFeedback.LinkInputSig(trilist.UShortInput[joinMap.NumberOfUsersConnectedFB]); + + trilist.SetUShortSigAction(joinMap.LoginCode, (u) => AirMedia.AirMedia.LoginCode.UShortValue = u); + LoginCodeFeedback.LinkInputSig(trilist.UShortInput[joinMap.LoginCode]); + + ConnectionAddressFeedback.LinkInputSig(trilist.StringInput[joinMap.ConnectionAddressFB]); + HostnameFeedback.LinkInputSig(trilist.StringInput[joinMap.HostnameFB]); + SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumberFeedback]); + } + + void AirMedia_AirMediaChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args) + { + if (args.EventId == AirMediaInputSlot.AirMediaStatusFeedbackEventId) + IsInSessionFeedback.FireUpdate(); + else if (args.EventId == AirMediaInputSlot.AirMediaErrorFeedbackEventId) + ErrorFeedback.FireUpdate(); + else if (args.EventId == AirMediaInputSlot.AirMediaNumberOfUserConnectedEventId) + NumberOfUsersConnectedFeedback.FireUpdate(); + else if (args.EventId == AirMediaInputSlot.AirMediaLoginCodeEventId) + LoginCodeFeedback.FireUpdate(); + else if (args.EventId == AirMediaInputSlot.AirMediaConnectionAddressFeedbackEventId) + ConnectionAddressFeedback.FireUpdate(); + else if (args.EventId == AirMediaInputSlot.AirMediaHostNameFeedbackEventId) + HostnameFeedback.FireUpdate(); + } + + void DisplayControl_DisplayControlChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args) + { + if (args.EventId == AmX00.VideoOutFeedbackEventId) + VideoOutFeedback.FireUpdate(); + else if (args.EventId == AmX00.EnableAutomaticRoutingFeedbackEventId) + AutomaticInputRoutingEnabledFeedback.FireUpdate(); + } + + void HdmiIn_StreamChange(Crestron.SimplSharpPro.DeviceSupport.Stream stream, Crestron.SimplSharpPro.DeviceSupport.StreamEventArgs args) + { + if (args.EventId == DMInputEventIds.SourceSyncEventId) + HdmiVideoSyncDetectedFeedback.FireUpdate(); + } + + /// + /// Sets the VideoOut source ( 0 = PinpointUX, 1 = AirMedia, 2 = HDMI, 3 = DM, 4 = Airboard ) + /// + /// source number + public void SelectVideoOut(uint source) + { + AirMedia.DisplayControl.VideoOut = (AmX00DisplayControl.eAirMediaX00VideoSource)source; + } + + /// + /// Selects the PinPointUXLandingPage input + /// + public void SelectPinPointUxLandingPage() + { + AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.PinPointUxLandingPage; + } + + /// + /// Selects the AirMedia input + /// + public void SelectAirMedia() + { + AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.AirMedia; + } + + /// + /// Selects the DM input + /// + public void SelectDmIn() + { + AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.HDMI; + } + + /// + /// Selects the HDMI INput + /// + public void SelectHdmiIn() + { + AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.DM; + } + + public void SelectAirboardIn() + { + AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.AirBoard; + } + + /// + /// Reboots the device + /// + public void RebootDevice() + { + AirMedia.AirMedia.DeviceReboot(); + } + + #region IIROutputPorts Members + + public CrestronCollection IROutputPorts + { + get { return AirMedia.IROutputPorts; } + } + + public int NumberOfIROutputPorts + { + get { return AirMedia.NumberOfIROutputPorts; } + } + + + + #endregion + + + + #region IComPorts Members + + public CrestronCollection ComPorts + { + get { return AirMedia.ComPorts; } + } + + public int NumberOfComPorts + { + get { return AirMedia.NumberOfComPorts; } + } + + #endregion + + + } + + public class AirMediaControllerFactory : EssentialsDeviceFactory + { + public AirMediaControllerFactory() + { + TypeNames = new List() { "am200", "am300" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + var type = dc.Type.ToLower(); + + Debug.Console(1, "Factory Attempting to create new AirMedia Device"); + + var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); + AmX00 amDevice = null; + if (type == "am200") + amDevice = new Crestron.SimplSharpPro.DM.AirMedia.Am200(props.Control.IpIdInt, Global.ControlSystem); + else if (type == "am300") + amDevice = new Crestron.SimplSharpPro.DM.AirMedia.Am300(props.Control.IpIdInt, Global.ControlSystem); + + return new AirMediaController(dc.Key, dc.Name, amDevice, dc, props); + + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs index 7d57127a..5ce95c93 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs @@ -4,15 +4,16 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Cards; using Crestron.SimplSharpPro.DM.Blades; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; - +using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; - +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.DM.Config; namespace PepperDash.Essentials.DM { @@ -20,7 +21,7 @@ namespace PepperDash.Essentials.DM { /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions /// /// - public class DmBladeChassisController : CrestronGenericBaseDevice, IDmSwitch, IRoutingInputsOutputs, IRouting, IHasFeedback { + public class DmBladeChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingInputsOutputs, IRouting, IHasFeedback { public DMChassisPropertiesConfig PropertiesConfig { get; set; } public Switch Chassis { get; private set; } @@ -570,6 +571,243 @@ namespace PepperDash.Essentials.DM { #endregion + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new DmBladeChassisControllerJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + + // Link up outputs + for (uint i = 1; i <= Chassis.NumberOfOutputs; i++) + { + var ioSlot = i; + + // Control + trilist.SetUShortSigAction(joinMap.OutputVideo + ioSlot, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video)); + + if (TxDictionary.ContainsKey(ioSlot)) + { + Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot); + var txKey = TxDictionary[ioSlot]; + var basicTxDevice = DeviceManager.GetDeviceForKey(txKey) as DmTxControllerBase; + + var advancedTxDevice = basicTxDevice as DmTxControllerBase; + + if (Chassis is DmMd128x128 || Chassis is DmMd64x64) + { + InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); + } + else + { + if (advancedTxDevice != null) + { + advancedTxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); + Debug.Console(2, "Linking Tx Online Feedback from Advanced Transmitter at input {0}", ioSlot); + } + else if (InputEndpointOnlineFeedbacks[ioSlot] != null) + { + Debug.Console(2, "Linking Tx Online Feedback from Input Card {0}", ioSlot); + InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); + } + } + + if (basicTxDevice != null && advancedTxDevice == null) + trilist.BooleanInput[joinMap.TxAdvancedIsPresent + ioSlot].BoolValue = true; + + if (advancedTxDevice != null) + { + advancedTxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); + } + else + { + Debug.Console(1, "Setting up actions and feedbacks on input card {0}", ioSlot); + VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); + + var inputPort = InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; + if (inputPort != null) + { + Debug.Console(1, "Port value for input card {0} is set", ioSlot); + var port = inputPort.Port; + + if (port != null) + { + if (port is HdmiInputWithCEC) + { + Debug.Console(1, "Port is HdmiInputWithCec"); + + var hdmiInPortWCec = port as HdmiInputWithCEC; + + if (hdmiInPortWCec.HdcpSupportedLevel != eHdcpSupportedLevel.Unknown) + { + SetHdcpStateAction(true, hdmiInPortWCec, joinMap.HdcpSupportState + ioSlot, trilist); + } + + InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); + + if (InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) + trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = (ushort)InputCardHdcpCapabilityTypes[ioSlot]; + else + trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = 1; + } + } + } + else + { + inputPort = InputPorts[string.Format("inputCard{0}--dmIn", ioSlot)]; + + if (inputPort != null) + { + var port = inputPort.Port; + + if (port is DMInputPortWithCec) + { + Debug.Console(1, "Port is DMInputPortWithCec"); + + var dmInPortWCec = port as DMInputPortWithCec; + + SetHdcpStateAction(PropertiesConfig.InputSlotSupportsHdcp2[ioSlot], dmInPortWCec, joinMap.HdcpSupportState + ioSlot, trilist); + + InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); + + if (InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) + trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = (ushort)InputCardHdcpCapabilityTypes[ioSlot]; + else + trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = 1; + } + } + } + } + } + else + { + VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); + + var inputPort = InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; + if (inputPort != null) + { + var hdmiPort = inputPort.Port as EndpointHdmiInput; + + if (hdmiPort != null) + { + SetHdcpStateAction(true, hdmiPort, joinMap.HdcpSupportState + ioSlot, trilist); + InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); + } + } + } + if (RxDictionary.ContainsKey(ioSlot)) + { + Debug.Console(2, "Creating Rx Feedbacks {0}", ioSlot); + //var rxKey = RxDictionary[ioSlot]; + //var rxDevice = DeviceManager.GetDeviceForKey(rxKey) as DmRmcControllerBase; + //var hdBaseTDevice = DeviceManager.GetDeviceForKey(rxKey) as DmHdBaseTControllerBase; + //if (hdBaseTDevice != null) { + OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]); + //} + //else if (rxDevice != null) { + // rxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]); + //} + } + + // Feedback + VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo + ioSlot]); + + + OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames + ioSlot]); + InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames + ioSlot]); + OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames + ioSlot]); + } + } + + private void SetHdcpStateAction(bool hdcpTypeSimple, HdmiInputWithCEC port, uint join, BasicTriList trilist) + { + if (hdcpTypeSimple) + { + trilist.SetUShortSigAction(join, + s => + { + if (s == 0) + { + port.HdcpSupportOff(); + } + else if (s > 0) + { + port.HdcpSupportOn(); + } + }); + } + else + { + trilist.SetUShortSigAction(join, + u => + { + port.HdcpReceiveCapability = (eHdcpCapabilityType)u; + }); + } + } + + private void SetHdcpStateAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist) + { + if (hdcpTypeSimple) + { + trilist.SetUShortSigAction(join, + s => + { + if (s == 0) + { + port.HdcpSupportOff(); + } + else if (s > 0) + { + port.HdcpSupportOn(); + } + }); + } + else + { + trilist.SetUShortSigAction(join, + u => + { + port.HdcpCapability = (eHdcpCapabilityType)u; + }); + } + } + + private void SetHdcpStateAction(bool supportsHdcp2, DMInputPortWithCec port, uint join, BasicTriList trilist) + { + if (!supportsHdcp2) + { + trilist.SetUShortSigAction(join, + s => + { + if (s == 0) + { + port.HdcpSupportOff(); + } + else if (s > 0) + { + port.HdcpSupportOn(); + } + }); + } + else + { + trilist.SetUShortSigAction(join, + u => + { + port.HdcpReceiveCapability = (eHdcpCapabilityType)u; + }); + } + } } /* diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 033d6a54..7313aece 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -2,11 +2,16 @@ using System; using System.Collections.Generic; using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Cards; +using Crestron.SimplSharpPro.DM.Endpoints; +using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.DM.Config; +using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.DM { @@ -14,7 +19,8 @@ namespace PepperDash.Essentials.DM /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions /// /// - public class DmChassisController : CrestronGenericBaseDevice, IDmSwitch, IRoutingInputsOutputs, IRouting, IHasFeedback + [Description("Wrapper class for all DM-MD chassis variants from 8x8 to 128x128")] + public class DmChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingInputsOutputs, IRouting, IHasFeedback { public DMChassisPropertiesConfig PropertiesConfig { get; set; } @@ -985,6 +991,277 @@ namespace PepperDash.Essentials.DM } } #endregion + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new DmChassisControllerJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + var chassis = Chassis as DmMDMnxn; + + IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + + trilist.SetUShortSigAction(joinMap.SystemId, o => + { + if (chassis != null) + chassis.SystemId.UShortValue = o; + }); + + trilist.SetSigTrueAction(joinMap.SystemId, () => { + if (chassis != null) chassis.ApplySystemId(); + }); + + SystemIdFeebdack.LinkInputSig(trilist.UShortInput[joinMap.SystemId]); + SystemIdBusyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SystemId]); + + // Link up outputs + for (uint i = 1; i <= Chassis.NumberOfOutputs; i++) + { + var ioSlot = i; + + // Control + trilist.SetUShortSigAction(joinMap.OutputVideo + ioSlot, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video)); + trilist.SetUShortSigAction(joinMap.OutputAudio + ioSlot, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio)); + trilist.SetUShortSigAction(joinMap.OutputUsb + ioSlot, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.UsbOutput)); + trilist.SetUShortSigAction(joinMap.InputUsb + ioSlot, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.UsbInput)); + + if (TxDictionary.ContainsKey(ioSlot)) + { + Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot); + var txKey = TxDictionary[ioSlot]; + var basicTxDevice = DeviceManager.GetDeviceForKey(txKey) as DmTxControllerBase; + + var advancedTxDevice = basicTxDevice; + + if (Chassis is DmMd8x8Cpu3 || Chassis is DmMd8x8Cpu3rps + || Chassis is DmMd16x16Cpu3 || Chassis is DmMd16x16Cpu3rps + || Chassis is DmMd32x32Cpu3 || Chassis is DmMd32x32Cpu3rps) + { + InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); + } + else + { + if (advancedTxDevice != null) + { + advancedTxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); + Debug.Console(2, "Linking Tx Online Feedback from Advanced Transmitter at input {0}", ioSlot); + } + else if (InputEndpointOnlineFeedbacks[ioSlot] != null) + { + Debug.Console(2, "Linking Tx Online Feedback from Input Card {0}", ioSlot); + InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); + } + } + + if (basicTxDevice != null && advancedTxDevice == null) + trilist.BooleanInput[joinMap.TxAdvancedIsPresent + ioSlot].BoolValue = true; + + if (advancedTxDevice != null) + { + advancedTxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); + } + else if (advancedTxDevice == null || basicTxDevice != null) + { + Debug.Console(1, "Setting up actions and feedbacks on input card {0}", ioSlot); + VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); + + var inputPort = InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; + if (inputPort != null) + { + Debug.Console(1, "Port value for input card {0} is set", ioSlot); + var port = inputPort.Port; + + if (port != null) + { + if (port is HdmiInputWithCEC) + { + Debug.Console(1, "Port is HdmiInputWithCec"); + + var hdmiInPortWCec = port as HdmiInputWithCEC; + + if (hdmiInPortWCec.HdcpSupportedLevel != eHdcpSupportedLevel.Unknown) + { + SetHdcpStateAction(true, hdmiInPortWCec, joinMap.HdcpSupportState + ioSlot, trilist); + } + + InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); + + if (InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) + trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = (ushort)InputCardHdcpCapabilityTypes[ioSlot]; + else + trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = 1; + } + } + } + else + { + inputPort = InputPorts[string.Format("inputCard{0}--dmIn", ioSlot)]; + + if (inputPort != null) + { + var port = inputPort.Port; + + if (port is DMInputPortWithCec) + { + Debug.Console(1, "Port is DMInputPortWithCec"); + + var dmInPortWCec = port as DMInputPortWithCec; + + if (dmInPortWCec != null) + { + SetHdcpStateAction(PropertiesConfig.InputSlotSupportsHdcp2[ioSlot], dmInPortWCec, joinMap.HdcpSupportState + ioSlot, trilist); + } + + InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); + + if (InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) + trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = (ushort)InputCardHdcpCapabilityTypes[ioSlot]; + else + trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = 1; + } + } + } + } + } + else + { + VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); + + var inputPort = InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; + if (inputPort != null) + { + var hdmiPort = inputPort.Port as EndpointHdmiInput; + + if (hdmiPort != null) + { + SetHdcpStateAction(true, hdmiPort, joinMap.HdcpSupportState + ioSlot, trilist); + InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); + } + } + } + + if (RxDictionary.ContainsKey(ioSlot)) + { + Debug.Console(2, "Creating Rx Feedbacks {0}", ioSlot); + var rxKey = RxDictionary[ioSlot]; + var rxDevice = DeviceManager.GetDeviceForKey(rxKey) as DmRmcControllerBase; + var hdBaseTDevice = DeviceManager.GetDeviceForKey(rxKey) as DmHdBaseTControllerBase; + if (Chassis is DmMd8x8Cpu3 || Chassis is DmMd8x8Cpu3rps + || Chassis is DmMd16x16Cpu3 || Chassis is DmMd16x16Cpu3rps + || Chassis is DmMd32x32Cpu3 || Chassis is DmMd32x32Cpu3rps || hdBaseTDevice != null) + { + OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]); + } + else if (rxDevice != null) + { + rxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]); + } + } + + // Feedback + VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo + ioSlot]); + AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio + ioSlot]); + UsbOutputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputUsb + ioSlot]); + UsbInputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.InputUsb + ioSlot]); + + OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames + ioSlot]); + InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames + ioSlot]); + OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames + ioSlot]); + OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentAudioInputNames + ioSlot]); + + OutputDisabledByHdcpFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputDisabledByHdcp + ioSlot]); + } + } + + private void SetHdcpStateAction(bool hdcpTypeSimple, HdmiInputWithCEC port, uint join, BasicTriList trilist) + { + if (hdcpTypeSimple) + { + trilist.SetUShortSigAction(join, + s => + { + if (s == 0) + { + port.HdcpSupportOff(); + } + else if (s > 0) + { + port.HdcpSupportOn(); + } + }); + } + else + { + trilist.SetUShortSigAction(join, + u => + { + port.HdcpReceiveCapability = (eHdcpCapabilityType)u; + }); + } + } + + private void SetHdcpStateAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist) + { + if (hdcpTypeSimple) + { + trilist.SetUShortSigAction(join, + s => + { + if (s == 0) + { + port.HdcpSupportOff(); + } + else if (s > 0) + { + port.HdcpSupportOn(); + } + }); + } + else + { + trilist.SetUShortSigAction(join, + u => + { + port.HdcpCapability = (eHdcpCapabilityType)u; + }); + } + } + + private void SetHdcpStateAction(bool supportsHdcp2, DMInputPortWithCec port, uint join, BasicTriList trilist) + { + if (!supportsHdcp2) + { + trilist.SetUShortSigAction(join, + s => + { + if (s == 0) + { + port.HdcpSupportOff(); + } + else if (s > 0) + { + port.HdcpSupportOn(); + } + }); + } + else + { + trilist.SetUShortSigAction(join, + u => + { + port.HdcpReceiveCapability = (eHdcpCapabilityType)u; + }); + } + } } public struct PortNumberType @@ -1000,4 +1277,41 @@ namespace PepperDash.Essentials.DM } } -} \ No newline at end of file + public class DmChassisControllerFactory : EssentialsDeviceFactory + { + public DmChassisControllerFactory() + { + TypeNames = new List() { "dmmd8x8", "dmmd8x8rps", "dmmd8x8cpu3", "dmmd8x8cpu3rps", + "dmmd16x16", "dmmd16x16rps", "dmmd16x16cpu3", "dmmd16x16cpu3rps", + "dmmd32x32", "dmmd32x32rps", "dmmd32x32cpu3", "dmmd32x32cpu3rps", + "dmmd64x64", "dmmd128x128" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + var type = dc.Type.ToLower(); + + Debug.Console(1, "Factory Attempting to create new DmChassisController Device"); + + if (type.StartsWith("dmmd8x") || type.StartsWith("dmmd16x") || type.StartsWith("dmmd32x")) + { + + var props = JsonConvert.DeserializeObject + (dc.Properties.ToString()); + return PepperDash.Essentials.DM.DmChassisController. + GetDmChassisController(dc.Key, dc.Name, type, props); + } + else if (type.StartsWith("dmmd128x") || type.StartsWith("dmmd64x")) + { + var props = JsonConvert.DeserializeObject + (dc.Properties.ToString()); + return PepperDash.Essentials.DM.DmBladeChassisController. + GetDmChassisController(dc.Key, dc.Name, type, props); + } + + return null; + } + } + +} + diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs index 8856be01..d330d650 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs @@ -4,21 +4,22 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; - +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Cards; - +using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; - +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.DM.Config; + namespace PepperDash.Essentials.DM { /// /// Exposes the volume levels for Program, Aux1 or Aux2 outputs on a DMPS3 chassis /// - public class DmpsAudioOutputController : Device + public class DmpsAudioOutputController : EssentialsBridgeableDevice { Card.Dmps3OutputBase OutputCard; @@ -100,6 +101,62 @@ namespace PepperDash.Essentials.DM } } } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new DmpsAudioOutputControllerJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + if (MasterVolumeLevel != null) + { + SetUpDmpsAudioOutputJoins(trilist, MasterVolumeLevel, joinMap.MasterVolume); + } + + if (SourceVolumeLevel != null) + { + SetUpDmpsAudioOutputJoins(trilist, SourceVolumeLevel, joinMap.SourceVolume); + } + + if (Codec1VolumeLevel != null) + { + SetUpDmpsAudioOutputJoins(trilist, Codec1VolumeLevel, joinMap.Codec1Volume); + } + + if (Codec2VolumeLevel != null) + { + SetUpDmpsAudioOutputJoins(trilist, Codec2VolumeLevel, joinMap.Codec2Volume); + } + + } + + static void SetUpDmpsAudioOutputJoins(BasicTriList trilist, DmpsAudioOutput output, uint joinStart) + { + var volumeLevelJoin = joinStart; + var muteOnJoin = joinStart; + var muteOffJoin = joinStart + 1; + var volumeUpJoin = joinStart + 2; + var volumeDownJoin = joinStart + 3; + + + trilist.SetUShortSigAction(volumeLevelJoin, output.SetVolume); + output.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[volumeLevelJoin]); + + trilist.SetSigTrueAction(muteOnJoin, output.MuteOn); + output.MuteFeedback.LinkInputSig(trilist.BooleanInput[muteOnJoin]); + trilist.SetSigTrueAction(muteOffJoin, output.MuteOff); + output.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[muteOffJoin]); + + trilist.SetBoolSigAction(volumeUpJoin, output.VolumeUp); + trilist.SetBoolSigAction(volumeDownJoin, output.VolumeDown); + } } public class DmpsAudioOutput : IBasicVolumeWithFeedback diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 6ed0e63b..4c4b256d 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -4,19 +4,22 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Cards; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; - +using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; - +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.DM.Config; +using Feedback = PepperDash.Essentials.Core.Feedback; + namespace PepperDash.Essentials.DM { - public class DmpsRoutingController : Device, IRoutingInputsOutputs, IRouting, IHasFeedback + public class DmpsRoutingController : EssentialsBridgeableDevice, IRouting, IHasFeedback { public CrestronControlSystem Dmps { get; set; } public ISystemControl SystemControl { get; private set; } @@ -151,6 +154,114 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new DmpsRoutingControllerJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + // Link up outputs + for (uint i = 1; i <= Dmps.NumberOfSwitcherInputs; i++) + { + Debug.Console(2, this, "Linking Input Card {0}", i); + + var ioSlot = i; + + //if (TxDictionary.ContainsKey(ioSlot)) + //{ + // Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot); + // var TxKey = TxDictionary[ioSlot]; + // var TxDevice = DeviceManager.GetDeviceForKey(TxKey) as DmTxControllerBase; + // //TxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); + // // TxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); + // // trilist.SetUShortSigAction((ApiMap.HdcpSupport[ioSlot]), u => TxDevice.SetHdcpSupportAll((ePdtHdcpSupport)(u))); + // // TxDevice.HdcpSupportAllFeedback.LinkInputSig(trilist.UShortInput[joinMap. + ioSlot]); + // // trilist.UShortInput[ApiMap.HdcpSupportCapability[ioSlot]].UShortValue = TxDevice.HdcpSupportCapability; + //} + //else + //{ + // // dmChassis.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[ApiMap.TxVideoSyncStatus[ioSlot]]); + //} + + if (VideoInputSyncFeedbacks[ioSlot] != null) + VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); + + if (InputNameFeedbacks[ioSlot] != null) + InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames + ioSlot]); + + trilist.SetStringSigAction(joinMap.InputNames + ioSlot, new Action(s => + { + var inputCard = Dmps.SwitcherInputs[ioSlot] as DMInput; + + if (inputCard != null) + { + if (inputCard.NameFeedback != null && !string.IsNullOrEmpty(inputCard.NameFeedback.StringValue) && inputCard.NameFeedback.StringValue != s) + if (inputCard.Name != null) + inputCard.Name.StringValue = s; + } + })); + + + if (InputEndpointOnlineFeedbacks[ioSlot] != null) + InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); + } + + for (uint i = 1; i <= Dmps.NumberOfSwitcherOutputs; i++) + { + Debug.Console(2, this, "Linking Output Card {0}", i); + + var ioSlot = i; + // Control + trilist.SetUShortSigAction(joinMap.OutputVideo + ioSlot, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video)); + trilist.SetUShortSigAction(joinMap.OutputAudio + ioSlot, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio)); + + trilist.SetStringSigAction(joinMap.OutputNames + ioSlot, s => + { + var outputCard = Dmps.SwitcherOutputs[ioSlot] as DMOutput; + + //Debug.Console(2, dmpsRouter, "Output Name String Sig Action for Output Card {0}", ioSlot); + + if (outputCard != null) + { + //Debug.Console(2, dmpsRouter, "Card Type: {0}", outputCard.CardInputOutputType); + + if (!(outputCard is Card.Dmps3CodecOutput) && outputCard.NameFeedback != null) + { + if (!string.IsNullOrEmpty(outputCard.NameFeedback.StringValue)) + { + //Debug.Console(2, dmpsRouter, "NameFeedabck: {0}", outputCard.NameFeedback.StringValue); + + if (outputCard.NameFeedback.StringValue != s && outputCard.Name != null) + { + outputCard.Name.StringValue = s; + } + } + } + } + }); + + // Feedback + if (VideoOutputFeedbacks[ioSlot] != null) + VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo + ioSlot]); + if (AudioOutputFeedbacks[ioSlot] != null) + AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio + ioSlot]); + if (OutputNameFeedbacks[ioSlot] != null) + OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames + ioSlot]); + if (OutputVideoRouteNameFeedbacks[ioSlot] != null) + OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames + ioSlot]); + if (OutputAudioRouteNameFeedbacks[ioSlot] != null) + OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentAudioInputNames + ioSlot]); + if (OutputEndpointOnlineFeedbacks[ioSlot] != null) + OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]); + } + } /// diff --git a/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs b/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs index 2417ce7e..5c532ac5 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Collections.Generic; using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronIO; @@ -6,6 +7,7 @@ using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.AirMedia; using Crestron.SimplSharpPro.UI; +using Crestron.SimplSharp.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -17,86 +19,33 @@ using PepperDash.Essentials.DM.Endpoints.DGEs; namespace PepperDash.Essentials.DM { - public class DeviceFactory - { - public static IKeyed GetDevice(DeviceConfig dc) - { - var key = dc.Key; - var name = dc.Name; - var type = dc.Type; - var properties = dc.Properties; + /// + /// Responsible for loading the type factories for this library + /// + public class DeviceFactory + { + public DeviceFactory() + { + var assy = Assembly.GetExecutingAssembly(); + PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy); + + var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract); - var typeName = dc.Type.ToLower(); - - if (typeName.StartsWith("am")) + if (types != null) { - if (typeName == "am200" || typeName == "am300") + foreach (var type in types) { - var props = JsonConvert.DeserializeObject(properties.ToString()); - AmX00 amDevice = null; - if (typeName == "am200") - amDevice = new Crestron.SimplSharpPro.DM.AirMedia.Am200(props.Control.IpIdInt, Global.ControlSystem); - else if (typeName == "am300") - amDevice = new Crestron.SimplSharpPro.DM.AirMedia.Am300(props.Control.IpIdInt, Global.ControlSystem); - - return new AirMediaController(key, name, amDevice, dc, props); + try + { + var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); + factory.LoadTypeFactories(); + } + catch (Exception e) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name); + } } } - else if (typeName.StartsWith("dmmd8x") || typeName.StartsWith("dmmd16x") || typeName.StartsWith("dmmd32x")) - { - var props = JsonConvert.DeserializeObject - (properties.ToString()); - return PepperDash.Essentials.DM.DmChassisController. - GetDmChassisController(key, name, type, props); - } - else if (typeName.StartsWith("dmmd128x") || typeName.StartsWith("dmmd64x")) { - var props = JsonConvert.DeserializeObject - (properties.ToString()); - return PepperDash.Essentials.DM.DmBladeChassisController. - GetDmChassisController(key, name, type, props); - } - // Hand off to DmTxHelper class - else if (typeName.StartsWith("dmtx")) { - var props = JsonConvert.DeserializeObject - (properties.ToString()); - return PepperDash.Essentials.DM.DmTxHelper.GetDmTxController(key, name, type, props); - } - - // Hand off to DmRmcHelper class - else if (typeName.StartsWith("dmrmc")) { - var props = JsonConvert.DeserializeObject - (properties.ToString()); - return PepperDash.Essentials.DM.DmRmcHelper.GetDmRmcController(key, name, type, props); - } - - else if (typeName.Equals("hdmd4x14ke")) { - var props = JsonConvert.DeserializeObject - (properties.ToString()); - return PepperDash.Essentials.DM.Chassis.HdMdNxM4kEController.GetController(key, name, type, props); - } - - else if (typeName.Equals("hdmd400ce") || typeName.Equals("hdmd300ce") || typeName.Equals("hdmd200ce") || typeName.Equals("hdmd200c1ge")) { - var props = JsonConvert.DeserializeObject - (properties.ToString()); - - if (typeName.Equals("hdmd400ce")) - return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, - new HdMd400CE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); - else if (typeName.Equals("hdmd300ce")) - return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, - new HdMd300CE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); - else if (typeName.Equals("hdmd200ce")) - return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, - new HdMd200CE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); - else if (typeName.Equals("hdmd200c1ge")) - return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, - new HdMd200C1GE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); - } - - return null; - } - - - } - + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/DmLite/HdMdxxxCEController.cs b/essentials-framework/Essentials DM/Essentials_DM/DmLite/HdMdxxxCEController.cs index 8113c218..59a318cd 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/DmLite/HdMdxxxCEController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/DmLite/HdMdxxxCEController.cs @@ -4,19 +4,23 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; - +using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.DM { /// /// Represent both a transmitter and receiver pair of the HD-MD-400-C-E / HD-MD-300-C-E / HD-MD-200-C-E kits /// - public class HdMdxxxCEController : CrestronGenericBaseDevice, IRouting//, IComPorts + [Description("Wrapper class for all HD-MD variants")] + public class HdMdxxxCEController : CrestronGenericBridgeableBaseDevice, IRouting//, IComPorts { /// ///// DmLite Ports @@ -217,10 +221,89 @@ namespace PepperDash.Essentials.DM //public CrestronCollection ComPorts { get { return TxRxPair.ComPorts as CrestronCollection; } } //public int NumberOfComPorts { get { return 1; } } //#endregion + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new HdMdxxxCEControllerJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + RemoteEndDetectedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RemoteEndDetected]); + + trilist.SetSigTrueAction(joinMap.AutoRouteOn, AutoRouteOn); + AutoRouteOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AutoRouteOn]); + trilist.SetSigTrueAction(joinMap.AutoRouteOff, AutoRouteOff); + AutoRouteOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.AutoRouteOff]); + + trilist.SetSigTrueAction(joinMap.PriorityRoutingOn, PriorityRouteOn); + PriorityRoutingOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PriorityRoutingOn]); + trilist.SetSigTrueAction(joinMap.PriorityRoutingOff, PriorityRouteOff); + PriorityRoutingOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PriorityRoutingOff]); + + trilist.SetSigTrueAction(joinMap.InputOnScreenDisplayEnabled, OnScreenDisplayEnable); + InputOnScreenDisplayEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputOnScreenDisplayEnabled]); + trilist.SetSigTrueAction(joinMap.AutoRouteOff, OnScreenDisplayDisable); + InputOnScreenDisplayEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.InputOnScreenDisplayDisabled]); + + trilist.SetUShortSigAction(joinMap.VideoSource, (i) => ExecuteSwitch(i, null, eRoutingSignalType.Video | eRoutingSignalType.Audio)); + VideoSourceFeedback.LinkInputSig(trilist.UShortInput[joinMap.VideoSource]); + + trilist.UShortInput[joinMap.SourceCount].UShortValue = (ushort)InputPorts.Count; + + foreach (var input in InputPorts) + { + var number = Convert.ToUInt16(input.Selector); + SyncDetectedFeedbacks[number].LinkInputSig(trilist.BooleanInput[joinMap.SyncDetected + number]); + trilist.StringInput[joinMap.SourceNames + number].StringValue = input.Key; + } + } } public class HdMdxxxCEPropertiesConfig { public ControlPropertiesConfig Control { get; set; } } + + public class HdMdxxxCEControllerFactory : EssentialsDeviceFactory + { + public HdMdxxxCEControllerFactory() + { + TypeNames = new List() { "hdmd400ce", "hdmd300ce", "hdmd200ce", "hdmd200c1ge"}; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + var typeName = dc.Type.ToLower(); + var key = dc.Key; + var name = dc.Name; + + Debug.Console(1, "Factory Attempting to create new HD-MD Device"); + + var props = JsonConvert.DeserializeObject + (dc.Properties.ToString()); + + if (typeName.Equals("hdmd400ce")) + return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, + new HdMd400CE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); + else if (typeName.Equals("hdmd300ce")) + return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, + new HdMd300CE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); + else if (typeName.Equals("hdmd200ce")) + return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, + new HdMd200CE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); + else if (typeName.Equals("hdmd200c1ge")) + return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, + new HdMd200C1GE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); + else + return null; + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/DgeController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/DgeController.cs index 0fc00323..6b586ac3 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/DgeController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/DgeController.cs @@ -63,4 +63,37 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs #endregion } + + public class DgeControllerFactory : EssentialsDeviceFactory + { + public DgeControllerFactory() + { + TypeNames = new List() { "dge100", "dmdge200c" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + var typeName = dc.Type.ToLower(); + var comm = CommFactory.GetControlPropertiesConfig(dc); + var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); + + Debug.Console(1, "Factory Attempting to create new DgeControllerm Device"); + + Dge100 dgeDevice = null; + if (typeName == "dge100") + dgeDevice = new Dge100(comm.IpIdInt, Global.ControlSystem); + else if (typeName == "dmdge200c") + dgeDevice = new DmDge200C(comm.IpIdInt, Global.ControlSystem); + + if (dgeDevice == null) + { + Debug.Console(1, "Unable to create DGE device"); + return null; + } + + var dgeController = new DgeController(dc.Key + "-comPorts", dc.Name, dgeDevice, dc, props); + + return dgeController; + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc100SController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc100SController.cs index 49034fab..ef70e4f7 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc100SController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc100SController.cs @@ -4,11 +4,13 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.DM { @@ -56,6 +58,11 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge); + } + #region IIROutputPorts Members public CrestronCollection IROutputPorts { get { return Rmc.IROutputPorts; } } public int NumberOfIROutputPorts { get { return Rmc.NumberOfIROutputPorts; } } diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc150SController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc150SController.cs index e5d5a7df..faff23d4 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc150SController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc150SController.cs @@ -4,11 +4,13 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.DM { @@ -95,6 +97,11 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge); + } + #region IIROutputPorts Members public CrestronCollection IROutputPorts { get { return Rmc.IROutputPorts; } } public int NumberOfIROutputPorts { get { return Rmc.NumberOfIROutputPorts; } } diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200CController.cs index 7fbef021..44b1af6c 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200CController.cs @@ -4,11 +4,13 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.DM { @@ -95,7 +97,12 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } - #region IIROutputPorts Members + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge); + } + + #region IIROutputPorts Members public CrestronCollection IROutputPorts { get { return Rmc.IROutputPorts; } } public int NumberOfIROutputPorts { get { return Rmc.NumberOfIROutputPorts; } } #endregion diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200S2Controller.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200S2Controller.cs index ec2ead98..c30b680f 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200S2Controller.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200S2Controller.cs @@ -4,11 +4,13 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.DM { @@ -95,6 +97,11 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge); + } + #region IIROutputPorts Members public CrestronCollection IROutputPorts { get { return Rmc.IROutputPorts; } } public int NumberOfIROutputPorts { get { return Rmc.NumberOfIROutputPorts; } } diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200SController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200SController.cs index 9f2a5251..c48850c8 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200SController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200SController.cs @@ -4,11 +4,13 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.DM { @@ -95,7 +97,12 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } - #region IIROutputPorts Members + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge); + } + + #region IIROutputPorts Members public CrestronCollection IROutputPorts { get { return Rmc.IROutputPorts; } } public int NumberOfIROutputPorts { get { return Rmc.NumberOfIROutputPorts; } } #endregion diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4KScalerCController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4KScalerCController.cs index e12aa8e6..6595c6e3 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4KScalerCController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4KScalerCController.cs @@ -4,11 +4,13 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.DM { @@ -102,7 +104,12 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } - #region IIROutputPorts Members + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge); + } + + #region IIROutputPorts Members public CrestronCollection IROutputPorts { get { return Rmc.IROutputPorts; } } public int NumberOfIROutputPorts { get { return Rmc.NumberOfIROutputPorts; } } #endregion diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kScalerCDspController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kScalerCDspController.cs index 1d614854..8e52822b 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kScalerCDspController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kScalerCDspController.cs @@ -4,11 +4,13 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.DM { @@ -102,6 +104,11 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge); + } + #region IIROutputPorts Members public CrestronCollection IROutputPorts { get { return Rmc.IROutputPorts; } } public int NumberOfIROutputPorts { get { return Rmc.NumberOfIROutputPorts; } } 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 f8ad5cf6..da3e587a 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,17 @@ using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; - +using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.DM.Config; +using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.DM { - public abstract class DmRmcControllerBase : CrestronGenericBaseDevice + [Description("Wrapper class for all DM-RMC variants")] + public abstract class DmRmcControllerBase : CrestronGenericBridgeableBaseDevice { public virtual StringFeedback VideoOutputResolutionFeedback { get; protected set; } public virtual StringFeedback EdidManufacturerFeedback { get; protected set; } @@ -33,6 +36,32 @@ namespace PepperDash.Essentials.DM } AddToFeedbackList(VideoOutputResolutionFeedback, EdidManufacturerFeedback, EdidSerialNumberFeedback, EdidNameFeedback, EdidPreferredTimingFeedback); } + + protected void LinkDmRmcToApi(DmRmcControllerBase rmc, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new DmRmcControllerJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, rmc, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + rmc.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + if (rmc.VideoOutputResolutionFeedback != null) + rmc.VideoOutputResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentOutputResolution]); + if (rmc.EdidManufacturerFeedback != null) + rmc.EdidManufacturerFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidManufacturer]); + if (rmc.EdidNameFeedback != null) + rmc.EdidNameFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidName]); + if (rmc.EdidPreferredTimingFeedback != null) + rmc.EdidPreferredTimingFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidPrefferedTiming]); + if (rmc.EdidSerialNumberFeedback != null) + rmc.EdidSerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidSerialNumber]); + } } public abstract class DmHdBaseTControllerBase : CrestronGenericBaseDevice @@ -254,4 +283,25 @@ namespace PepperDash.Essentials.DM } } + public class DmRmcControllerFactory : EssentialsDeviceFactory + { + public DmRmcControllerFactory() + { + TypeNames = new List() { "hdbasetrx", "dmrmc4k100c1g", "dmrmc100c", "dmrmc100s", "dmrmc4k100c", "dmrmc150s", + "dmrmc200c", "dmrmc200s", "dmrmc200s2", "dmrmcscalerc", "dmrmcscalers", "dmrmcscalers2", "dmrmc4kscalerc", "dmrmc4kscalercdsp" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + var type = dc.Type.ToLower(); + + Debug.Console(1, "Factory Attempting to create new DM-RMC Device"); + + var props = JsonConvert.DeserializeObject + (dc.Properties.ToString()); + return PepperDash.Essentials.DM.DmRmcHelper.GetDmRmcController(dc.Key, dc.Name, type, props); + + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerCController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerCController.cs index c488864e..32044d48 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerCController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerCController.cs @@ -4,11 +4,13 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.DM { @@ -95,7 +97,12 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } - #region IIROutputPorts Members + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge); + } + + #region IIROutputPorts Members public CrestronCollection IROutputPorts { get { return Rmc.IROutputPorts; } } public int NumberOfIROutputPorts { get { return Rmc.NumberOfIROutputPorts; } } #endregion diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerS2Controller.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerS2Controller.cs index 29ba7789..60c3ca07 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerS2Controller.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerS2Controller.cs @@ -4,11 +4,13 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.DM { @@ -95,6 +97,11 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge); + } + #region IIROutputPorts Members public CrestronCollection IROutputPorts { get { return Rmc.IROutputPorts; } } public int NumberOfIROutputPorts { get { return Rmc.NumberOfIROutputPorts; } } diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerSController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerSController.cs index 0371f765..e7b5a132 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerSController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerSController.cs @@ -4,11 +4,13 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.DM { @@ -95,6 +97,11 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge); + } + #region IIROutputPorts Members public CrestronCollection IROutputPorts { get { return Rmc.IROutputPorts; } } public int NumberOfIROutputPorts { get { return Rmc.NumberOfIROutputPorts; } } diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcX100CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcX100CController.cs index 33bb6fce..a7260813 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcX100CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcX100CController.cs @@ -4,11 +4,13 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.DM { @@ -56,7 +58,12 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } - #region IIROutputPorts Members + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge); + } + + #region IIROutputPorts Members public CrestronCollection IROutputPorts { get { return Rmc.IROutputPorts; } } public int NumberOfIROutputPorts { get { return Rmc.NumberOfIROutputPorts; } } #endregion diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx200Controller.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx200Controller.cs index 42ecf5c6..923a7600 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx200Controller.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx200Controller.cs @@ -4,12 +4,14 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.DM.Config; namespace PepperDash.Essentials.DM @@ -216,6 +218,11 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmTxToApi(this, trilist, joinStart, joinMapKey, bridge); + } + /// /// Enables or disables free run /// diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx201CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx201CController.cs index 37ee38b3..e68a6fc5 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx201CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx201CController.cs @@ -4,12 +4,14 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.DM.Config; namespace PepperDash.Essentials.DM @@ -218,6 +220,11 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmTxToApi(this, trilist, joinStart, joinMapKey, bridge); + } + /// /// Enables or disables free run /// diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx401CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx401CController.cs index 18e91fbe..25c16281 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx401CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx401CController.cs @@ -5,12 +5,14 @@ using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; //using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.DM.Config; namespace PepperDash.Essentials.DM @@ -215,6 +217,11 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmTxToApi(this, trilist, joinStart, joinMapKey, bridge); + } + public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type) { Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k100Controller.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k100Controller.cs index a6f41c95..c62d0adf 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k100Controller.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k100Controller.cs @@ -1,24 +1,17 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro; //using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; -using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; - -using PepperDash.Core; using PepperDash.Essentials.Core; -using PepperDash.Essentials.DM.Config; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.DM { - using eVst = Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType; - using eAst = Crestron.SimplSharpPro.DeviceSupport.eX02AudioSourceType; + using eVst = eX02VideoSourceType; + using eAst = eX02AudioSourceType; - public class DmTx4k100Controller : BasicDmTxControllerBase, IRoutingInputsOutputs, IHasFeedback, + public class DmTx4k100Controller : DmTxControllerBase, IRoutingInputsOutputs, IIROutputPorts, IComPorts, ICec { public DmTx4K100C1G Tx { get; private set; } @@ -37,7 +30,7 @@ namespace PepperDash.Essentials.DM /// /// Helps get the "real" inputs, including when in Auto /// - public Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType ActualActiveVideoInput + public eX02VideoSourceType ActualActiveVideoInput { get { @@ -77,17 +70,11 @@ namespace PepperDash.Essentials.DM } - - public override bool CustomActivate() + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { - // Link up all of these damned events to the various RoutingPorts via a helper handler - - - // Base does register and sets up comm monitoring. - return base.CustomActivate(); + LinkDmTxToApi(this, trilist, joinStart, joinMapKey, bridge); } - #region IIROutputPorts Members public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } } public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } } @@ -101,5 +88,7 @@ namespace PepperDash.Essentials.DM #region ICec Members public Cec StreamCec { get { return Tx.StreamCec; } } #endregion + + public override StringFeedback ActiveVideoInputFeedback { get; protected set; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k202CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k202CController.cs index fce45926..1b5ecf6d 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k202CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k202CController.cs @@ -5,12 +5,14 @@ using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; //using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.DM.Config; namespace PepperDash.Essentials.DM @@ -186,6 +188,11 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmTxToApi(this, trilist, joinStart, joinMapKey, bridge); + } + public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type) { Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k302CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k302CController.cs index baaac013..5d00a32d 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k302CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k302CController.cs @@ -5,12 +5,14 @@ using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; //using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.DM.Config; namespace PepperDash.Essentials.DM @@ -223,6 +225,11 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmTxToApi(this, trilist, joinStart, joinMapKey, bridge); + } + /// /// Enables or disables free run /// diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs index 2f7dfafd..27340407 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs @@ -5,12 +5,14 @@ using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; //using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.DM.Config; namespace PepperDash.Essentials.DM @@ -199,6 +201,11 @@ namespace PepperDash.Essentials.DM return base.CustomActivate(); } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmTxToApi(this, trilist, joinStart, joinMapKey, bridge); + } + public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type) { Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs index f438b37b..81a56008 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs @@ -4,13 +4,17 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; - +using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.DM.Config; +using PepperDash.Essentials.Core.Config; + namespace PepperDash.Essentials.DM { @@ -23,7 +27,7 @@ namespace PepperDash.Essentials.DM /// /// /// - public static BasicDmTxControllerBase GetDmTxController(string key, string name, string typeName, DmTxPropertiesConfig props) + public static DmTxControllerBase GetDmTxController(string key, string name, string typeName, DmTxPropertiesConfig props) { // switch on type name... later... @@ -141,26 +145,18 @@ namespace PepperDash.Essentials.DM } } - public abstract class BasicDmTxControllerBase : CrestronGenericBaseDevice - { - public BasicDmTxControllerBase(string key, string name, GenericBase hardware) - : base(key, name, hardware) - { - - } - } - /// /// /// - public abstract class DmTxControllerBase : BasicDmTxControllerBase + [Description("Wrapper class for all DM-TX variants")] + public abstract class DmTxControllerBase : CrestronGenericBridgeableBaseDevice { public virtual void SetPortHdcpCapability(eHdcpCapabilityType hdcpMode, uint port) { } public virtual eHdcpCapabilityType HdcpSupportCapability { get; protected set; } public abstract StringFeedback ActiveVideoInputFeedback { get; protected set; } public RoutingInputPortWithVideoStatuses AnyVideoInput { get; protected set; } - public DmTxControllerBase(string key, string name, EndpointTransmitterBase hardware) + protected DmTxControllerBase(string key, string name, EndpointTransmitterBase hardware) : base(key, name, hardware) { // if wired to a chassis, skip registration step in base class @@ -170,13 +166,181 @@ namespace PepperDash.Essentials.DM } AddToFeedbackList(ActiveVideoInputFeedback); } + + protected DmTxControllerBase(string key, string name, DmHDBasedTEndPoint hardware) : base(key, name, hardware) + { + } + + protected void LinkDmTxToApi(DmTxControllerBase tx, BasicTriList trilist, uint joinStart, string joinMapKey, + EiscApiAdvanced bridge) + { + var joinMap = new DmTxControllerJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + if (tx.Hardware is DmHDBasedTEndPoint) + { + Debug.Console(1, tx, "No properties to link. Skipping device {0}", tx.Name); + return; + } + + Debug.Console(1, tx, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + tx.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + tx.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus]); + tx.AnyVideoInput.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentInputResolution]); + trilist.UShortInput[joinMap.HdcpSupportCapability].UShortValue = (ushort)tx.HdcpSupportCapability; + + bool hdcpTypeSimple; + + if (tx.Hardware is DmTx4kX02CBase) + hdcpTypeSimple = false; + else + hdcpTypeSimple = true; + + if (tx is ITxRouting) + { + var txR = tx as ITxRouting; + + trilist.SetUShortSigAction(joinMap.VideoInput, + i => txR.ExecuteNumericSwitch(i, 0, eRoutingSignalType.Video)); + trilist.SetUShortSigAction(joinMap.AudioInput, + i => txR.ExecuteNumericSwitch(i, 0, eRoutingSignalType.Audio)); + + txR.VideoSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.VideoInput]); + txR.AudioSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.AudioInput]); + + trilist.UShortInput[joinMap.HdcpSupportCapability].UShortValue = (ushort)tx.HdcpSupportCapability; + + if (txR.InputPorts[DmPortName.HdmiIn] != null) + { + var inputPort = txR.InputPorts[DmPortName.HdmiIn]; + + if (tx.Feedbacks["HdmiInHdcpCapability"] != null) + { + var intFeedback = tx.Feedbacks["HdmiInHdcpCapability"] as IntFeedback; + if (intFeedback != null) + intFeedback.LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState]); + } + + if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null) + { + var port = inputPort.Port as EndpointHdmiInput; + + SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port1HdcpState, trilist); + } + } + + if (txR.InputPorts[DmPortName.HdmiIn1] != null) + { + var inputPort = txR.InputPorts[DmPortName.HdmiIn1]; + + if (tx.Feedbacks["HdmiIn1HdcpCapability"] != null) + { + var intFeedback = tx.Feedbacks["HdmiIn1HdcpCapability"] as IntFeedback; + if (intFeedback != null) + intFeedback.LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState]); + } + + if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null) + { + var port = inputPort.Port as EndpointHdmiInput; + + SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port1HdcpState, trilist); + } + } + + if (txR.InputPorts[DmPortName.HdmiIn2] != null) + { + var inputPort = txR.InputPorts[DmPortName.HdmiIn2]; + + if (tx.Feedbacks["HdmiIn2HdcpCapability"] != null) + { + var intFeedback = tx.Feedbacks["HdmiIn2HdcpCapability"] as IntFeedback; + if (intFeedback != null) + intFeedback.LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState]); + } + + if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null) + { + var port = inputPort.Port as EndpointHdmiInput; + + SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port2HdcpState, trilist); + } + } + + } + + var txFreeRun = tx as IHasFreeRun; + if (txFreeRun != null) + { + txFreeRun.FreeRunEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.FreeRunEnabled]); + trilist.SetBoolSigAction(joinMap.FreeRunEnabled, new Action(txFreeRun.SetFreeRunEnabled)); + } + + var txVga = tx as IVgaBrightnessContrastControls; + { + if (txVga == null) return; + + txVga.VgaBrightnessFeedback.LinkInputSig(trilist.UShortInput[joinMap.VgaBrightness]); + txVga.VgaContrastFeedback.LinkInputSig(trilist.UShortInput[joinMap.VgaContrast]); + + trilist.SetUShortSigAction(joinMap.VgaBrightness, txVga.SetVgaBrightness); + trilist.SetUShortSigAction(joinMap.VgaContrast, txVga.SetVgaContrast); + } + } + + private void SetHdcpCapabilityAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist) + { + if (hdcpTypeSimple) + { + trilist.SetUShortSigAction(join, + s => + { + if (s == 0) + { + port.HdcpSupportOff(); + } + else if (s > 0) + { + port.HdcpSupportOn(); + } + }); + } + else + { + trilist.SetUShortSigAction(join, + s => + { + port.HdcpCapability = (eHdcpCapabilityType)s; + }); + } + } } - //public enum ePdtHdcpSupport - //{ - // HdcpOff = 0, - // Hdcp1 = 1, - // Hdcp2 = 2, - // Hdcp2_2= 3, - // Auto = 99 - //} -} \ No newline at end of file + + public class DmTxControllerFactory : EssentialsDeviceFactory + { + public DmTxControllerFactory() + { + TypeNames = new List() { "dmtx200c", "dmtx201c", "dmtx201s", "dmtx4k100c", "dmtx4k202c", "dmtx4kz202c", "dmtx4k302c", "dmtx4kz302c", "dmtx401c", "dmtx401s" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + var type = dc.Type.ToLower(); + + Debug.Console(1, "Factory Attempting to create new DM-TX Device"); + + var props = JsonConvert.DeserializeObject + (dc.Properties.ToString()); + return PepperDash.Essentials.DM.DmTxHelper.GetDmTxController(dc.Key, dc.Name, type, props); + } + } + +} + diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Audio/GenericAudioOut.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Audio/GenericAudioOut.cs index d89a36fc..70596904 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Audio/GenericAudioOut.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Audio/GenericAudioOut.cs @@ -6,6 +6,8 @@ using Crestron.SimplSharp; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; + using PepperDash.Essentials.Core.Routing; namespace PepperDash.Essentials.Devices.Common @@ -13,7 +15,7 @@ namespace PepperDash.Essentials.Devices.Common /// /// Represents and audio endpoint /// - public class GenericAudioOut : Device, IRoutingSinkNoSwitching + public class GenericAudioOut : EssentialsDevice, IRoutingSinkNoSwitching { public event SourceInfoChangeHandler CurrentSourceChange; @@ -98,4 +100,20 @@ namespace PepperDash.Essentials.Devices.Common } + public class GenericAudioOutWithVolumeFactory : EssentialsDeviceFactory + { + public GenericAudioOutWithVolumeFactory() + { + TypeNames = new List() { "genericaudiooutwithvolume" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new GenericAudioOutWithVolumeFactory Device"); + var zone = dc.Properties.Value("zone"); + return new GenericAudioOutWithVolume(dc.Key, dc.Name, + dc.Properties.Value("volumeDeviceKey"), zone); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/AudioCodec/AudioCodecBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/AudioCodec/AudioCodecBase.cs index 15a998a4..56998d46 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/AudioCodec/AudioCodecBase.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/AudioCodec/AudioCodecBase.cs @@ -10,7 +10,7 @@ using PepperDash.Essentials.Devices.Common.Codec; namespace PepperDash.Essentials.Devices.Common.AudioCodec { - public abstract class AudioCodecBase : Device, IHasDialer, IUsageTracking, IAudioCodecInfo + public abstract class AudioCodecBase : EssentialsDevice, IHasDialer, IUsageTracking, IAudioCodecInfo { public event EventHandler CallStatusChange; diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/AudioCodec/MockAC/MockAC.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/AudioCodec/MockAC/MockAC.cs index e0645624..84880654 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/AudioCodec/MockAC/MockAC.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/AudioCodec/MockAC/MockAC.cs @@ -6,6 +6,7 @@ using Crestron.SimplSharp; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Devices.Common.Codec; namespace PepperDash.Essentials.Devices.Common.AudioCodec @@ -111,4 +112,20 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec } } } + + public class MockACFactory : EssentialsDeviceFactory + { + public MockACFactory() + { + TypeNames = new List() { "mockac" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new MockAc Device"); + var props = Newtonsoft.Json.JsonConvert.DeserializeObject(dc.Properties.ToString()); + return new AudioCodec.MockAC(dc.Key, dc.Name, props); + } + } + } \ 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 8a7dcf03..960b8355 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 @@ -2,13 +2,17 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using Crestron.SimplSharp; +using Crestron.SimplSharp.Reflection; +using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Presets; using PepperDash.Essentials.Devices.Common.Codec; -using System.Text.RegularExpressions; -using Crestron.SimplSharp.Reflection; +using Newtonsoft.Json; namespace PepperDash.Essentials.Devices.Common.Cameras { @@ -21,8 +25,16 @@ namespace PepperDash.Essentials.Devices.Common.Cameras Focus = 8 } - public abstract class CameraBase : Device + public abstract class CameraBase : EssentialsDevice, IRoutingOutputs { + public eCameraControlMode ControlMode { get; protected set; } + + #region IRoutingOutputs Members + + public RoutingPortCollection OutputPorts { get; protected set; } + + #endregion + public bool CanPan { get @@ -58,15 +70,191 @@ namespace PepperDash.Essentials.Devices.Common.Cameras // A bitmasked value to indicate the movement capabilites of this camera protected eCameraCapabilities Capabilities { get; set; } - public CameraBase(string key, string name) : - base(key, name) { } + protected CameraBase(string key, string name) : + base(key, name) + { + OutputPorts = new RoutingPortCollection(); + + ControlMode = eCameraControlMode.Manual; + } + + protected void LinkCameraToApi(CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey, + EiscApiAdvanced bridge) + { + CameraControllerJoinMap joinMap = new CameraControllerJoinMap(joinStart); + + // Adds the join map to the bridge + bridge.AddJoinMap(cameraDevice.Key, joinMap); + + var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); + + if (customJoins != null) + { + joinMap.SetCustomJoinData(customJoins); + } + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + Debug.Console(0, "Linking to Bridge Type {0}", cameraDevice.GetType().Name.ToString()); + + var commMonitor = cameraDevice as ICommunicationMonitor; + commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig( + trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); + + var ptzCamera = cameraDevice as IHasCameraPtzControl; + + if (ptzCamera != null) + { + trilist.SetBoolSigAction(joinMap.PanLeft.JoinNumber, (b) => + { + if (b) + { + ptzCamera.PanLeft(); + } + else + { + ptzCamera.PanStop(); + } + }); + trilist.SetBoolSigAction(joinMap.PanRight.JoinNumber, (b) => + { + if (b) + { + ptzCamera.PanRight(); + } + else + { + ptzCamera.PanStop(); + } + }); + + trilist.SetBoolSigAction(joinMap.TiltUp.JoinNumber, (b) => + { + if (b) + { + ptzCamera.TiltUp(); + } + else + { + ptzCamera.TiltStop(); + } + }); + trilist.SetBoolSigAction(joinMap.TiltDown.JoinNumber, (b) => + { + if (b) + { + ptzCamera.TiltDown(); + } + else + { + ptzCamera.TiltStop(); + } + }); + + trilist.SetBoolSigAction(joinMap.ZoomIn.JoinNumber, (b) => + { + if (b) + { + ptzCamera.ZoomIn(); + } + else + { + ptzCamera.ZoomStop(); + } + }); + + trilist.SetBoolSigAction(joinMap.ZoomOut.JoinNumber, (b) => + { + if (b) + { + ptzCamera.ZoomOut(); + } + else + { + ptzCamera.ZoomStop(); + } + }); + } + + if (cameraDevice is IPower) + { + 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]); + } + + if (cameraDevice is ICommunicationMonitor) + { + var monitoredCamera = cameraDevice as ICommunicationMonitor; + monitoredCamera.CommunicationMonitor.IsOnlineFeedback.LinkInputSig( + trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); + } + + if (cameraDevice is IHasCameraPresets) + { + // Set the preset lables when they change + var presetsCamera = cameraDevice as IHasCameraPresets; + presetsCamera.PresetsListHasChanged += new EventHandler((o, a) => + { + for (int i = 1; i <= joinMap.NumberOfPresets.JoinNumber; i++) + { + int tempNum = i - 1; + + string label = ""; + + var preset = presetsCamera.Presets.FirstOrDefault(p => p.ID.Equals(i)); + + if (preset != null) + label = preset.Description; + + trilist.SetString((ushort) (joinMap.PresetLabelStart.JoinNumber + tempNum), label); + } + }); + + for (int i = 0; i < joinMap.NumberOfPresets.JoinNumber; i++) + { + int tempNum = i; + + trilist.SetSigTrueAction((ushort) (joinMap.PresetRecallStart.JoinNumber + tempNum), () => + { + presetsCamera.PresetSelect(tempNum); + }); + trilist.SetSigTrueAction((ushort) (joinMap.PresetSaveStart.JoinNumber + tempNum), () => + { + var label = trilist.GetString((ushort) (joinMap.PresetLabelStart.JoinNumber + tempNum)); + + presetsCamera.PresetStore(tempNum, label); + }); + } + } + } } + public class CameraPreset : PresetBase + { + public CameraPreset(int id, string description, bool isDefined, bool isDefinable) + : base(id, description, isDefined, isDefinable) + { + + } + } + + public class CameraPropertiesConfig { public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; } public ControlPropertiesConfig Control { get; set; } + [JsonProperty("supportsAutoMode")] + public bool SupportsAutoMode { get; set; } + + [JsonProperty("supportsOffMode")] + public bool SupportsOffMode { get; set; } + + [JsonProperty("presets")] + public List Presets { get; set; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraControl.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraControl.cs index b17bd325..36142bdd 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraControl.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraControl.cs @@ -9,9 +9,9 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.Cameras { public enum eCameraControlMode - { - Off = 0, - Manual, + { + Manual = 0, + Off, Auto } @@ -88,6 +88,8 @@ namespace PepperDash.Essentials.Devices.Common.Cameras /// public interface IHasCameraPanControl { + // void PanLeft(bool pressRelease); + // void PanRight(bool pressRelease); void PanLeft(); void PanRight(); void PanStop(); @@ -98,6 +100,8 @@ namespace PepperDash.Essentials.Devices.Common.Cameras /// public interface IHasCameraTiltControl { + // void TiltDown(bool pressRelease); + // void TildUp(bool pressRelease); void TiltDown(); void TiltUp(); void TiltStop(); @@ -108,6 +112,8 @@ namespace PepperDash.Essentials.Devices.Common.Cameras /// public interface IHasCameraZoomControl { + // void ZoomIn(bool pressRelease); + // void ZoomOut(bool pressRelease); void ZoomIn(); void ZoomOut(); void ZoomStop(); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs index 182b560c..4393229c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs @@ -3,15 +3,18 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Devices.Common.Codec; using System.Text.RegularExpressions; using Crestron.SimplSharp.Reflection; namespace PepperDash.Essentials.Devices.Common.Cameras { - public class CameraVisca : CameraBase, IHasCameraPtzControl, ICommunicationMonitor + public class CameraVisca : CameraBase, IHasCameraPtzControl, ICommunicationMonitor, IHasCameraPresets, IPower, IBridgeAdvanced { public IBasicCommunication Communication { get; private set; } public CommunicationGather PortGather { get; private set; } @@ -25,11 +28,14 @@ namespace PepperDash.Essentials.Devices.Common.Cameras public bool PowerIsOn { get; private set; } byte[] IncomingBuffer = new byte[] { }; - public BoolFeedback PowerIsOnFeedback { get; private set; } + public BoolFeedback PowerIsOnFeedback { get; private set; } public CameraVisca(string key, string name, IBasicCommunication comm, CameraPropertiesConfig props) : base(key, name) { + Presets = props.Presets; + + OutputPorts.Add(new RoutingOutputPort("videoOut", eRoutingSignalType.Video, eRoutingPortConnectionType.None, null, this, true)); // Default to all capabilties Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom | eCameraCapabilities.Focus; @@ -75,7 +81,13 @@ namespace PepperDash.Essentials.Devices.Common.Cameras CrestronConsole.AddNewConsoleCommand(s => Communication.Connect(), "con" + Key, "", ConsoleAccessLevelEnum.AccessOperator); return true; } - void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) + + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge); + } + + void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) { Debug.Console(2, this, "Socket Status Change: {0}", e.Client.ClientStatus.ToString()); @@ -132,6 +144,15 @@ namespace PepperDash.Essentials.Devices.Common.Cameras { SendBytes(new Byte[] {0x81, 0x01, 0x04, 0x00, 0x03, 0xFF}); } + + public void PowerToggle() + { + if (PowerIsOnFeedback.BoolValue) + PowerOff(); + else + PowerOn(); + } + public void PanLeft() { SendPanTiltCommand(new byte[] {0x01, 0x03}); @@ -206,5 +227,40 @@ namespace PepperDash.Essentials.Devices.Common.Cameras SendBytes(new byte[] { 0x81, 0x01, 0x04, 0x3F, 0x01, (byte)presetNumber, 0xFF }); } - } + #region IHasCameraPresets Members + + public event EventHandler PresetsListHasChanged; + + public List Presets { get; private set; } + + public void PresetSelect(int preset) + { + RecallPreset(preset); + } + + public void PresetStore(int preset, string description) + { + SavePreset(preset); + } + + #endregion + } + + public class CameraViscaFactory : EssentialsDeviceFactory + { + public CameraViscaFactory() + { + TypeNames = new List() { "cameravisca" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new CameraVisca Device"); + var comm = CommFactory.CreateCommForDevice(dc); + var props = Newtonsoft.Json.JsonConvert.DeserializeObject( + dc.Properties.ToString()); + return new Cameras.CameraVisca(dc.Key, dc.Name, comm, props); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/IHasCameraPresets.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/IHasCameraPresets.cs new file mode 100644 index 00000000..a8e8983d --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/IHasCameraPresets.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Describes a camera with preset functionality + /// + public interface IHasCameraPresets + { + event EventHandler PresetsListHasChanged; + + List Presets { get; } + + void PresetSelect(int preset); + + void PresetStore(int preset, string description); + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Crestron/Gateways/CenRfgwController.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Crestron/Gateways/CenRfgwController.cs index ee37674a..04f6eb17 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Crestron/Gateways/CenRfgwController.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Crestron/Gateways/CenRfgwController.cs @@ -8,6 +8,8 @@ using Crestron.SimplSharpPro.Gateways; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; + namespace PepperDash.Essentials.Devices.Common { @@ -112,4 +114,20 @@ namespace PepperDash.Essentials.Devices.Common { Ethernet, EthernetShared, Cresnet } + + public class CenRfgwControllerFactory : EssentialsDeviceFactory + { + public CenRfgwControllerFactory() + { + TypeNames = new List() { "cenrfgwex", "cenerfgwpoe" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new CEN-GWEXER Device"); + return CenRfgwController.GetNewExGatewayController(dc.Key, dc.Name, + dc.Properties.Value("id"), dc.Properties.Value("gatewayType")); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/BiampTesira/BiampTesiraForteDsp.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/BiampTesira/BiampTesiraForteDsp.cs index 27a29145..86850fea 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/BiampTesira/BiampTesiraForteDsp.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/BiampTesira/BiampTesiraForteDsp.cs @@ -5,6 +5,7 @@ using System.Text; using Crestron.SimplSharp; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; using System.Text.RegularExpressions; @@ -373,4 +374,22 @@ namespace PepperDash.Essentials.Devices.Common.DSP public TesiraForteControlPoint ControlPoint { get; set; } } } + + public class BiampTesiraForteDspFactory : EssentialsDeviceFactory + { + public BiampTesiraForteDspFactory() + { + TypeNames = new List() { "biamptesira" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new BiampTesira Device"); + var comm = CommFactory.CreateCommForDevice(dc); + var props = Newtonsoft.Json.JsonConvert.DeserializeObject( + dc.Properties.ToString()); + return new BiampTesiraForteDsp(dc.Key, dc.Name, comm, props); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/BiampTesira/BiampTesiraForteDspLevel.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/BiampTesira/BiampTesiraForteDspLevel.cs index d0f83115..15d424a2 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/BiampTesira/BiampTesiraForteDspLevel.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/BiampTesira/BiampTesiraForteDspLevel.cs @@ -10,6 +10,19 @@ using System.Text.RegularExpressions; namespace PepperDash.Essentials.Devices.Common.DSP { + public interface IBiampTesiraDspLevelControl : IBasicVolumeWithFeedback + { + /// + /// In BiAmp: Instance Tag, QSC: Named Control, Polycom: + /// + string ControlPointTag { get; } + int Index1 { get; } + int Index2 { get; } + bool HasMute { get; } + bool HasLevel { get; } + bool AutomaticUnmuteOnVolumeUp { get; } + } + public class TesiraForteLevelControl : TesiraForteControlPoint, IBiampTesiraDspLevelControl, IKeyed { bool _IsMuted; diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/DspBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/DspBase.cs index 318268f1..cad57761 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/DspBase.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/DspBase.cs @@ -9,7 +9,7 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.DSP { - public abstract class DspBase : Device + public abstract class DspBase : EssentialsDevice { public Dictionary LevelControlPoints { get; private set; } @@ -56,19 +56,4 @@ namespace PepperDash.Essentials.Devices.Common.DSP // ATC // Mics, unusual - public interface IBiampTesiraDspLevelControl : IBasicVolumeWithFeedback - { - /// - /// In BiAmp: Instance Tag, QSC: Named Control, Polycom: - /// - string ControlPointTag { get; } - int Index1 { get; } - int Index2 { get; } - bool HasMute { get; } - bool HasLevel { get; } - bool AutomaticUnmuteOnVolumeUp { get; } - } - - - } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/DiscPlayer/IRDiscPlayerBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/DiscPlayer/IRDiscPlayerBase.cs index 0f4a65ac..581ea3b5 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/DiscPlayer/IRDiscPlayerBase.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/DiscPlayer/IRDiscPlayerBase.cs @@ -5,13 +5,18 @@ using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + + using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Routing; +using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.Devices.Common { - public class IRBlurayBase : Device, IDiscPlayerControls, IUiDisplayInfo, IRoutingOutputs, IUsageTracking + public class IRBlurayBase : EssentialsDevice, IDiscPlayerControls, IUiDisplayInfo, IRoutingOutputs, IUsageTracking { public IrOutputPortController IrPort { get; private set; } @@ -311,4 +316,30 @@ namespace PepperDash.Essentials.Devices.Common #endregion } + + public class IRBlurayBaseFactory : EssentialsDeviceFactory + { + public IRBlurayBaseFactory() + { + TypeNames = new List() { "discplayer", "bluray" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new IRBlurayPlayer Device"); + + if (dc.Properties["control"]["method"].Value() == "ir") + { + var irCont = IRPortHelper.GetIrOutputPortController(dc); + return new IRBlurayBase(dc.Key, dc.Name, irCont); + } + else if (dc.Properties["control"]["method"].Value() == "com") + { + Debug.Console(0, "[{0}] COM Device type not implemented YET!", dc.Key); + } + + return null; + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/AvocorVTFDisplay.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/AvocorVTFDisplay.cs index 22226e74..20d9fbec 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/AvocorVTFDisplay.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/AvocorVTFDisplay.cs @@ -5,9 +5,13 @@ 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 { @@ -15,7 +19,7 @@ namespace PepperDash.Essentials.Devices.Displays /// /// public class AvocorDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, ICommunicationMonitor, IInputDisplayPort1, - IInputHdmi1, IInputHdmi2, IInputHdmi3, IInputHdmi4, IInputVga1 + IInputHdmi1, IInputHdmi2, IInputHdmi3, IInputHdmi4, IInputVga1, IBridgeAdvanced { public IBasicCommunication Communication { get; private set; } public CommunicationGather PortGather { get; private set; } @@ -199,7 +203,12 @@ namespace PepperDash.Essentials.Devices.Displays return true; } - void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) + 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(); @@ -717,4 +726,24 @@ namespace PepperDash.Essentials.Devices.Displays #endregion } + + public class AvocorDisplayFactory : EssentialsDeviceFactory + { + public AvocorDisplayFactory() + { + TypeNames = new List() { "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; + + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/DeviceFactory.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/DeviceFactory.cs deleted file mode 100644 index 8b4941d7..00000000 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/DeviceFactory.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using Crestron.SimplSharp; -using Crestron.SimplSharp.CrestronIO; -using Crestron.SimplSharpPro; - -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; - -namespace PepperDash.Essentials.Devices.Displays -{ - public class DisplayDeviceFactory - { - public static IKeyed GetDevice(DeviceConfig dc) - { - var key = dc.Key; - var name = dc.Name; - var type = dc.Type; - var properties = dc.Properties; - - var typeName = dc.Type.ToLower(); - - try - { - if (typeName == "necmpsx") - { - var comm = CommFactory.CreateCommForDevice(dc); - if (comm != null) - return new NecPSXMDisplay(dc.Key, dc.Name, comm); - } - if (typeName == "panasonicthef") - { - var comm = CommFactory.CreateCommForDevice(dc); - if (comm != null) - return new PanasonicThefDisplay(dc.Key, dc.Name, comm); - } - else if(typeName == "samsungmdc") - { - var comm = CommFactory.CreateCommForDevice(dc); - if (comm != null) - return new SamsungMDC(dc.Key, dc.Name, comm, dc.Properties["id"].Value()); - } - if (typeName == "avocorvtf") - { - var comm = CommFactory.CreateCommForDevice(dc); - if (comm != null) - return new AvocorDisplay(dc.Key, dc.Name, comm, null); - } - - } - catch (Exception e) - { - Debug.Console(0, "Displays factory: Exception creating device type {0}, key {1}: \nCONFIG JSON: {2} \nERROR: {3}\n\n", - dc.Type, dc.Key, JsonConvert.SerializeObject(dc), e); - return null; - } - - return null; - } - } -} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/NECPSXMDisplay.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/NECPSXMDisplay.cs index 61349632..176f28ac 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/NECPSXMDisplay.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/NECPSXMDisplay.cs @@ -4,16 +4,20 @@ 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 { /// /// /// - public class NecPSXMDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, ICommunicationMonitor + public class NecPSXMDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, ICommunicationMonitor, IBridgeAdvanced { public IBasicCommunication Communication { get; private set; } public CommunicationGather PortGather { get; private set; } @@ -150,7 +154,12 @@ namespace PepperDash.Essentials.Devices.Displays return true; } - public override FeedbackCollection Feedbacks + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge); + } + + public override FeedbackCollection Feedbacks { get { @@ -353,4 +362,23 @@ namespace PepperDash.Essentials.Devices.Displays #endregion } + + public class NecPSXMDisplayFactory : EssentialsDeviceFactory + { + public NecPSXMDisplayFactory() + { + TypeNames = new List() { "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; + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/NecPaSeriesProjector.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/NecPaSeriesProjector.cs index 34263818..86c8ddaa 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/NecPaSeriesProjector.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/NecPaSeriesProjector.cs @@ -4,13 +4,14 @@ 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 : ComTcpDisplayBase + public class NecPaSeriesProjector : ComTcpDisplayBase, IBridgeAdvanced { public readonly IntFeedback Lamp1RemainingPercent; int _Lamp1RemainingPercent; @@ -218,5 +219,9 @@ namespace PepperDash.Essentials.Devices.Displays } + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge); + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/PanasonicThDisplay.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/PanasonicThDisplay.cs index 5781f134..b8d33bd1 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/PanasonicThDisplay.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/PanasonicThDisplay.cs @@ -4,16 +4,20 @@ 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 { /// /// /// - public class PanasonicThefDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, ICommunicationMonitor + public class PanasonicThDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, ICommunicationMonitor, IBridgeAdvanced { public IBasicCommunication Communication { get; private set; } public CommunicationGather PortGather { get; private set; } @@ -70,7 +74,7 @@ namespace PepperDash.Essentials.Devices.Displays /// /// Constructor for IBasicCommunication /// - public PanasonicThefDisplay(string key, string name, IBasicCommunication comm) + public PanasonicThDisplay(string key, string name, IBasicCommunication comm) : base(key, name) { Communication = comm; @@ -79,7 +83,7 @@ namespace PepperDash.Essentials.Devices.Displays /// /// Constructor for TCP /// - public PanasonicThefDisplay(string key, string name, string hostname, int port) + public PanasonicThDisplay(string key, string name, string hostname, int port) : base(key, name) { Communication = new GenericTcpIpClient(key + "-tcp", hostname, port, 5000); @@ -90,7 +94,7 @@ namespace PepperDash.Essentials.Devices.Displays /// /// Constructor for COM /// - public PanasonicThefDisplay(string key, string name, ComPort port, ComPort.ComPortSpec spec) + public PanasonicThDisplay(string key, string name, ComPort port, ComPort.ComPortSpec spec) : base(key, name) { Communication = new ComPortController(key + "-com", port, spec); @@ -129,7 +133,7 @@ namespace PepperDash.Essentials.Devices.Displays //}; } - ~PanasonicThefDisplay() + ~PanasonicThDisplay() { PortGather = null; } @@ -142,7 +146,12 @@ namespace PepperDash.Essentials.Devices.Displays return true; } - public override FeedbackCollection Feedbacks + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge); + } + + public override FeedbackCollection Feedbacks { get { @@ -335,4 +344,23 @@ namespace PepperDash.Essentials.Devices.Displays #endregion } + + public class PanasonicThDisplayFactory : EssentialsDeviceFactory + { + public PanasonicThDisplayFactory() + { + TypeNames = new List() { "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; + } + } + } \ No newline at end of file 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 975487e0..b2de0f8f 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 @@ -5,9 +5,15 @@ 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 { @@ -15,7 +21,7 @@ namespace PepperDash.Essentials.Devices.Displays /// /// public class SamsungMDC : TwoWayDisplayBase, IBasicVolumeWithFeedback, ICommunicationMonitor, IInputDisplayPort1, IInputDisplayPort2, - IInputHdmi1, IInputHdmi2, IInputHdmi3, IInputHdmi4 + IInputHdmi1, IInputHdmi2, IInputHdmi3, IInputHdmi4, IBridgeAdvanced { public IBasicCommunication Communication { get; private set; } @@ -146,7 +152,12 @@ namespace PepperDash.Essentials.Devices.Displays return true; } - public override FeedbackCollection Feedbacks + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge); + } + + public override FeedbackCollection Feedbacks { get { @@ -629,4 +640,23 @@ namespace PepperDash.Essentials.Devices.Displays #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/Environment/Crestron Lighting/Din8sw8.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Crestron Lighting/Din8sw8.cs index e371d2d1..b262ef84 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Crestron Lighting/Din8sw8.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Crestron Lighting/Din8sw8.cs @@ -9,11 +9,12 @@ using Crestron.SimplSharpPro.Lighting; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.CrestronIO; namespace PepperDash.Essentials.Devices.Common.Environment.Lighting { - public class Din8sw8Controller : Device, ISwitchedOutputCollection + public class Din8sw8Controller : EssentialsDevice, ISwitchedOutputCollection { // Need to figure out some sort of interface to make these switched outputs behave like processor relays so they can be used interchangably @@ -85,4 +86,21 @@ namespace PepperDash.Essentials.Devices.Common.Environment.Lighting } } + public class Din8sw8ControllerFactory : EssentialsDeviceFactory + { + public Din8sw8ControllerFactory() + { + TypeNames = new List() { "din8sw8" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Din8sw8Controller Device"); + var comm = CommFactory.GetControlPropertiesConfig(dc); + + return new Din8sw8Controller(dc.Key, comm.CresnetIdInt); + + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Lutron/LutronQuantum.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Lutron/LutronQuantum.cs index adcceb4f..84cf46c2 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Lutron/LutronQuantum.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Lutron/LutronQuantum.cs @@ -3,9 +3,13 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; +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.Lighting; +using LightingBase = PepperDash.Essentials.Core.Lighting.LightingBase; namespace PepperDash.Essentials.Devices.Common.Environment.Lutron { @@ -77,6 +81,14 @@ namespace PepperDash.Essentials.Devices.Common.Environment.Lutron return true; } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = LinkLightingToApi(this, trilist, joinStart, joinMapKey, bridge); + + CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + trilist.SetStringSigAction(joinMap.IntegrationIdSet, s => IntegrationId = s); + } + void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) { Debug.Console(2, this, "Socket Status Change: {0}", e.Client.ClientStatus.ToString()); @@ -253,4 +265,23 @@ namespace PepperDash.Essentials.Devices.Common.Environment.Lutron // public string Username { get; set; } // public string Password { get; set; } } + + public class LutronQuantumAreaFactory : EssentialsDeviceFactory + { + public LutronQuantumAreaFactory() + { + TypeNames = new List() { "lutronqs" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new LutronQuantumArea Device"); + var comm = CommFactory.CreateCommForDevice(dc); + + var props = Newtonsoft.Json.JsonConvert.DeserializeObject(dc.Properties.ToString()); + + return new LutronQuantumArea(dc.Key, dc.Name, comm, props); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Somfy/RelayControlledShade.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Somfy/RelayControlledShade.cs index 22e06d03..a78e5045 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Somfy/RelayControlledShade.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Somfy/RelayControlledShade.cs @@ -6,6 +6,7 @@ using Crestron.SimplSharp; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.CrestronIO; using PepperDash.Essentials.Core.Shades; @@ -110,4 +111,21 @@ namespace PepperDash.Essentials.Devices.Common.Environment.Somfy public IOPortConfig Close { get; set; } } } + + public class RelayControlledShadeFactory : EssentialsDeviceFactory + { + public RelayControlledShadeFactory() + { + TypeNames = new List() { "relaycontrolledshade" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Generic Comm Device"); + var props = Newtonsoft.Json.JsonConvert.DeserializeObject(dc.Properties.ToString()); + + return new Environment.Somfy.RelayControlledShade(dc.Key, dc.Name, props); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index 6b57d1ca..147ace5b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -102,6 +102,7 @@ + @@ -114,6 +115,7 @@ + @@ -130,7 +132,6 @@ - diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Factory/DeviceFactory.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Factory/DeviceFactory.cs index 48179ff1..c860d0cb 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Factory/DeviceFactory.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Factory/DeviceFactory.cs @@ -1,9 +1,11 @@ using System; +using System.Linq; using System.Collections.Generic; using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.GeneralIO; +using Crestron.SimplSharp.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -18,370 +20,33 @@ using PepperDash.Essentials.Devices.Common.VideoCodec; using PepperDash.Essentials.Devices.Common.Occupancy; using PepperDash.Essentials.Devices.Common.Environment; - - namespace PepperDash.Essentials.Devices.Common { - public class DeviceFactory - { - public static IKeyed GetDevice(DeviceConfig dc) - { - var key = dc.Key; - var name = dc.Name; - var type = dc.Type; - var properties = dc.Properties; - var propAnon = new {}; - JsonConvert.DeserializeAnonymousType(dc.Properties.ToString(), propAnon); + public class DeviceFactory + { - var typeName = dc.Type.ToLower(); - var groupName = dc.Group.ToLower(); + public DeviceFactory() + { + var assy = Assembly.GetExecutingAssembly(); + PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy); + + var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract); - if (typeName == "appletv") - { - var irCont = IRPortHelper.GetIrOutputPortController(dc); - return new AppleTV(key, name, irCont); - } - else if (typeName == "analogwaylivecore") - { - var comm = CommFactory.CreateCommForDevice(dc); - var props = JsonConvert.DeserializeObject( - properties.ToString()); - return new AnalogWayLiveCore(key, name, comm, props); - } - else if (typeName == "basicirdisplay") - { - var ir = IRPortHelper.GetIrPort(properties); - if (ir != null) + if (types != null) + { + foreach (var type in types) { - var display = new BasicIrDisplay(key, name, ir.Port, ir.FileName); - display.IrPulseTime = 200; // Set default pulse time for IR commands. - return display; - } - } - - else if (typeName == "biamptesira") - { - var comm = CommFactory.CreateCommForDevice(dc); - var props = JsonConvert.DeserializeObject( - properties.ToString()); - return new BiampTesiraForteDsp(key, name, comm, props); - } - - - else if (typeName == "cameravisca") - { - var comm = CommFactory.CreateCommForDevice(dc); - var props = JsonConvert.DeserializeObject( - properties.ToString()); - return new Cameras.CameraVisca(key, name, comm, props); - } - - else if (typeName == "cenrfgwex") - { - return CenRfgwController.GetNewExGatewayController(key, name, - properties.Value("id"), properties.Value("gatewayType")); - } - - else if (typeName == "cenerfgwpoe") - { - return CenRfgwController.GetNewErGatewayController(key, name, - properties.Value("id"), properties.Value("gatewayType")); - } - - else if (groupName == "discplayer") // (typeName == "irbluray") - { - if (properties["control"]["method"].Value() == "ir") - { - var irCont = IRPortHelper.GetIrOutputPortController(dc); - return new IRBlurayBase(key, name, irCont); - } - else if (properties["control"]["method"].Value() == "com") - { - Debug.Console(0, "[{0}] COM Device type not implemented YET!", key); - } - } - else if (typeName == "digitallogger") - { - // var comm = CommFactory.CreateCommForDevice(dc); - var props = JsonConvert.DeserializeObject( - properties.ToString()); - return new DigitalLogger(key, name, props); - } - else if (typeName == "genericaudiooutwithvolume") - { - var zone = dc.Properties.Value("zone"); - return new GenericAudioOutWithVolume(key, name, - dc.Properties.Value("volumeDeviceKey"), zone); - } - - else if (groupName == "genericsource") - { - return new GenericSource(key, name); - } - - else if (typeName == "inroompc") - { - return new Core.Devices.InRoomPc(key, name); - } - - else if (typeName == "laptop") - { - return new Core.Devices.Laptop(key, name); - } - - else if (typeName == "mockvc") - { - return new VideoCodec.MockVC(dc); - } - - else if (typeName == "mockac") - { - var props = JsonConvert.DeserializeObject(properties.ToString()); - return new AudioCodec.MockAC(key, name, props); - } - - else if (typeName.StartsWith("ciscospark")) - { - var comm = CommFactory.CreateCommForDevice(dc); - return new VideoCodec.Cisco.CiscoSparkCodec(dc, comm); - } - - else if (typeName == "zoomroom") - { - var comm = CommFactory.CreateCommForDevice(dc); - return new VideoCodec.ZoomRoom.ZoomRoom(dc, comm); - } - - else if (typeName == "digitalinput") - { - var props = JsonConvert.DeserializeObject(properties.ToString()); - - IDigitalInputPorts portDevice; - - if (props.PortDeviceKey == "processor") - portDevice = Global.ControlSystem as IDigitalInputPorts; - else - portDevice = DeviceManager.GetDeviceForKey(props.PortDeviceKey) as IDigitalInputPorts; - - if (portDevice == null) - Debug.Console(0, "ERROR: Unable to add digital input device with key '{0}'. Port Device does not support digital inputs", key); - else - { - var cs = (portDevice as CrestronControlSystem); - if (cs == null) + try { - Debug.Console(0, "ERROR: Port device for [{0}] is not control system", props.PortDeviceKey); - return null; + var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); + factory.LoadTypeFactories(); } - - if (cs.SupportsVersiport) + catch (Exception e) { - Debug.Console(1, "Attempting to add Digital Input device to Versiport port '{0}'", props.PortNumber); - - if (props.PortNumber > cs.NumberOfVersiPorts) - { - Debug.Console(0, "WARNING: Cannot add Vesiport {0} on {1}. Out of range", - props.PortNumber, props.PortDeviceKey); - return null; - } - - Versiport vp = cs.VersiPorts[props.PortNumber]; - - if (!vp.Registered) - { - var regSuccess = vp.Register(); - if (regSuccess == eDeviceRegistrationUnRegistrationResponse.Success) - { - Debug.Console(1, "Successfully Created Digital Input Device on Versiport"); - return new GenericVersiportDigitalInputDevice(key, vp, props); - } - else - { - Debug.Console(0, "WARNING: Attempt to register versiport {0} on device with key '{1}' failed: {2}", - props.PortNumber, props.PortDeviceKey, regSuccess); - return null; - } - } - } - else if (cs.SupportsDigitalInput) - { - Debug.Console(1, "Attempting to add Digital Input device to Digital Input port '{0}'", props.PortNumber); - - if (props.PortNumber > cs.NumberOfDigitalInputPorts) - { - Debug.Console(0, "WARNING: Cannot register DIO port {0} on {1}. Out of range", - props.PortNumber, props.PortDeviceKey); - return null; - } - - DigitalInput digitalInput = cs.DigitalInputPorts[props.PortNumber]; - - if (!digitalInput.Registered) - { - if (digitalInput.Register() == eDeviceRegistrationUnRegistrationResponse.Success) - { - Debug.Console(1, "Successfully Created Digital Input Device on Digital Input"); - return new GenericDigitalInputDevice(key, digitalInput); - } - else - Debug.Console(0, "WARNING: Attempt to register digital input {0} on device with key '{1}' failed.", - props.PortNumber, props.PortDeviceKey); - } + Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name); } } } - - else if (typeName == "relayoutput") - { - var props = JsonConvert.DeserializeObject(properties.ToString()); - - IRelayPorts portDevice; - - if (props.PortDeviceKey == "processor") - portDevice = Global.ControlSystem as IRelayPorts; - else - portDevice = DeviceManager.GetDeviceForKey(props.PortDeviceKey) as IRelayPorts; - - if (portDevice == null) - Debug.Console(0, "Unable to add relay device with key '{0}'. Port Device does not support relays", key); - else - { - var cs = (portDevice as CrestronControlSystem); - - if (cs != null) - { - // The relay is on a control system processor - if (!cs.SupportsRelay || props.PortNumber > cs.NumberOfRelayPorts) - { - Debug.Console(0, "Port Device: {0} does not support relays or does not have enough relays"); - return null; - } - } - else - { - // The relay is on another device type - - if (props.PortNumber > portDevice.NumberOfRelayPorts) - { - Debug.Console(0, "Port Device: {0} does not have enough relays"); - return null; - } - } - - Relay relay = portDevice.RelayPorts[props.PortNumber]; - - if (!relay.Registered) - { - if (relay.Register() == eDeviceRegistrationUnRegistrationResponse.Success) - return new GenericRelayDevice(key, relay); - else - Debug.Console(0, "Attempt to register relay {0} on device with key '{1}' failed.", props.PortNumber, props.PortDeviceKey); - } - else - { - return new GenericRelayDevice(key, relay); - } - - // Future: Check if portDevice is 3-series card or other non control system that supports versiports - } - } - - else if (typeName == "microphoneprivacycontroller") - { - var props = JsonConvert.DeserializeObject(properties.ToString()); - - return new Core.Privacy.MicrophonePrivacyController(key, props); - } - else if (typeName == "roku") - { - var irCont = IRPortHelper.GetIrOutputPortController(dc); - return new Roku2(key, name, irCont); - } - - else if (groupName == "settopbox") //(typeName == "irstbbase") - { - var irCont = IRPortHelper.GetIrOutputPortController(dc); - var config = dc.Properties.ToObject(); - var stb = new IRSetTopBoxBase(key, name, irCont, config); - - //stb.HasDvr = properties.Value("hasDvr"); - var listName = properties.Value("presetsList"); - if (listName != null) - stb.LoadPresets(listName); - return stb; - } - else if (typeName == "tvonecorio") - { - var comm = CommFactory.CreateCommForDevice(dc); - var props = JsonConvert.DeserializeObject( - properties.ToString()); - return new TVOneCorio(key, name, comm, props); - } - - - else if (typeName == "glsoirccn") - { - var comm = CommFactory.GetControlPropertiesConfig(dc); - - GlsOccupancySensorBase occSensor = null; - - occSensor = new GlsOirCCn(comm.CresnetIdInt, Global.ControlSystem); - - if (occSensor != null) - return new GlsOccupancySensorBaseController(key, name, occSensor); - else - Debug.Console(0, "ERROR: Unable to create Occupancy Sensor Device. Key: '{0}'", key); - } - - else if (typeName == "glsodtccn") - { - var comm = CommFactory.GetControlPropertiesConfig(dc); - - var occSensor = new GlsOdtCCn(comm.CresnetIdInt, Global.ControlSystem); - - if (occSensor != null) - return new GlsOdtOccupancySensorController(key, name, occSensor); - else - Debug.Console(0, "ERROR: Unable to create Occupancy Sensor Device. Key: '{0}'", key); - } - - else if (groupName == "lighting") - { - if (typeName == "lutronqs") - { - var comm = CommFactory.CreateCommForDevice(dc); - - var props = JsonConvert.DeserializeObject(properties.ToString()); - - return new Environment.Lutron.LutronQuantumArea(key, name, comm, props); - } - else if (typeName == "din8sw8") - { - var comm = CommFactory.GetControlPropertiesConfig(dc); - - return new Environment.Lighting.Din8sw8Controller(key, comm.CresnetIdInt); - } - - } - - else if (groupName == "environment") - { - if (typeName == "shadecontroller") - { - var props = JsonConvert.DeserializeObject(properties.ToString()); - - return new Core.Shades.ShadeController(key, name, props); - } - else if (typeName == "relaycontrolledshade") - { - var props = JsonConvert.DeserializeObject(properties.ToString()); - - return new Environment.Somfy.RelayControlledShade(key, name, props); - } - - } - - return null; - } - } + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Generic/GenericSource.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Generic/GenericSource.cs index 4627fd7b..697639e5 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Generic/GenericSource.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Generic/GenericSource.cs @@ -8,11 +8,12 @@ using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Routing; namespace PepperDash.Essentials.Devices.Common { - public class GenericSource : Device, IUiDisplayInfo, IRoutingOutputs, IUsageTracking + public class GenericSource : EssentialsDevice, IUiDisplayInfo, IRoutingOutputs, IUsageTracking { public uint DisplayUiType { get { return DisplayUiConstants.TypeNoControls; } } @@ -39,4 +40,19 @@ namespace PepperDash.Essentials.Devices.Common #endregion } + + public class GenericSourceFactory : EssentialsDeviceFactory + { + public GenericSourceFactory() + { + TypeNames = new List() { "genericsource" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Generic Source Device"); + return new GenericSource(dc.Key, dc.Name); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/AnalogWay/AnalongWayLiveCore.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/AnalogWay/AnalongWayLiveCore.cs index c2178bdb..97d8a8dd 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/AnalogWay/AnalongWayLiveCore.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/AnalogWay/AnalongWayLiveCore.cs @@ -5,13 +5,14 @@ using System.Text; using Crestron.SimplSharp; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; using System.Text.RegularExpressions; namespace PepperDash.Essentials.Devices.Common { - public class AnalogWayLiveCore : Device + public class AnalogWayLiveCore : EssentialsDevice { public IBasicCommunication Communication { get; private set; } public CommunicationGather PortGather { get; private set; } @@ -238,4 +239,22 @@ namespace PepperDash.Essentials.Devices.Common // public QscDspControlPoint ControlPoint { get; set; } } } + + public class AnalogWayLiveCoreFactory : EssentialsDeviceFactory + { + public AnalogWayLiveCoreFactory() + { + TypeNames = new List() { "analogwaylivecore" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new AnalogWayLiveCore Device"); + var comm = CommFactory.CreateCommForDevice(dc); + var props = Newtonsoft.Json.JsonConvert.DeserializeObject( + dc.Properties.ToString()); + return new AnalogWayLiveCore(dc.Key, dc.Name, comm, props); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/TVOneCorio.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/TVOneCorio.cs index a3dd9745..b5a1004f 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/TVOneCorio.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/TVOneCorio.cs @@ -5,13 +5,14 @@ using System.Text; using Crestron.SimplSharp; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; using System.Text.RegularExpressions; namespace PepperDash.Essentials.Devices.Common { - public class TVOneCorio : Device + public class TVOneCorio : EssentialsDevice { public IBasicCommunication Communication { get; private set; } public CommunicationGather PortGather { get; private set; } @@ -238,4 +239,22 @@ namespace PepperDash.Essentials.Devices.Common // public QscDspControlPoint ControlPoint { get; set; } } } + + public class TVOneCorioFactory : EssentialsDeviceFactory + { + public TVOneCorioFactory() + { + TypeNames = new List() { "tvonecorio" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new TVOneCorio Device"); + var comm = CommFactory.CreateCommForDevice(dc); + var props = Newtonsoft.Json.JsonConvert.DeserializeObject( + dc.Properties.ToString()); + return new TVOneCorio(dc.Key, dc.Name, comm, props); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOccupancySensorBaseController.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOccupancySensorBaseController.cs index 380a090a..18bdb1be 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOccupancySensorBaseController.cs @@ -3,14 +3,17 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.GeneralIO; - +using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Devices.Common.Occupancy { - public class GlsOccupancySensorBaseController : CrestronGenericBaseDevice, IOccupancyStatusProvider + public class GlsOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider { public GlsOccupancySensorBase OccSensor { get; private set; } @@ -251,5 +254,150 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy { OccSensor.ExternalPhotoSensorMinimumChange.UShortValue = value; } + + + + protected void LinkOccSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist, + uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new GlsOccupancySensorBaseJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + #region Single and Dual Sensor Stuff + occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + trilist.StringInput[joinMap.Name].StringValue = occController.Name; + + trilist.OnlineStatusChange += (d, args) => + { + if (args.DeviceOnLine) + { + trilist.StringInput[joinMap.Name].StringValue = occController.Name; + } + }; + + // Occupied status + trilist.SetSigTrueAction(joinMap.ForceOccupied, occController.ForceOccupied); + trilist.SetSigTrueAction(joinMap.ForceVacant, occController.ForceVacant); + occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback]); + occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback]); + occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback]); + trilist.SetBoolSigAction(joinMap.EnableRawStates, occController.EnableRawStates); + + // Timouts + trilist.SetUShortSigAction(joinMap.Timeout, occController.SetRemoteTimeout); + occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout]); + occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback]); + + // LED Flash + trilist.SetSigTrueAction(joinMap.EnableLedFlash, () => occController.SetLedFlashEnable(true)); + trilist.SetSigTrueAction(joinMap.DisableLedFlash, () => occController.SetLedFlashEnable(false)); + occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash]); + + // Short Timeout + trilist.SetSigTrueAction(joinMap.EnableShortTimeout, () => occController.SetShortTimeoutState(true)); + trilist.SetSigTrueAction(joinMap.DisableShortTimeout, () => occController.SetShortTimeoutState(false)); + occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout]); + + // PIR Sensor + trilist.SetSigTrueAction(joinMap.EnablePir, () => occController.SetPirEnable(true)); + trilist.SetSigTrueAction(joinMap.DisablePir, () => occController.SetPirEnable(false)); + occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir]); + + // PIR Sensitivity in Occupied State + trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState, occController.IncrementPirSensitivityInOccupiedState); + trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState, occController.DecrementPirSensitivityInOccupiedState); + occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInOccupiedState]); + + // PIR Sensitivity in Vacant State + trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState, occController.IncrementPirSensitivityInVacantState); + trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState, occController.DecrementPirSensitivityInVacantState); + occController.PirSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInVacantState]); + #endregion + + #region Dual Technology Sensor Stuff + var odtOccController = occController as GlsOdtOccupancySensorController; + + if (odtOccController == null) return; + // OR When Vacated + trilist.SetBoolSigAction(joinMap.OrWhenVacated, odtOccController.SetOrWhenVacatedState); + odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated]); + + // AND When Vacated + trilist.SetBoolSigAction(joinMap.AndWhenVacated, odtOccController.SetAndWhenVacatedState); + odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated]); + + // Ultrasonic A Sensor + trilist.SetSigTrueAction(joinMap.EnableUsA, () => odtOccController.SetUsAEnable(true)); + trilist.SetSigTrueAction(joinMap.DisableUsA, () => odtOccController.SetUsAEnable(false)); + odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA]); + + // Ultrasonic B Sensor + trilist.SetSigTrueAction(joinMap.EnableUsB, () => odtOccController.SetUsBEnable(true)); + trilist.SetSigTrueAction(joinMap.DisableUsB, () => odtOccController.SetUsBEnable(false)); + odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB]); + + // US Sensitivity in Occupied State + trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState, odtOccController.IncrementUsSensitivityInOccupiedState); + trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState, odtOccController.DecrementUsSensitivityInOccupiedState); + odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInOccupiedState]); + + // US Sensitivity in Vacant State + trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState, odtOccController.IncrementUsSensitivityInVacantState); + trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState, odtOccController.DecrementUsSensitivityInVacantState); + odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInVacantState]); + + //Sensor Raw States + odtOccController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback]); + odtOccController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback]); + + #endregion + } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge); + } } + + public class GlsOccupancySensorBaseControllerFactory : EssentialsDeviceFactory + { + public GlsOccupancySensorBaseControllerFactory() + { + TypeNames = new List() { "glsoirccn" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); + + var typeName = dc.Type.ToLower(); + var key = dc.Key; + var name = dc.Name; + var comm = CommFactory.GetControlPropertiesConfig(dc); + + GlsOccupancySensorBase occSensor = null; + + occSensor = new GlsOirCCn(comm.CresnetIdInt, Global.ControlSystem); + + if (occSensor != null) + { + return new GlsOccupancySensorBaseController(key, name, occSensor); + } + else + { + Debug.Console(0, "ERROR: Unable to create Occupancy Sensor Device. Key: '{0}'", key); + return null; + } + + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOdtOccupancySensorController.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOdtOccupancySensorController.cs index 16e449bf..f7d9943a 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOdtOccupancySensorController.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOdtOccupancySensorController.cs @@ -3,10 +3,13 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.GeneralIO; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Devices.Common.Occupancy { @@ -117,16 +120,8 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy /// public void SetUsAEnable(bool state) { - if (state) - { - OccSensor.EnableUsA.BoolValue = state; - OccSensor.DisableUsA.BoolValue = !state; - } - else - { - OccSensor.EnableUsA.BoolValue = state; - OccSensor.DisableUsA.BoolValue = !state; - } + OccSensor.EnableUsA.BoolValue = state; + OccSensor.DisableUsA.BoolValue = !state; } @@ -136,16 +131,8 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy /// public void SetUsBEnable(bool state) { - if (state) - { - OccSensor.EnableUsB.BoolValue = state; - OccSensor.DisableUsB.BoolValue = !state; - } - else - { - OccSensor.EnableUsB.BoolValue = state; - OccSensor.DisableUsB.BoolValue = !state; - } + OccSensor.EnableUsB.BoolValue = state; + OccSensor.DisableUsB.BoolValue = !state; } public void IncrementUsSensitivityInOccupiedState(bool pressRelease) @@ -167,5 +154,43 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy { OccSensor.DecrementUsSensitivityInVacantState.BoolValue = pressRelease; } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge); + } } + + public class GlsOdtOccupancySensorControllerFactory : EssentialsDeviceFactory + { + public GlsOdtOccupancySensorControllerFactory() + { + TypeNames = new List() { "glsodtccn" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); + + var typeName = dc.Type.ToLower(); + var key = dc.Key; + var name = dc.Name; + var comm = CommFactory.GetControlPropertiesConfig(dc); + + var occSensor = new GlsOdtCCn(comm.CresnetIdInt, Global.ControlSystem); + + if (occSensor != null) + { + return new GlsOdtOccupancySensorController(key, name, occSensor); + } + else + { + Debug.Console(0, "ERROR: Unable to create Occupancy Sensor Device. Key: '{0}'", key); + return null; + } + + + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Power Controllers/Digitallogger.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Power Controllers/Digitallogger.cs index 358c63cb..11a96537 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Power Controllers/Digitallogger.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Power Controllers/Digitallogger.cs @@ -3,18 +3,21 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; using PepperDash.Essentials.Core; using System.Text.RegularExpressions; using Crestron.SimplSharp.Net.Http; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.Devices.Common { - public class DigitalLogger : Device + public class DigitalLogger : EssentialsBridgeableDevice { public IBasicCommunication Communication { get; private set; } public CommunicationGather PortGather { get; private set; } @@ -134,6 +137,31 @@ namespace PepperDash.Essentials.Devices.Common return true; } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new DigitalLoggerJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + for (uint i = 1; i <= CircuitCount; i++) + { + var circuit = i; + CircuitNameFeedbacks[circuit - 1].LinkInputSig(trilist.StringInput[joinMap.CircuitNames + circuit]); + CircuitIsCritical[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitIsCritical + circuit]); + CircuitState[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitState + circuit]); + trilist.SetSigTrueAction(joinMap.CircuitCycle + circuit, () => CycleCircuit(circuit - 1)); + trilist.SetSigTrueAction(joinMap.CircuitOnCmd + circuit, () => TurnOnCircuit(circuit - 1)); + trilist.SetSigTrueAction(joinMap.CircuitOffCmd + circuit, () => TurnOffCircuit(circuit - 1)); + + } + } + void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) { Debug.Console(2, this, "Socket Status Change: {0}", e.Client.ClientStatus.ToString()); @@ -310,4 +338,20 @@ namespace PepperDash.Essentials.Devices.Common } } + + public class DigitalLoggerFactory : EssentialsDeviceFactory + { + public DigitalLoggerFactory() + { + TypeNames = new List() { "digitallogger" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new DigitalLogger Device"); + var props = JsonConvert.DeserializeObject( + dc.Properties.ToString()); + return new DigitalLogger(dc.Key, dc.Name, props); + } + } } \ 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 78e2ac22..25d17eb4 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 @@ -4,15 +4,18 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; - +using Crestron.SimplSharpPro.DeviceSupport; +using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Presets; using PepperDash.Essentials.Core.Routing; namespace PepperDash.Essentials.Devices.Common { - public class IRSetTopBoxBase : Device, ISetTopBoxControls, IUiDisplayInfo, IRoutingOutputs, IUsageTracking, IPower + public class IRSetTopBoxBase : EssentialsBridgeableDevice, ISetTopBoxControls, IRoutingOutputs, IUsageTracking, IPower { public IrOutputPortController IrPort { get; private set; } @@ -367,5 +370,119 @@ namespace PepperDash.Essentials.Devices.Common } #endregion + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new SetTopBoxControllerJoinMap(); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + Debug.Console(0, "Linking to Display: {0}", Name); + + trilist.StringInput[joinMap.Name].StringValue = Name; + + var stbBase = this as ISetTopBoxControls; + + trilist.BooleanInput[joinMap.HasDpad].BoolValue = stbBase.HasDpad; + trilist.BooleanInput[joinMap.HasNumeric].BoolValue = stbBase.HasNumeric; + trilist.BooleanInput[joinMap.HasDvr].BoolValue = stbBase.HasDvr; + trilist.BooleanInput[joinMap.HasPresets].BoolValue = stbBase.HasPresets; + + trilist.SetBoolSigAction(joinMap.DvrList, stbBase.DvrList); + trilist.SetBoolSigAction(joinMap.Replay, stbBase.Replay); + + trilist.SetStringSigAction(joinMap.LoadPresets, stbBase.LoadPresets); + + var stbPower = this as IPower; + + trilist.SetSigTrueAction(joinMap.PowerOn, stbPower.PowerOn); + trilist.SetSigTrueAction(joinMap.PowerOff, stbPower.PowerOff); + trilist.SetSigTrueAction(joinMap.PowerToggle, stbPower.PowerToggle); + + var stbDPad = this as IDPad; + + trilist.SetBoolSigAction(joinMap.Up, stbDPad.Up); + trilist.SetBoolSigAction(joinMap.Down, stbDPad.Down); + trilist.SetBoolSigAction(joinMap.Left, stbDPad.Left); + trilist.SetBoolSigAction(joinMap.Right, stbDPad.Right); + trilist.SetBoolSigAction(joinMap.Select, stbDPad.Select); + trilist.SetBoolSigAction(joinMap.Menu, stbDPad.Menu); + trilist.SetBoolSigAction(joinMap.Exit, stbDPad.Exit); + + var stbChannel = this as IChannel; + trilist.SetBoolSigAction(joinMap.ChannelUp, stbChannel.ChannelUp); + trilist.SetBoolSigAction(joinMap.ChannelDown, stbChannel.ChannelDown); + trilist.SetBoolSigAction(joinMap.LastChannel, stbChannel.LastChannel); + trilist.SetBoolSigAction(joinMap.Guide, stbChannel.Guide); + trilist.SetBoolSigAction(joinMap.Info, stbChannel.Info); + trilist.SetBoolSigAction(joinMap.Exit, stbChannel.Exit); + + var stbColor = this as IColor; + trilist.SetBoolSigAction(joinMap.Red, stbColor.Red); + trilist.SetBoolSigAction(joinMap.Green, stbColor.Green); + trilist.SetBoolSigAction(joinMap.Yellow, stbColor.Yellow); + trilist.SetBoolSigAction(joinMap.Blue, stbColor.Blue); + + var stbKeypad = this as ISetTopBoxNumericKeypad; + + trilist.StringInput[joinMap.KeypadAccessoryButton1Label].StringValue = stbKeypad.KeypadAccessoryButton1Label; + trilist.StringInput[joinMap.KeypadAccessoryButton2Label].StringValue = stbKeypad.KeypadAccessoryButton2Label; + + trilist.BooleanInput[joinMap.HasKeypadAccessoryButton1].BoolValue = stbKeypad.HasKeypadAccessoryButton1; + trilist.BooleanInput[joinMap.HasKeypadAccessoryButton2].BoolValue = stbKeypad.HasKeypadAccessoryButton2; + + trilist.SetBoolSigAction(joinMap.Digit0, stbKeypad.Digit0); + trilist.SetBoolSigAction(joinMap.Digit1, stbKeypad.Digit1); + trilist.SetBoolSigAction(joinMap.Digit2, stbKeypad.Digit2); + trilist.SetBoolSigAction(joinMap.Digit3, stbKeypad.Digit3); + trilist.SetBoolSigAction(joinMap.Digit4, stbKeypad.Digit4); + trilist.SetBoolSigAction(joinMap.Digit5, stbKeypad.Digit5); + trilist.SetBoolSigAction(joinMap.Digit6, stbKeypad.Digit6); + trilist.SetBoolSigAction(joinMap.Digit7, stbKeypad.Digit7); + trilist.SetBoolSigAction(joinMap.Digit8, stbKeypad.Digit8); + trilist.SetBoolSigAction(joinMap.Digit9, stbKeypad.Digit9); + trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton1Press, stbKeypad.KeypadAccessoryButton1); + trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton2Press, stbKeypad.KeypadAccessoryButton1); + trilist.SetBoolSigAction(joinMap.Dash, stbKeypad.Dash); + trilist.SetBoolSigAction(joinMap.KeypadEnter, stbKeypad.KeypadEnter); + + var stbTransport = this as ITransport; + trilist.SetBoolSigAction(joinMap.Play, stbTransport.Play); + trilist.SetBoolSigAction(joinMap.Pause, stbTransport.Pause); + trilist.SetBoolSigAction(joinMap.Rewind, stbTransport.Rewind); + trilist.SetBoolSigAction(joinMap.FFwd, stbTransport.FFwd); + trilist.SetBoolSigAction(joinMap.ChapMinus, stbTransport.ChapMinus); + trilist.SetBoolSigAction(joinMap.ChapPlus, stbTransport.ChapPlus); + trilist.SetBoolSigAction(joinMap.Stop, stbTransport.Stop); + trilist.SetBoolSigAction(joinMap.Record, stbTransport.Record); + } + } + + public class IRSetTopBoxBaseFactory : EssentialsDeviceFactory + { + public IRSetTopBoxBaseFactory() + { + TypeNames = new List() { "settopbox" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new SetTopBox Device"); + var irCont = IRPortHelper.GetIrOutputPortController(dc); + var config = dc.Properties.ToObject(); + var stb = new IRSetTopBoxBase(dc.Key, dc.Name, irCont, config); + + var listName = dc.Properties.Value("presetsList"); + if (listName != null) + stb.LoadPresets(listName); + return stb; + + } } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/SoftCodec/BlueJeansPc.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/SoftCodec/BlueJeansPc.cs new file mode 100644 index 00000000..735df48c --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/SoftCodec/BlueJeansPc.cs @@ -0,0 +1,179 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Routing; +using PepperDash.Essentials.Core.Devices; +using PepperDash.Essentials.Core.Config; + + +namespace PepperDash.Essentials.Devices.Common.SoftCodec +{ + public class BlueJeansPc : InRoomPc, IRoutingInputs, IRunRouteAction, IRoutingSinkNoSwitching + { + + public RoutingInputPort AnyVideoIn { get; private set; } + + #region IRoutingInputs Members + + public RoutingPortCollection InputPorts { get; private set; } + + #endregion + + public BlueJeansPc(string key, string name) + : base(key, name) + { + InputPorts = new RoutingPortCollection(); + InputPorts.Add(AnyVideoIn = new RoutingInputPort(RoutingPortNames.AnyVideoIn, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.None, 0, this)); + } + + #region IRunRouteAction Members + + public void RunRouteAction(string routeKey, string sourceListKey) + { + RunRouteAction(routeKey, sourceListKey, null); + } + + public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback) + { + CrestronInvoke.BeginInvoke(o => + { + Debug.Console(1, this, "Run route action '{0}' on SourceList: {1}", routeKey, sourceListKey); + + var dict = ConfigReader.ConfigObject.GetSourceListForKey(sourceListKey); + if (dict == null) + { + Debug.Console(1, this, "WARNING: Config source list '{0}' not found", sourceListKey); + return; + } + + // Try to get the list item by it's string key + if (!dict.ContainsKey(routeKey)) + { + Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'", + routeKey, sourceListKey); + return; + } + + var item = dict[routeKey]; + + foreach (var route in item.RouteList) + { + DoRoute(route); + } + + // store the name and UI info for routes + if (item.SourceKey == "none") + { + CurrentSourceInfoKey = routeKey; + CurrentSourceInfo = null; + } + else if (item.SourceKey != null) + { + CurrentSourceInfoKey = routeKey; + CurrentSourceInfo = item; + } + + // report back when done + if (successCallback != null) + successCallback(); + }); + } + + #endregion + + /// + /// + /// + /// + /// + bool DoRoute(SourceRouteListItem route) + { + IRoutingSinkNoSwitching dest = null; + + dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching; + + if (dest == null) + { + Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey); + return false; + } + + if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase)) + { + dest.ReleaseRoute(); + if (dest is IPower) + (dest as IPower).PowerOff(); + } + else + { + var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs; + if (source == null) + { + Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey); + return false; + } + dest.ReleaseAndMakeRoute(source, route.Type); + } + return true; + } + + + + #region IHasCurrentSourceInfoChange Members + + public string CurrentSourceInfoKey { get; set; } + + /// + /// The SourceListItem last run - containing names and icons + /// + public SourceListItem CurrentSourceInfo + { + get { return _CurrentSourceInfo; } + set + { + if (value == _CurrentSourceInfo) return; + + var handler = CurrentSourceChange; + // remove from in-use tracker, if so equipped + if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking) + (_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control"); + + if (handler != null) + handler(_CurrentSourceInfo, ChangeType.WillChange); + + _CurrentSourceInfo = value; + + // add to in-use tracking + if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking) + (_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control"); + if (handler != null) + handler(_CurrentSourceInfo, ChangeType.DidChange); + } + } + SourceListItem _CurrentSourceInfo; + + public event SourceInfoChangeHandler CurrentSourceChange; + + #endregion + } + + public class BlueJeansPcFactory : EssentialsDeviceFactory + { + public BlueJeansPcFactory() + { + TypeNames = new List() { "bluejeanspc" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new BlueJeansPc Device"); + return new SoftCodec.BlueJeansPc(dc.Key, dc.Name); + } + } + +} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Streaming/AppleTV.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Streaming/AppleTV.cs index 596c16dd..1182d312 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Streaming/AppleTV.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Streaming/AppleTV.cs @@ -5,14 +5,16 @@ using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; - +using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Routing; namespace PepperDash.Essentials.Devices.Common { - public class AppleTV : Device, IDPad, ITransport, IUiDisplayInfo, IRoutingOutputs + public class AppleTV : EssentialsBridgeableDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingOutputs { public IrOutputPortController IrPort { get; private set; } @@ -141,5 +143,44 @@ namespace PepperDash.Essentials.Devices.Common public RoutingPortCollection OutputPorts { get; private set; } #endregion + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new AppleTvJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + Debug.Console(0, "Linking to Bridge Type {0}", GetType().Name); + + trilist.SetBoolSigAction(joinMap.UpArrow, Up); + trilist.SetBoolSigAction(joinMap.DnArrow, Down); + trilist.SetBoolSigAction(joinMap.LeftArrow, Left); + trilist.SetBoolSigAction(joinMap.RightArrow, Right); + trilist.SetBoolSigAction(joinMap.Select, Select); + trilist.SetBoolSigAction(joinMap.Menu, Menu); + trilist.SetBoolSigAction(joinMap.PlayPause, Play); + } } + + public class AppleTVFactory : EssentialsDeviceFactory + { + public AppleTVFactory() + { + TypeNames = new List() { "appletv" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new AppleTV Device"); + var irCont = IRPortHelper.GetIrOutputPortController(dc); + return new AppleTV(dc.Key, dc.Name, irCont); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Streaming/Roku.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Streaming/Roku.cs index 1c162040..49f96c31 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Streaming/Roku.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Streaming/Roku.cs @@ -8,11 +8,12 @@ using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Routing; namespace PepperDash.Essentials.Devices.Common { - public class Roku2 : Device, IDPad, ITransport, IUiDisplayInfo, IRoutingOutputs + public class Roku2 : EssentialsDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingOutputs { [Api] public IrOutputPortController IrPort { get; private set; } @@ -145,4 +146,21 @@ namespace PepperDash.Essentials.Devices.Common #endregion } + + public class Roku2Factory : EssentialsDeviceFactory + { + public Roku2Factory() + { + TypeNames = new List() { "roku" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Roku Device"); + var irCont = IRPortHelper.GetIrOutputPortController(dc); + return new Roku2(dc.Key, dc.Name, irCont); + + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCamera.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCamera.cs index 12819336..6f68b369 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCamera.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCamera.cs @@ -3,12 +3,13 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; - +using Crestron.SimplSharpPro.DeviceSupport; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Devices.Common.Cameras; namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { - public class CiscoFarEndCamera : CameraBase, IHasCameraPtzControl, IAmFarEndCamera + public class CiscoFarEndCamera : CameraBase, IHasCameraPtzControl, IAmFarEndCamera, IBridgeAdvanced { protected CiscoSparkCodec ParentCodec { get; private set; } @@ -98,9 +99,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Stop CallId: {0}", CallId)); } + + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge); + } } - public class CiscoSparkCamera : CameraBase, IHasCameraPtzControl, IHasCameraFocusControl + public class CiscoSparkCamera : CameraBase, IHasCameraPtzControl, IHasCameraFocusControl, IBridgeAdvanced { /// /// The codec this camera belongs to @@ -308,5 +314,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } #endregion + + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge); + } } } \ No newline at end of file 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 f8f7b298..cad7a18c 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 @@ -1843,4 +1843,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } } + public class CiscoSparkCodecFactory : EssentialsDeviceFactory + { + public CiscoSparkCodecFactory() + { + TypeNames = new List() { "ciscospark", "ciscowebex", "ciscowebexpro", "ciscoroomkit" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Cisco Codec Device"); + var comm = CommFactory.CreateCommForDevice(dc); + return new VideoCodec.Cisco.CiscoSparkCodec(dc, comm); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/RoomPresets.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/RoomPresets.cs index 2846674a..1b456774 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/RoomPresets.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/RoomPresets.cs @@ -7,6 +7,7 @@ using Crestron.SimplSharp; using Newtonsoft.Json; using PepperDash.Core; +using PepperDash.Essentials.Core.Presets; using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco; namespace PepperDash.Essentials.Devices.Common.VideoCodec @@ -67,34 +68,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } /// - /// Represents a room preset on a video coded. Typically stores camera position(s) and video routing. Can be recalled by Far End if enabled. + /// Represents a room preset on a video codec. Typically stores camera position(s) and video routing. Can be recalled by Far End if enabled. /// - public class CodecRoomPreset + public class CodecRoomPreset : PresetBase { - [JsonProperty("id")] - public int ID { get; set; } - /// - /// Used to store the name of the preset - /// - [JsonProperty("description")] - public string Description { get; set; } - /// - /// Indicates if the preset is defined(stored) in the codec - /// - [JsonProperty("defined")] - public bool Defined { get; set; } - /// - /// Indicates if the preset has the capability to be defined - /// - [JsonProperty("isDefinable")] - public bool IsDefinable { get; set; } - public CodecRoomPreset(int id, string description, bool def, bool isDef) + : base(id, description, def, isDef) { - ID = id; - Description = description; - Defined = def; - IsDefinable = isDef; + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs index d6580b67..dc32ecd8 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs @@ -770,4 +770,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec _AutoAnswerEnabled = value; } } + + public class MockVCFactory : EssentialsDeviceFactory + { + public MockVCFactory() + { + TypeNames = new List() { "mockvc" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new MockVC Device"); + return new VideoCodec.MockVC(dc); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVCCamera.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVCCamera.cs index c404ac89..0c008849 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVCCamera.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVCCamera.cs @@ -3,13 +3,14 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; - +using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Devices.Common.VideoCodec; namespace PepperDash.Essentials.Devices.Common.Cameras { - public class MockVCCamera : CameraBase, IHasCameraPtzControl, IHasCameraFocusControl + public class MockVCCamera : CameraBase, IHasCameraPtzControl, IHasCameraFocusControl, IBridgeAdvanced { protected VideoCodecBase ParentCodec { get; private set; } @@ -111,9 +112,14 @@ namespace PepperDash.Essentials.Devices.Common.Cameras } #endregion + + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge); + } } - public class MockFarEndVCCamera : CameraBase, IHasCameraPtzControl, IAmFarEndCamera + public class MockFarEndVCCamera : CameraBase, IHasCameraPtzControl, IAmFarEndCamera, IBridgeAdvanced { protected VideoCodecBase ParentCodec { get; private set; } @@ -191,5 +197,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras } #endregion + + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge); + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 84881df3..13fa895d 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1676,4 +1676,20 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom InitialSyncComplete = false; } } + + public class ZoomRoomFactory : EssentialsDeviceFactory + { + public ZoomRoomFactory() + { + TypeNames = new List() { "zoomroom" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new ZoomRoom Device"); + var comm = CommFactory.CreateCommForDevice(dc); + return new VideoCodec.ZoomRoom.ZoomRoom(dc, comm); + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomCamera.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomCamera.cs index 209cfdd9..4fa377ae 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomCamera.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomCamera.cs @@ -3,7 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; - +using Crestron.SimplSharpPro.DeviceSupport; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Devices.Common.Cameras; namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom @@ -29,7 +30,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } - public class ZoomRoomCamera : CameraBase, IHasCameraPtzControl + public class ZoomRoomCamera : CameraBase, IHasCameraPtzControl, IBridgeAdvanced { protected ZoomRoom ParentCodec { get; private set; } @@ -198,6 +199,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } #endregion + + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge); + } } public class ZoomRoomFarEndCamera : ZoomRoomCamera, IAmFarEndCamera