From f59654d75e364a18bb06693bb8eb0bcb60df8f35 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 6 Aug 2020 13:56:42 -0600 Subject: [PATCH 01/15] working on #109 to add QR support for TSW panels --- .../PepperDashEssentials.csproj | 1 + .../UI/JoinConstants/UIBoolJoin.cs | 1665 +++++++++-------- .../UI/JoinConstants/UIStringlJoin.cs | 21 +- .../EssentialsPanelMainInterfaceDriver.cs | 46 +- ...tialsPresentationPanelAvFunctionsDriver.cs | 10 +- .../EssentialsHuddlePanelAvFunctionsDriver.cs | 39 +- ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 35 +- .../UIDrivers/ScreenSaverController.cs | 99 + .../DeviceTypeInterfaces/IMobileControl.cs | 26 +- .../Room/EssentialsRoomBase.cs | 32 + .../CrestronTouchpanelPropertiesConfig.cs | 6 + 11 files changed, 1143 insertions(+), 837 deletions(-) create mode 100644 PepperDashEssentials/UIDrivers/ScreenSaverController.cs diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj index c522b52e..7fbda5ee 100644 --- a/PepperDashEssentials/PepperDashEssentials.csproj +++ b/PepperDashEssentials/PepperDashEssentials.csproj @@ -155,6 +155,7 @@ + diff --git a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs index f5a16578..a347fd90 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs @@ -1,490 +1,490 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.DeviceSupport; - -namespace PepperDash.Essentials -{ - /// - /// Where all UI element common joins are defined - /// - public class UIBoolJoin - { - /// - /// 901 - /// - public const uint VolumeUpPress = 901; - /// - /// 902 - /// - public const uint VolumeDownPress = 902; - - //**************************************************** - // Codec General - - /// - /// 1001 - /// - public const uint CallEndPress = 1001; - /// - /// 1002 - /// - public const uint CallEndAllConfirmPress = 1002; - /// - /// 1003 - For tapping the text field to reveal the keyboard - /// - public const uint CodecDirectorySearchTextPress = 1003; - /// - /// 1004 - /// - public const uint CallStopSharingPress = 1004; - /// - /// 1005 - /// - public const uint CallSharedSourceInfoVisible = 1005; - /// - /// 1006 - /// - public const uint CallEndAllConfirmVisible = 1006; - - - - // Audio Conference - /// - /// 1101 - /// - public const uint ACKeypadVisible = 1101; - /// - /// 1102 - /// - public const uint ACStagingPopoverVisible = 1102; - /// - /// 1111 - /// - public const uint ACSpeedDial1Press = 1111; - /// - /// 1112 - /// - public const uint ACSpeedDial2Press = 1112; - /// - /// 1113 - /// - public const uint ACSpeedDial3Press = 1113; - /// - /// 1114 - /// - public const uint ACSpeedDial4Press = 1114; - /// - /// 1121 - /// - public const uint ACSpeedDial1Visible = 1121; - /// - /// 1122 - /// - public const uint ACSpeedDial2Visible = 1122; - /// - /// 1123 - /// - public const uint ACSpeedDial3Visible = 1123; - /// - /// 1124 - /// - public const uint ACSpeedDial4Visible = 1124; - - //****************************************************** - // Video Conference - /// - /// 1201 - /// - public const uint VCKeypadWithFavoritesVisible = 1201; - /// - /// 1202 - /// - public const uint VCStagingInactivePopoverVisible = 1202; - /// - /// - /// - public const uint VCStagingActivePopoverVisible = 1203; - /// - /// - /// - public const uint VCKeypadVisible = 1204; - /// - /// 1205 - /// - public const uint VCDirectoryVisible = 1205; - /// - /// 1206 - /// - public const uint VCRecentsVisible = 1206; - /// - /// 1207 - /// - public const uint VCCameraVisible = 1207; - /// - /// 1208 - /// - public const uint VCSelfViewLayoutVisible = 1208; - /// - /// 1211 - 1215 - /// - public const uint VCFavoritePressStart = 1211; - // RANGE IN USE - public const uint VCFavoritePressEnd = 1215; - /// - /// 1221 - 1225 - /// - public const uint VCFavoriteVisibleStart = 1221; - // RANGE IN USE - public const uint VCFavoriteVisibleEnd = 1225; - /// - /// 1231 - /// - public const uint VCStagingRecentsPress = 1231; - /// - /// 1232 - /// - public const uint VCStagingDirectoryPress = 1232; - /// - /// 1233 - /// - public const uint VCStagingKeypadPress = 1233; - /// - /// 1234 - /// - public const uint VCStagingConnectPress = 1234; - /// - /// 1235 - /// - public const uint VCStagingCameraPress = 1235; - /// - /// 1236 - /// - public const uint VCStagingConnectEnable = 1236; - /// - /// 1237 - When the user touches the text field, should trigger keyboard - /// - public const uint VCKeypadTextPress = 1237; - /// - /// 1238 - /// - public const uint VCKeypadBackspacePress = 1238; - /// - /// 1239 - /// - public const uint VCKeypadBackspaceVisible = 1239; - /// - /// 1240 - /// - public const uint VCDirectoryBackPress = 1240; - /// - /// 1241 For touching the text area to bring up keyboard - /// - public const uint VCDirectorySearchTextPress = 1241; - /// - /// 1242 - /// - public const uint VCStagingSelfViewLayoutPress = 1242; - /// - /// 1243 - /// - public const uint VCDirectoryBackVisible = 1243; - /// - /// 1244 - /// - public const uint VCDirectoryBackspacePress = 1244; - /// - /// 1245 - /// - public const uint VCDirectoryBackspaceVisible = 1245; - /// - /// 1251 - /// - public const uint VCSelfViewTogglePress = 1251; - /// - /// 1252 - /// - public const uint VCLayoutTogglePress = 1252; - /// - /// 1253 - /// - public const uint VCSelfViewPipTogglePress = 1253; - /// - /// 1254 - /// - public const uint VCLayoutToggleEnable = 1254; - /// - /// 1255 - /// - public const uint VCMinMaxPress = 1255; - /// - /// 1256 - /// - public const uint VCMinMaxEnable = 1256; - - // Letter joins start at 2921; - - //****************************************************** - - // Environment Joins - - // Popup Container - - /// - /// 2001 - 2004 - /// - public const uint EnvironmentBackgroundSubpageVisibleBase = 2000; - - - // ColumnOne - - /// - /// 2011 - 2015 - /// - public const uint EnvironmentColumnOneLightingTypeVisibleBase = 2010; - - /// - /// 2016 - 2020 - /// - public const uint EnvironmentColumnOneShadingTypeVisibleBase = 2015; - - // ColumnTwo - - /// - /// 2021 - 2025 - /// - public const uint EnvironmentColumnTwoLightingTypeVisibleBase = 2020; - - /// - /// 2026 - 2030 - /// - public const uint EnvironmentColumnTwoShadingTypeVisibleBase = 2025; - - // ColumnThree - - /// - /// 2031 - 2035 - /// - public const uint EnvironmentColumnThreeLightingTypeVisibleBase = 2030; - - /// - /// 2036 - 2040 - /// - public const uint EnvironmentColumnThreeShadingTypeVisibleBase = 2035; - - // ColumnFour - - /// - /// 2041 - 2045 - /// - public const uint EnvironmentColumnFourLightingTypeVisibleBase = 2040; - - /// - /// 2046 - 2050 - /// - public const uint EnvironmentColumnFourShadingTypeVisibleBase = 2045; - - // Button press - - /// - /// 2051 - 2060 - /// - public const uint EnvironmentColumnOneButtonPressBase = 2050; - - /// - /// 2061 - 2070 - /// - public const uint EnvironmentColumnTwoButtonPressBase = 2060; - - /// - /// 2071 - 2080 - /// - public const uint EnvironmentColumnThreeButtonPressBase = 2070; - - /// - /// 2081 - 2090 - /// - public const uint EnvironmentColumnFourButtonPressBase = 2080; - - // Button visibility - - /// - /// 2151 - 2160 - /// - public const uint EnvironmentColumnOneButtonVisibleBase = 2150; - - /// - /// 2161 - 2170 - /// - public const uint EnvironmentColumnTwoButtonVisibleBase = 2160; - - /// - /// 2171 - 2180 - /// - public const uint EnvironmentColumnThreeButtonVisibleBase = 2170; - - /// - /// 2181 - 2190 - /// - public const uint EnvironmentColumnFourButtonVisibleBase = 2180; - - - //****************************************************** - - /// - /// 3101 - /// - public const uint TechExitButton = 3101; - /// - /// 3106 - /// - public const uint TechCommonItemsVisbible = 3106; - /// - /// 3107 - /// - public const uint TechSystemStatusVisible = 3107; - /// - /// 3108 - /// - public const uint TechDisplayControlsVisible = 3108; - /// - /// 3109 - /// - public const uint TechPanelSetupVisible = 3109; - /// - /// 3110 - /// - public const uint TechAdvancedVolumeVisible = 3110; - /// - /// 3111 - /// - public const uint TechAboutVisible = 3111; - /// - /// 3112 - /// - public const uint TechSchedulerVisible = 3112; - - //***************************************************** - /// - /// 3811 - /// - public const uint VolumeSingleMute1Visible = 3811; - /// - /// 3812 - /// - public const uint VolumeSlider1Press = 3812; - /// - /// 3813 - /// - public const uint Volume1ProgramMutePressAndFB = 3813; - /// - /// 3821 - /// - public const uint Volume2Visible = 3821; - /// - /// 3822 - /// - public const uint VolumeSlider2Press = 3822; - /// - /// 3823 - /// - public const uint Volume2MutePressAndFB = 3823; - /// - /// 3831 - /// - public const uint Volume3Visible = 3831; - /// - /// 3832 - /// - public const uint VolumeSlider3Press = 3832; - /// - /// 3833 - /// - public const uint Volume3MutePressAndFB = 3833; - /// - /// 3841 - /// - public const uint Volume4Visible = 3841; - /// - /// 3842 - /// - public const uint VolumeSlider4Press = 3842; - /// - /// 3843 - /// - public const uint Volume4MutePressAndFB = 3843; - /// - /// 3851 - /// - public const uint Volume5Visible = 3851; - /// - /// 3852 - /// - public const uint VolumeSlider5Press = 3852; - /// - /// 3853 - /// - public const uint Volume5MutePressAndFB = 3853; - /// - /// 3861 - /// - public const uint Volume6Visible = 3861; - /// - /// 3862 - /// - public const uint VolumeSlider6Press = 3862; - /// - /// 3863 - /// - public const uint Volume6MutePressAndFB = 3863; - - /// - /// 3869 - when the system is off and the gear is pressed - /// - public const uint VolumesPagePowerOffVisible = 3869; - /// - /// 3870 - /// - public const uint VolumesPageVisible = 3870; - /// - /// 3871 - /// - public const uint VolumeDualMute1Visible = 3871; - /// - /// 3874 - /// - public const uint Volume1SpeechMutePressAndFB = 3874; - /// - /// 3875 - /// - public const uint Volume1BackerVisibility = 3875; - /// - /// 3891 - /// - public const uint VolumeDefaultPress = 3891; - /// - /// 3951 - /// - /// 3952 - /// - public const uint HeaderIcon2Press = 3952; - /// - /// 3953 - /// - public const uint HeaderIcon3Press = 3953; - /// - /// 3954 - /// - public const uint HeaderIcon4Press = 3954; - /// - /// 3955 - /// +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; + +namespace PepperDash.Essentials +{ + /// + /// Where all UI element common joins are defined + /// + public class UIBoolJoin + { + /// + /// 901 + /// + public const uint VolumeUpPress = 901; + /// + /// 902 + /// + public const uint VolumeDownPress = 902; + + //**************************************************** + // Codec General + + /// + /// 1001 + /// + public const uint CallEndPress = 1001; + /// + /// 1002 + /// + public const uint CallEndAllConfirmPress = 1002; + /// + /// 1003 - For tapping the text field to reveal the keyboard + /// + public const uint CodecDirectorySearchTextPress = 1003; + /// + /// 1004 + /// + public const uint CallStopSharingPress = 1004; + /// + /// 1005 + /// + public const uint CallSharedSourceInfoVisible = 1005; + /// + /// 1006 + /// + public const uint CallEndAllConfirmVisible = 1006; + + + + // Audio Conference + /// + /// 1101 + /// + public const uint ACKeypadVisible = 1101; + /// + /// 1102 + /// + public const uint ACStagingPopoverVisible = 1102; + /// + /// 1111 + /// + public const uint ACSpeedDial1Press = 1111; + /// + /// 1112 + /// + public const uint ACSpeedDial2Press = 1112; + /// + /// 1113 + /// + public const uint ACSpeedDial3Press = 1113; + /// + /// 1114 + /// + public const uint ACSpeedDial4Press = 1114; + /// + /// 1121 + /// + public const uint ACSpeedDial1Visible = 1121; + /// + /// 1122 + /// + public const uint ACSpeedDial2Visible = 1122; + /// + /// 1123 + /// + public const uint ACSpeedDial3Visible = 1123; + /// + /// 1124 + /// + public const uint ACSpeedDial4Visible = 1124; + + //****************************************************** + // Video Conference + /// + /// 1201 + /// + public const uint VCKeypadWithFavoritesVisible = 1201; + /// + /// 1202 + /// + public const uint VCStagingInactivePopoverVisible = 1202; + /// + /// + /// + public const uint VCStagingActivePopoverVisible = 1203; + /// + /// + /// + public const uint VCKeypadVisible = 1204; + /// + /// 1205 + /// + public const uint VCDirectoryVisible = 1205; + /// + /// 1206 + /// + public const uint VCRecentsVisible = 1206; + /// + /// 1207 + /// + public const uint VCCameraVisible = 1207; + /// + /// 1208 + /// + public const uint VCSelfViewLayoutVisible = 1208; + /// + /// 1211 - 1215 + /// + public const uint VCFavoritePressStart = 1211; + // RANGE IN USE + public const uint VCFavoritePressEnd = 1215; + /// + /// 1221 - 1225 + /// + public const uint VCFavoriteVisibleStart = 1221; + // RANGE IN USE + public const uint VCFavoriteVisibleEnd = 1225; + /// + /// 1231 + /// + public const uint VCStagingRecentsPress = 1231; + /// + /// 1232 + /// + public const uint VCStagingDirectoryPress = 1232; + /// + /// 1233 + /// + public const uint VCStagingKeypadPress = 1233; + /// + /// 1234 + /// + public const uint VCStagingConnectPress = 1234; + /// + /// 1235 + /// + public const uint VCStagingCameraPress = 1235; + /// + /// 1236 + /// + public const uint VCStagingConnectEnable = 1236; + /// + /// 1237 - When the user touches the text field, should trigger keyboard + /// + public const uint VCKeypadTextPress = 1237; + /// + /// 1238 + /// + public const uint VCKeypadBackspacePress = 1238; + /// + /// 1239 + /// + public const uint VCKeypadBackspaceVisible = 1239; + /// + /// 1240 + /// + public const uint VCDirectoryBackPress = 1240; + /// + /// 1241 For touching the text area to bring up keyboard + /// + public const uint VCDirectorySearchTextPress = 1241; + /// + /// 1242 + /// + public const uint VCStagingSelfViewLayoutPress = 1242; + /// + /// 1243 + /// + public const uint VCDirectoryBackVisible = 1243; + /// + /// 1244 + /// + public const uint VCDirectoryBackspacePress = 1244; + /// + /// 1245 + /// + public const uint VCDirectoryBackspaceVisible = 1245; + /// + /// 1251 + /// + public const uint VCSelfViewTogglePress = 1251; + /// + /// 1252 + /// + public const uint VCLayoutTogglePress = 1252; + /// + /// 1253 + /// + public const uint VCSelfViewPipTogglePress = 1253; + /// + /// 1254 + /// + public const uint VCLayoutToggleEnable = 1254; + /// + /// 1255 + /// + public const uint VCMinMaxPress = 1255; + /// + /// 1256 + /// + public const uint VCMinMaxEnable = 1256; + + // Letter joins start at 2921; + + //****************************************************** + + // Environment Joins + + // Popup Container + + /// + /// 2001 - 2004 + /// + public const uint EnvironmentBackgroundSubpageVisibleBase = 2000; + + + // ColumnOne + + /// + /// 2011 - 2015 + /// + public const uint EnvironmentColumnOneLightingTypeVisibleBase = 2010; + + /// + /// 2016 - 2020 + /// + public const uint EnvironmentColumnOneShadingTypeVisibleBase = 2015; + + // ColumnTwo + + /// + /// 2021 - 2025 + /// + public const uint EnvironmentColumnTwoLightingTypeVisibleBase = 2020; + + /// + /// 2026 - 2030 + /// + public const uint EnvironmentColumnTwoShadingTypeVisibleBase = 2025; + + // ColumnThree + + /// + /// 2031 - 2035 + /// + public const uint EnvironmentColumnThreeLightingTypeVisibleBase = 2030; + + /// + /// 2036 - 2040 + /// + public const uint EnvironmentColumnThreeShadingTypeVisibleBase = 2035; + + // ColumnFour + + /// + /// 2041 - 2045 + /// + public const uint EnvironmentColumnFourLightingTypeVisibleBase = 2040; + + /// + /// 2046 - 2050 + /// + public const uint EnvironmentColumnFourShadingTypeVisibleBase = 2045; + + // Button press + + /// + /// 2051 - 2060 + /// + public const uint EnvironmentColumnOneButtonPressBase = 2050; + + /// + /// 2061 - 2070 + /// + public const uint EnvironmentColumnTwoButtonPressBase = 2060; + + /// + /// 2071 - 2080 + /// + public const uint EnvironmentColumnThreeButtonPressBase = 2070; + + /// + /// 2081 - 2090 + /// + public const uint EnvironmentColumnFourButtonPressBase = 2080; + + // Button visibility + + /// + /// 2151 - 2160 + /// + public const uint EnvironmentColumnOneButtonVisibleBase = 2150; + + /// + /// 2161 - 2170 + /// + public const uint EnvironmentColumnTwoButtonVisibleBase = 2160; + + /// + /// 2171 - 2180 + /// + public const uint EnvironmentColumnThreeButtonVisibleBase = 2170; + + /// + /// 2181 - 2190 + /// + public const uint EnvironmentColumnFourButtonVisibleBase = 2180; + + + //****************************************************** + + /// + /// 3101 + /// + public const uint TechExitButton = 3101; + /// + /// 3106 + /// + public const uint TechCommonItemsVisbible = 3106; + /// + /// 3107 + /// + public const uint TechSystemStatusVisible = 3107; + /// + /// 3108 + /// + public const uint TechDisplayControlsVisible = 3108; + /// + /// 3109 + /// + public const uint TechPanelSetupVisible = 3109; + /// + /// 3110 + /// + public const uint TechAdvancedVolumeVisible = 3110; + /// + /// 3111 + /// + public const uint TechAboutVisible = 3111; + /// + /// 3112 + /// + public const uint TechSchedulerVisible = 3112; + + //***************************************************** + /// + /// 3811 + /// + public const uint VolumeSingleMute1Visible = 3811; + /// + /// 3812 + /// + public const uint VolumeSlider1Press = 3812; + /// + /// 3813 + /// + public const uint Volume1ProgramMutePressAndFB = 3813; + /// + /// 3821 + /// + public const uint Volume2Visible = 3821; + /// + /// 3822 + /// + public const uint VolumeSlider2Press = 3822; + /// + /// 3823 + /// + public const uint Volume2MutePressAndFB = 3823; + /// + /// 3831 + /// + public const uint Volume3Visible = 3831; + /// + /// 3832 + /// + public const uint VolumeSlider3Press = 3832; + /// + /// 3833 + /// + public const uint Volume3MutePressAndFB = 3833; + /// + /// 3841 + /// + public const uint Volume4Visible = 3841; + /// + /// 3842 + /// + public const uint VolumeSlider4Press = 3842; + /// + /// 3843 + /// + public const uint Volume4MutePressAndFB = 3843; + /// + /// 3851 + /// + public const uint Volume5Visible = 3851; + /// + /// 3852 + /// + public const uint VolumeSlider5Press = 3852; + /// + /// 3853 + /// + public const uint Volume5MutePressAndFB = 3853; + /// + /// 3861 + /// + public const uint Volume6Visible = 3861; + /// + /// 3862 + /// + public const uint VolumeSlider6Press = 3862; + /// + /// 3863 + /// + public const uint Volume6MutePressAndFB = 3863; + + /// + /// 3869 - when the system is off and the gear is pressed + /// + public const uint VolumesPagePowerOffVisible = 3869; + /// + /// 3870 + /// + public const uint VolumesPageVisible = 3870; + /// + /// 3871 + /// + public const uint VolumeDualMute1Visible = 3871; + /// + /// 3874 + /// + public const uint Volume1SpeechMutePressAndFB = 3874; + /// + /// 3875 + /// + public const uint Volume1BackerVisibility = 3875; + /// + /// 3891 + /// + public const uint VolumeDefaultPress = 3891; + /// + /// 3951 + /// + /// 3952 + /// + public const uint HeaderIcon2Press = 3952; + /// + /// 3953 + /// + public const uint HeaderIcon3Press = 3953; + /// + /// 3954 + /// + public const uint HeaderIcon4Press = 3954; + /// + /// 3955 + /// public const uint HeaderIcon5Press = 3955; /// 3960 @@ -509,329 +509,370 @@ namespace PepperDash.Essentials /// /// 3965 /// - public const uint HeaderCaret5Visible = 3965; - - /// - /// 3999 - /// - public const uint GenericModalVisible = 3999; - /// - /// 12345 - /// - public const uint AvNoControlsSubVisible = 12345; - - // 10000 - 14999 are general "source" pages - - /// - /// 15001 - /// - public const uint StartPageVisible = 15001; - /// - /// 15002 Shows the start page in the source controls area of the screen - /// - public const uint TapToBeginVisible = 15002; - /// - /// 15003 Message text when no source is showing - /// - public const uint SelectASourceVisible = 15003; - /// - /// 15004 - /// - public const uint RoomIsOn = 15004; - /// - /// 15005 Shows always-on volume control subpage with only audio mute - /// - public const uint VolumeControlsSingleMuteVisible = 15005; - /// - /// 15006 Shows always-on volume control subpage with mic and audio mutes - /// - public const uint VolumeControlsDualMuteVisible = 15006; - /// - /// 15010 - /// - public const uint ShowPanelSetupPress = 15010; - /// - /// 15011 - Top bar with room name and button that pops up dialog with room data - /// - public const uint TopBarHabaneroVisible = 15011; - /// - /// 15012 - /// - public const uint SourceStagingBarVisible = 15012; - /// - /// 15013 - /// - public const uint PowerOffStep1Visible = 15013; - /// - /// 15014 - /// - public const uint PowerOffStep2Visible = 15014; - /// - /// 15015 - /// - public const uint ShowPowerOffPress = 15015; - /// - /// 15016 - /// - public const uint PowerOffMorePress = 15016; - /// - /// 15017 - /// - public const uint StagingPageAdditionalArrowsVisible = 15017; - /// - /// 15018 The Header with dynamic buttons - /// - public const uint TopBarHabaneroDynamicVisible = 15018; - /// - /// 15019 Shown when system is starting and not ready for use - /// - public const uint SystemInitializingVisible = 15019; - /// - /// 15020 - /// - public const uint PanelSetupVisible = 15020; - /// - /// 15021 - /// - public const uint SourceWaitOverlayVisible = 15021; - /// - /// 15022 - /// - public const uint ActivityFooterVisible = 15022; - /// - /// 15024 - /// - public const uint HeaderCallStatusLeftPositionVisible = 15024; - /// - /// 15025 - /// - public const uint HeaderCallStatusRightPositionVisible = 15025; - /// - /// 15027 - /// - public const uint HeaderCallStatusLabelPress = 15027; - /// - /// 15028 The gear button in header - /// - public const uint FIXFIX_HeaderGearButtonPress_FIXFIX = 15028; - /// - /// 15029 the room button in header - /// - public const uint HeaderRoomButtonPress = 15029; - /// - /// 15030 Visibility for room data popup - /// - public const uint RoomHeaderPageVisible = 15030; - /// - /// 15031 - /// - public const uint AllRoomsOffPress = 15031; - /// - /// 15032 - /// - public const uint DisplayPowerTogglePress = 15032; - /// - /// 15033 - /// - public const uint PowerOffCancelPress = 15033; - /// - /// 15034 - /// - public const uint PowerOffConfirmPress = 15034; - /// - /// 15035 - /// - public const uint VolumeButtonPopupPress = 15035; - /// - /// 15035 - /// - public const uint VolumeButtonPopupVisible = 15035; - /// - /// 15036 - /// - public const uint VolumeGaugePopupVisible = 15036; - /// - /// 15037 - /// - public const uint GearButtonVisible = 15037; - /// - /// 15038 - /// - public const uint CalendarHeaderButtonVisible = 15038; - /// - /// 15039 - /// - public const uint CalendarHeaderButtonPress = 15039; - /// - /// 15040 - /// - public const uint CallStatusPageVisible = 15040; - /// - /// 15041 - /// - public const uint LightsPageVisible = 15041; - /// - /// 15042 Closes whichever interlocked modal is open - /// - public const uint InterlockedModalClosePress = 15042; - /// - /// 15043 Vis for modal backer for full-screen source - /// - public const uint SourceBackgroundOverlayVisible = 15043; - /// - /// 15044 Close button for source modal overlay - /// - public const uint SourceBackgroundOverlayClosePress = 15044; - /// - /// 15045 - Visibility for the bar containing call navigation button list - /// - public const uint CallStagingBarVisible = 15045; - /// - /// 15046 - /// - public const uint MeetingsOrContacMethodsListVisible = 15046; - /// - /// 15047 The "Join" button on the next meeting ribbon - /// - public const uint NextMeetingJoinPress = 15047; - /// - /// 15048 Dismisses the ribbon - /// - public const uint NextMeetingModalClosePress = 15048; - /// - /// 15049 - /// - public const uint NextMeetingModalVisible = 15049; - /// - /// 15051 - /// - public const uint Display1SelectPressAndFb = 15051; - /// - /// 15052 - /// - public const uint Display1ControlButtonEnable = 15052; - /// - /// 15053 - /// - public const uint Display1ControlButtonPress = 15053; - /// - /// 15054 - /// - public const uint Display1AudioButtonEnable = 15054; - /// - /// 15055 - /// - public const uint Display1AudioButtonPressAndFb = 15055; - /// - /// 15056 - /// - public const uint Display2SelectPressAndFb = 15056; - /// - /// 15057 - /// - public const uint Display2ControlButtonEnable = 15057; - /// - /// 15058 - /// - public const uint Display2ControlButtonPress = 15058; - /// - /// 15059 - /// - public const uint Display2AudioButtonEnable = 15059; - /// - /// 15060 - /// - public const uint Display2AudioButtonPressAndFb = 15060; - /// - /// 15061 Reveals the dual-display subpage - /// - public const uint DualDisplayPageVisible = 15061; - /// - /// 15062 Reveals the toggle switch for the sharing mode - /// - public const uint ToggleSharingModeVisible = 15062; - /// - /// 15063 Press for the toggle mode switch - /// - public const uint ToggleSharingModePress = 15063; - /// - /// 15064 - /// - public const uint LogoDefaultVisible = 15064; - /// - /// 15065 - /// - public const uint LogoUrlVisible = 15065; - /// - /// 15066 - Reveals the active calls header item - /// - public const uint HeaderActiveCallsListVisible = 15066; - /// - /// 15067 - /// - public const uint NotificationRibbonVisible = 15067; - /// - /// 15083 - Press for Call help desk on AC/VC - /// - public const uint HelpPageShowCallButtonPress = 15083; - /// - /// 15084 - Show the "call help desk" button on help page - /// - public const uint HelpPageShowCallButtonVisible = 15084; - /// - /// 15085 Visibility join for help subpage - /// - public const uint HelpPageVisible = 15085; - /// - /// 15086 Press for help header button - /// - public const uint HelpPress = 15086; - /// - /// 15088 - /// - public const uint DateOnlyVisible = 15088; - /// - /// 15089 - /// - public const uint TimeOnlyVisible = 15089; - /// - /// 15090 - /// - public const uint DateAndTimeVisible = 15090; - /// - /// 15091 - /// - public const uint SetupFullDistrib = 15091; - - // PIN dialogs ************************************ - - /// - /// 15201 - /// - public const uint PinDialog4DigitVisible = 15201; - /// - /// 15206 - /// - public const uint PinDialogCancelPress = 15206; - /// - /// 15207 - /// - public const uint PinDialogErrorVisible = 15207; - /// - /// 15211 - /// - public const uint PinDialogDot1 = 15211; - /// - /// 15212 - /// - public const uint PinDialogDot2 = 15212; - /// - /// 15213 - /// - public const uint PinDialogDot3 = 15213; - /// - /// 15214 - /// - public const uint PinDialogDot4 = 15214; - } + public const uint HeaderCaret5Visible = 3965; + + /// + /// 3999 + /// + public const uint GenericModalVisible = 3999; + /// + /// 12345 + /// + public const uint AvNoControlsSubVisible = 12345; + + // 10000 - 14999 are general "source" pages + + /// + /// 15001 + /// + public const uint StartPageVisible = 15001; + /// + /// 15002 Shows the start page in the source controls area of the screen + /// + public const uint TapToBeginVisible = 15002; + /// + /// 15003 Message text when no source is showing + /// + public const uint SelectASourceVisible = 15003; + /// + /// 15004 + /// + public const uint RoomIsOn = 15004; + /// + /// 15005 Shows always-on volume control subpage with only audio mute + /// + public const uint VolumeControlsSingleMuteVisible = 15005; + /// + /// 15006 Shows always-on volume control subpage with mic and audio mutes + /// + public const uint VolumeControlsDualMuteVisible = 15006; + /// + /// 15010 + /// + public const uint ShowPanelSetupPress = 15010; + /// + /// 15011 - Top bar with room name and button that pops up dialog with room data + /// + public const uint TopBarHabaneroVisible = 15011; + /// + /// 15012 + /// + public const uint SourceStagingBarVisible = 15012; + /// + /// 15013 + /// + public const uint PowerOffStep1Visible = 15013; + /// + /// 15014 + /// + public const uint PowerOffStep2Visible = 15014; + /// + /// 15015 + /// + public const uint ShowPowerOffPress = 15015; + /// + /// 15016 + /// + public const uint PowerOffMorePress = 15016; + /// + /// 15017 + /// + public const uint StagingPageAdditionalArrowsVisible = 15017; + /// + /// 15018 The Header with dynamic buttons + /// + public const uint TopBarHabaneroDynamicVisible = 15018; + /// + /// 15019 Shown when system is starting and not ready for use + /// + public const uint SystemInitializingVisible = 15019; + /// + /// 15020 + /// + public const uint PanelSetupVisible = 15020; + /// + /// 15021 + /// + public const uint SourceWaitOverlayVisible = 15021; + /// + /// 15022 + /// + public const uint ActivityFooterVisible = 15022; + /// + /// 15024 + /// + public const uint HeaderCallStatusLeftPositionVisible = 15024; + /// + /// 15025 + /// + public const uint HeaderCallStatusRightPositionVisible = 15025; + /// + /// 15027 + /// + public const uint HeaderCallStatusLabelPress = 15027; + /// + /// 15028 The gear button in header + /// + public const uint FIXFIX_HeaderGearButtonPress_FIXFIX = 15028; + /// + /// 15029 the room button in header + /// + public const uint HeaderRoomButtonPress = 15029; + /// + /// 15030 Visibility for room data popup + /// + public const uint RoomHeaderPageVisible = 15030; + /// + /// 15031 + /// + public const uint AllRoomsOffPress = 15031; + /// + /// 15032 + /// + public const uint DisplayPowerTogglePress = 15032; + /// + /// 15033 + /// + public const uint PowerOffCancelPress = 15033; + /// + /// 15034 + /// + public const uint PowerOffConfirmPress = 15034; + /// + /// 15035 + /// + public const uint VolumeButtonPopupPress = 15035; + /// + /// 15035 + /// + public const uint VolumeButtonPopupVisible = 15035; + /// + /// 15036 + /// + public const uint VolumeGaugePopupVisible = 15036; + /// + /// 15037 + /// + public const uint GearButtonVisible = 15037; + /// + /// 15038 + /// + public const uint CalendarHeaderButtonVisible = 15038; + /// + /// 15039 + /// + public const uint CalendarHeaderButtonPress = 15039; + /// + /// 15040 + /// + public const uint CallStatusPageVisible = 15040; + /// + /// 15041 + /// + public const uint LightsPageVisible = 15041; + /// + /// 15042 Closes whichever interlocked modal is open + /// + public const uint InterlockedModalClosePress = 15042; + /// + /// 15043 Vis for modal backer for full-screen source + /// + public const uint SourceBackgroundOverlayVisible = 15043; + /// + /// 15044 Close button for source modal overlay + /// + public const uint SourceBackgroundOverlayClosePress = 15044; + /// + /// 15045 - Visibility for the bar containing call navigation button list + /// + public const uint CallStagingBarVisible = 15045; + /// + /// 15046 + /// + public const uint MeetingsOrContacMethodsListVisible = 15046; + /// + /// 15047 The "Join" button on the next meeting ribbon + /// + public const uint NextMeetingJoinPress = 15047; + /// + /// 15048 Dismisses the ribbon + /// + public const uint NextMeetingModalClosePress = 15048; + /// + /// 15049 + /// + public const uint NextMeetingModalVisible = 15049; + /// + /// 15051 + /// + public const uint Display1SelectPressAndFb = 15051; + /// + /// 15052 + /// + public const uint Display1ControlButtonEnable = 15052; + /// + /// 15053 + /// + public const uint Display1ControlButtonPress = 15053; + /// + /// 15054 + /// + public const uint Display1AudioButtonEnable = 15054; + /// + /// 15055 + /// + public const uint Display1AudioButtonPressAndFb = 15055; + /// + /// 15056 + /// + public const uint Display2SelectPressAndFb = 15056; + /// + /// 15057 + /// + public const uint Display2ControlButtonEnable = 15057; + /// + /// 15058 + /// + public const uint Display2ControlButtonPress = 15058; + /// + /// 15059 + /// + public const uint Display2AudioButtonEnable = 15059; + /// + /// 15060 + /// + public const uint Display2AudioButtonPressAndFb = 15060; + /// + /// 15061 Reveals the dual-display subpage + /// + public const uint DualDisplayPageVisible = 15061; + /// + /// 15062 Reveals the toggle switch for the sharing mode + /// + public const uint ToggleSharingModeVisible = 15062; + /// + /// 15063 Press for the toggle mode switch + /// + public const uint ToggleSharingModePress = 15063; + /// + /// 15064 + /// + public const uint LogoDefaultVisible = 15064; + /// + /// 15065 + /// + public const uint LogoUrlVisible = 15065; + /// + /// 15066 - Reveals the active calls header item + /// + public const uint HeaderActiveCallsListVisible = 15066; + /// + /// 15067 + /// + public const uint NotificationRibbonVisible = 15067; + /// + /// 15083 - Press for Call help desk on AC/VC + /// + public const uint HelpPageShowCallButtonPress = 15083; + /// + /// 15084 - Show the "call help desk" button on help page + /// + public const uint HelpPageShowCallButtonVisible = 15084; + /// + /// 15085 Visibility join for help subpage + /// + public const uint HelpPageVisible = 15085; + /// + /// 15086 Press for help header button + /// + public const uint HelpPress = 15086; + /// + /// 15088 + /// + public const uint DateOnlyVisible = 15088; + /// + /// 15089 + /// + public const uint TimeOnlyVisible = 15089; + /// + /// 15090 + /// + public const uint DateAndTimeVisible = 15090; + /// + /// 15091 + /// + public const uint SetupFullDistrib = 15091; + + /// + /// 15092 + /// + public const uint StartMCPageVisible = 15092; + + + /// + /// 15093 + /// + public const uint RoomHeaderMCPageVisible = 15093; + + /// + /// 15094 + /// + public const uint MCScreenSaverVisible = 15094; + + /// + /// 15095 + /// + public const uint MCScreenSaverPosition1Visible = 15095; + + /// + /// 15096 + /// + public const uint MCScreenSaverPosition2Visible = 15096; + + /// + /// 15097 + /// + public const uint MCScreenSaverPosition3Visible = 15097; + + /// + /// 15098 + /// + public const uint MCScreenSaverPosition4Visible = 15098; + + /// + /// 15099 + /// + public const uint MCScreenSaverClosePress = 15099; + + // PIN dialogs ************************************ + + /// + /// 15201 + /// + public const uint PinDialog4DigitVisible = 15201; + /// + /// 15206 + /// + public const uint PinDialogCancelPress = 15206; + /// + /// 15207 + /// + public const uint PinDialogErrorVisible = 15207; + /// + /// 15211 + /// + public const uint PinDialogDot1 = 15211; + /// + /// 15212 + /// + public const uint PinDialogDot2 = 15212; + /// + /// 15213 + /// + public const uint PinDialogDot3 = 15213; + /// + /// 15214 + /// + public const uint PinDialogDot4 = 15214; + } } \ No newline at end of file diff --git a/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs index b5f5a86b..5d9b9a2e 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs @@ -146,6 +146,10 @@ namespace PepperDash.Essentials /// public const uint RoomPhoneText = 3904; /// + /// 3905 - Video address/number for room header + /// + public const uint RoomVideoAddressText = 3905; + /// /// 3906 - The separator for verbose-header text on addresses /// public const uint RoomAddressPipeText = 3906; @@ -154,6 +158,14 @@ namespace PepperDash.Essentials /// public const uint RoomUserCode = 3907; /// + /// 3908 - The url for the mobile control server + /// + public const uint RoomMcUrl = 3908; + /// + /// 3908 - The url for the mobile control QR Code image + /// + public const uint RoomMcWQrCodeUrl = 3909; + /// /// 3911 /// public const uint PowerOffMessage = 3911; @@ -189,12 +201,19 @@ namespace PepperDash.Essentials /// /// 3923 /// - public const uint LogoUrl = 3923; + public const uint LogoUrlLightBkgnd = 3923; + + /// /// 3924 - the text on the "call help desk" button /// public const uint HelpPageCallButtonText = 3924; + /// + /// 3925 + /// + public const uint LogoUrlDarkBkgnd = 3923; + /// /// 3951 /// diff --git a/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs b/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs index e32015fe..59994712 100644 --- a/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs +++ b/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs @@ -1,4 +1,5 @@ using System; +using Crestron.SimplSharp; using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.UI; using PepperDash.Essentials.Core; @@ -11,6 +12,8 @@ namespace PepperDash.Essentials /// public class EssentialsPanelMainInterfaceDriver : PanelDriverBase { + CTimer InactivityTimer; + /// /// Assign the appropriate A/V driver. /// Want to keep the AvDriver alive, because it may hold states @@ -23,6 +26,8 @@ namespace PepperDash.Essentials public PanelDriverBase CurrentChildDriver { get; private set; } + public ScreenSaverController ScreenSaverController { get; private set; } + CrestronTouchpanelPropertiesConfig Config; /// @@ -35,8 +40,47 @@ namespace PepperDash.Essentials : base(trilist) { Config = config; + + var tsx52or60 = trilist as Tswx52ButtonVoiceControl; + + if (tsx52or60 != null) + { + tsx52or60.ExtenderTouchDetectionReservedSigs.DeviceExtenderSigChange += ExtenderTouchDetectionReservedSigs_DeviceExtenderSigChange; + } + else + { + var tswx70 = trilist as TswX70Base; + if (tswx70 != null) + { + tswx70.ExtenderTouchDetectionReservedSigs.DeviceExtenderSigChange += ExtenderTouchDetectionReservedSigs_DeviceExtenderSigChange; + } + } } + void ExtenderTouchDetectionReservedSigs_DeviceExtenderSigChange(Crestron.SimplSharpPro.DeviceExtender currentDeviceExtender, Crestron.SimplSharpPro.SigEventArgs args) + { + if (args.Sig.BoolValue) + { + if (InactivityTimer != null) + { + InactivityTimer.Reset(); + } + else + { + InactivityTimer = new CTimer((o) => InactivityTimerExpired(), Config.ScreenSaverTimeoutMin * 60 * 1000); + } + } + } + + void InactivityTimerExpired() + { + InactivityTimer.Stop(); + InactivityTimer.Dispose(); + InactivityTimer = null; + + ScreenSaverController.Show(); + } + public override void Show() { CurrentChildDriver = null; @@ -46,7 +90,7 @@ namespace PepperDash.Essentials public override void Hide() { - TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false; + TriList.BooleanInput[AvDriver.StartPageVisibleJoin].BoolValue = false; base.Hide(); } diff --git a/PepperDashEssentials/UIDrivers/Essentials/EssentialsPresentationPanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/Essentials/EssentialsPresentationPanelAvFunctionsDriver.cs index edda29e0..4a8cb53c 100644 --- a/PepperDashEssentials/UIDrivers/Essentials/EssentialsPresentationPanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/Essentials/EssentialsPresentationPanelAvFunctionsDriver.cs @@ -267,7 +267,7 @@ // HideAndClearCurrentDisplayModeSigsInUse(); // tl[UIBoolJoin.TopBarHabaneroVisible].BoolValue = false; // tl[UIBoolJoin.ActivityFooterVisible].BoolValue = false; -// tl[UIBoolJoin.StartPageVisible].BoolValue = false; +// tl[StartPageVisibleJoin].BoolValue = false; // tl[UIBoolJoin.TapToBeginVisible].BoolValue = false; // tl[UIBoolJoin.ToggleSharingModeVisible].BoolValue = false; // tl[UIBoolJoin.SourceStagingBarVisible].BoolValue = false; @@ -335,7 +335,7 @@ // } // else // { -// TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = true; +// TriList.BooleanInput[StartPageVisibleJoin].BoolValue = true; // TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = true; // TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false; // } @@ -525,7 +525,7 @@ // if (!_CurrentRoom.OnFeedback.BoolValue) // { // ShareButtonSig.BoolValue = true; -// TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false; +// TriList.BooleanInput[StartPageVisibleJoin].BoolValue = false; // ShowCurrentSharingMode(); // } // } @@ -953,13 +953,13 @@ // if (value) // { // SetupActivityFooterWhenRoomOn(); -// TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false; +// TriList.BooleanInput[StartPageVisibleJoin].BoolValue = false; // } // else // { // HideCurrentSharingMode(); // SetupActivityFooterWhenRoomOff(); -// TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = true; +// TriList.BooleanInput[StartPageVisibleJoin].BoolValue = true; // if (LastSelectedSourceSig != null) // { // LastSelectedSourceSig.BoolValue = false; diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs index 232a99da..c19b5fc1 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs @@ -24,6 +24,9 @@ namespace PepperDash.Essentials PresentationMode, AudioSetup } + public uint StartPageVisibleJoin { get; private set; } + + /// /// Whether volume ramping from this panel will show the volume /// gauge popup. @@ -225,7 +228,16 @@ namespace PepperDash.Essentials if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Habanero) { TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () => - PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderPageVisible)); + { + if (CurrentRoom.IsMobileControlEnabled) + { + PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderMCPageVisible); + } + else + { + PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderPageVisible); + } + }); } else if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose) { @@ -256,7 +268,7 @@ namespace PepperDash.Essentials } else { - TriList.SetBool(UIBoolJoin.StartPageVisible, true); + TriList.SetBool(StartPageVisibleJoin, true); TriList.SetBool(UIBoolJoin.TapToBeginVisible, true); SetupActivityFooterWhenRoomOff(); } @@ -330,7 +342,7 @@ namespace PepperDash.Essentials { TriList.SetBool(UIBoolJoin.LogoDefaultVisible, false); TriList.SetBool(UIBoolJoin.LogoUrlVisible, true); - TriList.SetString(UIStringJoin.LogoUrl, _CurrentRoom.LogoUrl); + TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _CurrentRoom.LogoUrl); } } @@ -351,7 +363,7 @@ namespace PepperDash.Essentials HideAndClearCurrentDisplayModeSigsInUse(); TriList.BooleanInput[UIBoolJoin.TopBarHabaneroDynamicVisible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.ActivityFooterVisible].BoolValue = false; - TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false; + TriList.BooleanInput[StartPageVisibleJoin].BoolValue = false; TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false; //TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = false; @@ -416,7 +428,7 @@ namespace PepperDash.Essentials } else { - TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = true; + TriList.BooleanInput[StartPageVisibleJoin].BoolValue = true; TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = true; TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false; } @@ -474,7 +486,7 @@ namespace PepperDash.Essentials void ShareButtonPressed() { ShareButtonSig.BoolValue = true; - TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false; + TriList.BooleanInput[StartPageVisibleJoin].BoolValue = false; TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = true; TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = true; // Run default source when room is off and share is pressed @@ -787,7 +799,7 @@ namespace PepperDash.Essentials { TriList.BooleanInput[UIBoolJoin.LogoDefaultVisible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.LogoUrlVisible].BoolValue = true; - TriList.StringInput[UIStringJoin.LogoUrl].StringValue = _CurrentRoom.LogoUrl; + TriList.StringInput[UIStringJoin.LogoUrlLightBkgnd].StringValue = _CurrentRoom.LogoUrl; } // Shutdown timer @@ -823,6 +835,15 @@ namespace PepperDash.Essentials room.ConfigChanged -= room_ConfigChanged; room.ConfigChanged += room_ConfigChanged; + if (room.IsMobileControlEnabled) + { + StartPageVisibleJoin = UIBoolJoin.StartMCPageVisible; + } + else + { + StartPageVisibleJoin = UIBoolJoin.StartPageVisible; + } + RefreshCurrentRoom(room); } @@ -855,7 +876,7 @@ namespace PepperDash.Essentials SetupActivityFooterWhenRoomOn(); TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = true; - TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false; + TriList.BooleanInput[StartPageVisibleJoin].BoolValue = false; TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = true; } @@ -863,7 +884,7 @@ namespace PepperDash.Essentials { SetupActivityFooterWhenRoomOff(); ShowLogo(); - TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = true; + TriList.BooleanInput[StartPageVisibleJoin].BoolValue = true; TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false; } diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 9248e50a..7ae11b18 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -28,6 +28,8 @@ namespace PepperDash.Essentials Presentation, AudioSetup, Call, Start } + public uint StartPageVisibleJoin { get; private set; } + /// /// Whether volume ramping from this panel will show the volume /// gauge popup. @@ -240,7 +242,16 @@ namespace PepperDash.Essentials if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Habanero) { TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () => - PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderPageVisible)); + { + if (CurrentRoom.IsMobileControlEnabled) + { + PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderMCPageVisible); + } + else + { + PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderPageVisible); + } + }); } else if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose) { @@ -276,7 +287,7 @@ namespace PepperDash.Essentials } else { - TriList.SetBool(UIBoolJoin.StartPageVisible, true); + TriList.SetBool(StartPageVisibleJoin, true); TriList.SetBool(UIBoolJoin.TapToBeginVisible, true); SetupActivityFooterWhenRoomOff(); } @@ -341,7 +352,7 @@ namespace PepperDash.Essentials { TriList.SetBool(UIBoolJoin.LogoDefaultVisible, false); TriList.SetBool(UIBoolJoin.LogoUrlVisible, true); - TriList.SetString(UIStringJoin.LogoUrl, _CurrentRoom.LogoUrl); + TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _CurrentRoom.LogoUrl); } } @@ -362,7 +373,7 @@ namespace PepperDash.Essentials HideAndClearCurrentDisplayModeSigsInUse(); TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, false); TriList.BooleanInput[UIBoolJoin.ActivityFooterVisible].BoolValue = false; - TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false; + TriList.BooleanInput[StartPageVisibleJoin].BoolValue = false; TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false; if (NextMeetingTimer != null) @@ -606,7 +617,7 @@ namespace PepperDash.Essentials return; HideLogo(); HideNextMeetingPopup(); - TriList.SetBool(UIBoolJoin.StartPageVisible, false); + TriList.SetBool(StartPageVisibleJoin, false); TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false); TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); if (CurrentSourcePageManager != null) @@ -626,7 +637,7 @@ namespace PepperDash.Essentials if (VCDriver.IsVisible) VCDriver.Hide(); HideNextMeetingPopup(); - TriList.SetBool(UIBoolJoin.StartPageVisible, false); + TriList.SetBool(StartPageVisibleJoin, false); TriList.SetBool(UIBoolJoin.CallStagingBarVisible, false); TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, true); // Run default source when room is off and share is pressed @@ -960,6 +971,15 @@ namespace PepperDash.Essentials room.ConfigChanged -= room_ConfigChanged; room.ConfigChanged += room_ConfigChanged; + if (room.IsMobileControlEnabled) + { + StartPageVisibleJoin = UIBoolJoin.StartMCPageVisible; + } + else + { + StartPageVisibleJoin = UIBoolJoin.StartPageVisible; + } + RefreshCurrentRoom(room); } @@ -1149,7 +1169,7 @@ namespace PepperDash.Essentials var value = _CurrentRoom.OnFeedback.BoolValue; TriList.BooleanInput[UIBoolJoin.RoomIsOn].BoolValue = value; - TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = !value; + TriList.BooleanInput[StartPageVisibleJoin].BoolValue = !value; if (value) //ON { @@ -1381,6 +1401,7 @@ namespace PepperDash.Essentials void ShowNotificationRibbon(string message, int timeout); void HideNotificationRibbon(); void ShowTech(); + uint StartPageVisibleJoin { get; } } /// diff --git a/PepperDashEssentials/UIDrivers/ScreenSaverController.cs b/PepperDashEssentials/UIDrivers/ScreenSaverController.cs new file mode 100644 index 00000000..a082987e --- /dev/null +++ b/PepperDashEssentials/UIDrivers/ScreenSaverController.cs @@ -0,0 +1,99 @@ +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 +{ + /// + /// Driver responsible for controlling the screenshaver showing the client logo, MC connection information and QR Code. Moves the elements around to prevent screen burn in + /// + public class ScreenSaverController : PanelDriverBase + { + CTimer PositionTimer; + + uint PositionTimeoutMs; + + List PositionJoins; + + int CurrentPositionIndex; + + public ScreenSaverController(EssentialsPanelMainInterfaceDriver parent, CrestronTouchpanelPropertiesConfig config) + : base(parent.TriList) + { + PositionTimeoutMs = config.ScreenSaverMovePositionIntervalMs; + + TriList.SetSigFalseAction(UIBoolJoin.MCScreenSaverClosePress, () => this.Hide()); + + PositionJoins = new List() + { UIBoolJoin.MCScreenSaverPosition1Visible, UIBoolJoin.MCScreenSaverPosition2Visible, UIBoolJoin.MCScreenSaverPosition3Visible, UIBoolJoin.MCScreenSaverPosition4Visible }; + } + + public override void Show() + { + TriList.SetBool(UIBoolJoin.MCScreenSaverVisible, true); + + StartPositionTimer(); + + base.Show(); + } + + public override void Hide() + { + PositionTimer.Stop(); + PositionTimer.Dispose(); + PositionTimer = null; + + ClearAllPositions(); + + TriList.SetBool(UIBoolJoin.MCScreenSaverVisible, false); + + base.Hide(); + } + + + + void StartPositionTimer() + { + if (PositionTimer == null) + { + PositionTimer = new CTimer((o) => PositionTimerExpired(), PositionTimeoutMs); + SetCurrentPosition(); + } + } + + void PositionTimerExpired() + { + if (CurrentPositionIndex <= PositionJoins.Count) + { + CurrentPositionIndex++; + } + else + { + CurrentPositionIndex = 0; + } + } + + // + void SetCurrentPosition() + { + ClearAllPositions(); + + // Set based on current index + TriList.SetBool(PositionJoins[CurrentPositionIndex], true); + } + + void ClearAllPositions() + { + foreach (var join in PositionJoins) + { + TriList.SetBool(join, false); + } + } + } + +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs index 03f73ba4..53170915 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs @@ -1,11 +1,33 @@ -using PepperDash.Core; +using System; +using PepperDash.Core; namespace PepperDash.Essentials.Core.DeviceTypeInterfaces { - public interface IMobileControl:IKeyed + /// + /// Describes a MobileControlSystemController + /// + public interface IMobileControl : IKeyed { void CreateMobileControlRoomBridge(EssentialsRoomBase room); void LinkSystemMonitorToAppServer(); } + + /// + /// Describes a MobileControl Room Bridge + /// + public interface IMobileControlRoomBridge : IKeyed + { + event EventHandler UserCodeChanged; + + IMobileControl Parent { get; } + + string UserCode { get; } + + string QrCodeUrl { get; } + + string McServerUrl { get; } + + string RoomName { get; } + } } \ 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 bb57941e..47d1399a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs @@ -9,6 +9,7 @@ using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Devices; +using PepperDash.Essentials.Core.DeviceTypeInterfaces; namespace PepperDash.Essentials.Core { @@ -37,6 +38,16 @@ namespace PepperDash.Essentials.Core protected abstract Func IsWarmingFeedbackFunc { get; } protected abstract Func IsCoolingFeedbackFunc { get; } + /// + /// Indicates if this room is Mobile Control Enabled + /// + public bool IsMobileControlEnabled { get; private set; } + + /// + /// The bridge for this room if Mobile Control is enabled + /// + public IMobileControlRoomBridge MobileControlRoomBridge { get; private set; } + /// /// The config name of the source list /// @@ -125,9 +136,30 @@ namespace PepperDash.Essentials.Core { if (RoomOccupancy != null) OnRoomOccupancyIsSet(); + + SetUpMobileControl(); }); } + /// + /// If mobile control is enabled, sets the appropriate properties + /// + void SetUpMobileControl() + { + var mcBridgeKey = string.Format("mobileControlBridge-{0}", Key); + var mcBridge = DeviceManager.GetDeviceForKey(mcBridgeKey); + if (mcBridge == null) + { + Debug.Console(1, this, "Mobile Control Bridge Not found for this room."); + return; + } + else + { + MobileControlRoomBridge = mcBridge as IMobileControlRoomBridge; + IsMobileControlEnabled = true; + } + } + void RoomVacancyShutdownPromptTimer_HasFinished(object sender, EventArgs e) { switch (VacancyMode) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/CrestronTouchpanelPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/CrestronTouchpanelPropertiesConfig.cs index 42882a51..73b66bce 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/CrestronTouchpanelPropertiesConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/CrestronTouchpanelPropertiesConfig.cs @@ -14,6 +14,8 @@ public UiSetupPropertiesConfig Setup { get; set; } public string HeaderStyle { get; set; } public bool IncludeInFusionRoomHealth { get; set; } + public uint ScreenSaverTimeoutMin { get; set; } + public uint ScreenSaverMovePositionIntervalMs { get; set; } /// @@ -26,6 +28,10 @@ { SourcesOverflowCount = 5; HeaderStyle = CrestronTouchpanelPropertiesConfig.Habanero; + + // Default values + ScreenSaverTimeoutMin = 5; + ScreenSaverMovePositionIntervalMs = 15000; } /// From bf7a0600f32f2087f47d50bf5c1cc7f8e474911c Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 6 Aug 2020 14:42:45 -0600 Subject: [PATCH 02/15] specified previous docker build version --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 315fbd67..a1325840 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -58,7 +58,7 @@ jobs: - name: Build Solution shell: powershell run: | - Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)" + Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder:v1.4.1 c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)" # Zip up the output files as needed - name: Zip Build Output shell: powershell From 637ca2f3129a75f1975cbe912547c321e85fb4be Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 6 Aug 2020 15:04:02 -0600 Subject: [PATCH 03/15] removes parent from interfaces --- .../DeviceTypeInterfaces/IMobileControl.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs index 53170915..616d61b1 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs @@ -11,6 +11,8 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces void CreateMobileControlRoomBridge(EssentialsRoomBase room); void LinkSystemMonitorToAppServer(); + + } /// @@ -20,8 +22,6 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces { event EventHandler UserCodeChanged; - IMobileControl Parent { get; } - string UserCode { get; } string QrCodeUrl { get; } From 192aa4255c256f2ed9a0698aff01918c1732a859 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 6 Aug 2020 15:20:24 -0600 Subject: [PATCH 04/15] Adds ability for dark logo option --- .../Room/Config/EssentialsRoomConfig.cs | 5 ++++- .../Room/Types/EssentialsDualDisplayRoom.cs | 3 ++- .../Room/Types/EssentialsHuddleSpaceRoom.cs | 3 ++- .../Room/Types/EssentialsHuddleVtc1Room.cs | 3 ++- .../EssentialsHuddlePanelAvFunctionsDriver.cs | 11 +++++++---- .../EssentialsHuddleVtc1PanelAvFunctionsDriver.cs | 5 +++-- .../Room/EssentialsRoomBase.cs | 4 +++- 7 files changed, 23 insertions(+), 11 deletions(-) diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs index b34e923b..e2d229e2 100644 --- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs @@ -156,7 +156,10 @@ namespace PepperDash.Essentials.Room.Config public EssentialsEnvironmentPropertiesConfig Environment { get; set; } [JsonProperty("logo")] - public EssentialsLogoPropertiesConfig Logo { get; set; } + public EssentialsLogoPropertiesConfig LogoLight { get; set; } + + [JsonProperty("logoDark")] + public EssentialsLogoPropertiesConfig LogoDark { get; set; } [JsonProperty("microphonePrivacy")] public EssentialsRoomMicrophonePrivacyConfig MicrophonePrivacy { get; set; } diff --git a/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs b/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs index 8113174a..7d855a3d 100644 --- a/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs @@ -327,7 +327,8 @@ namespace PepperDash.Essentials this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes); - this.LogoUrl = PropertiesConfig.Logo.GetUrl(); + this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetUrl(); + this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetUrl(); this.SourceListKey = PropertiesConfig.SourceListKey; this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem; this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100); diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs index 03f3afc7..7d8e2094 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs @@ -250,7 +250,8 @@ namespace PepperDash.Essentials this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes); - this.LogoUrl = PropertiesConfig.Logo.GetUrl(); + this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetUrl(); + this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetUrl(); this.SourceListKey = PropertiesConfig.SourceListKey; this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem; this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100); diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index b7ce3030..baeef0fb 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -340,7 +340,8 @@ namespace PepperDash.Essentials IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes); } - this.LogoUrl = PropertiesConfig.Logo.GetUrl(); + this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetUrl(); + this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetUrl(); this.SourceListKey = PropertiesConfig.SourceListKey; this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem; this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100); diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs index c19b5fc1..f7e1d5d4 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs @@ -333,7 +333,7 @@ namespace PepperDash.Essentials /// void ShowLogo() { - if (CurrentRoom.LogoUrl == null) + if (CurrentRoom.LogoUrlLightBkgnd == null) { TriList.SetBool(UIBoolJoin.LogoDefaultVisible, true); TriList.SetBool(UIBoolJoin.LogoUrlVisible, false); @@ -342,7 +342,8 @@ namespace PepperDash.Essentials { TriList.SetBool(UIBoolJoin.LogoDefaultVisible, false); TriList.SetBool(UIBoolJoin.LogoUrlVisible, true); - TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _CurrentRoom.LogoUrl); + TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _CurrentRoom.LogoUrlLightBkgnd); + TriList.SetString(UIStringJoin.LogoUrlDarkBkgnd, _CurrentRoom.LogoUrlDarkBkgnd); } } @@ -790,7 +791,7 @@ namespace PepperDash.Essentials } // Name and logo TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = _CurrentRoom.Name; - if (_CurrentRoom.LogoUrl == null) + if (_CurrentRoom.LogoUrlLightBkgnd == null) { TriList.BooleanInput[UIBoolJoin.LogoDefaultVisible].BoolValue = true; TriList.BooleanInput[UIBoolJoin.LogoUrlVisible].BoolValue = false; @@ -799,7 +800,9 @@ namespace PepperDash.Essentials { TriList.BooleanInput[UIBoolJoin.LogoDefaultVisible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.LogoUrlVisible].BoolValue = true; - TriList.StringInput[UIStringJoin.LogoUrlLightBkgnd].StringValue = _CurrentRoom.LogoUrl; + TriList.StringInput[UIStringJoin.LogoUrlLightBkgnd].StringValue = _CurrentRoom.LogoUrlLightBkgnd; + TriList.StringInput[UIStringJoin.LogoUrlLightBkgnd].StringValue = _CurrentRoom.LogoUrlDarkBkgnd; + } // Shutdown timer diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 7ae11b18..a3919385 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -343,7 +343,7 @@ namespace PepperDash.Essentials /// void ShowLogo() { - if (CurrentRoom.LogoUrl == null) + if (CurrentRoom.LogoUrlLightBkgnd == null) { TriList.SetBool(UIBoolJoin.LogoDefaultVisible, true); TriList.SetBool(UIBoolJoin.LogoUrlVisible, false); @@ -352,7 +352,8 @@ namespace PepperDash.Essentials { TriList.SetBool(UIBoolJoin.LogoDefaultVisible, false); TriList.SetBool(UIBoolJoin.LogoUrlVisible, true); - TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _CurrentRoom.LogoUrl); + TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _CurrentRoom.LogoUrlLightBkgnd); + TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _CurrentRoom.LogoUrlDarkBkgnd); } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs index 47d1399a..1d0f40ff 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs @@ -69,7 +69,9 @@ namespace PepperDash.Essentials.Core public Core.Privacy.MicrophonePrivacyController MicrophonePrivacy { get; set; } - public string LogoUrl { get; set; } + public string LogoUrlLightBkgnd { get; set; } + + public string LogoUrlDarkBkgnd { get; set; } protected SecondsCountdownTimer RoomVacancyShutdownTimer { get; private set; } From edd01785d5d23e208c41b1e444fb1530eb8ffc66 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 6 Aug 2020 18:07:23 -0600 Subject: [PATCH 05/15] Adds ability to get URL for both light and dark logo options --- .../Room/Config/EssentialsRoomConfig.cs | 12 +++++++++++- .../Room/Types/EssentialsDualDisplayRoom.cs | 4 ++-- .../Room/Types/EssentialsHuddleSpaceRoom.cs | 4 ++-- .../Room/Types/EssentialsHuddleVtc1Room.cs | 4 ++-- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs index e2d229e2..4991350c 100644 --- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs @@ -283,7 +283,7 @@ namespace PepperDash.Essentials.Room.Config /// /// Gets either the custom URL, a local-to-processor URL, or null if it's a default logo /// - public string GetUrl() + public string GetLogoUrlLight() { if (Type == "url") return Url; @@ -292,6 +292,16 @@ namespace PepperDash.Essentials.Room.Config CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0)); return null; } + + public string GetLogoUrlDark() + { + if (Type == "url") + return Url; + if (Type == "system") + return string.Format("http://{0}:8080/logo-dark.png", + CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0)); + return null; + } } /// diff --git a/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs b/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs index 7d855a3d..34432269 100644 --- a/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs @@ -327,8 +327,8 @@ namespace PepperDash.Essentials this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes); - this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetUrl(); - this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetUrl(); + this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight(); + this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark(); this.SourceListKey = PropertiesConfig.SourceListKey; this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem; this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100); diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs index 7d8e2094..f0604308 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs @@ -250,8 +250,8 @@ namespace PepperDash.Essentials this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes); - this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetUrl(); - this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetUrl(); + this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight(); + this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark(); this.SourceListKey = PropertiesConfig.SourceListKey; this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem; this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100); diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index baeef0fb..754409a7 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -340,8 +340,8 @@ namespace PepperDash.Essentials IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes); } - this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetUrl(); - this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetUrl(); + this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight(); + this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark(); this.SourceListKey = PropertiesConfig.SourceListKey; this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem; this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100); From 66c481e3dc39798e679bb8240babfab49c6b464a Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 6 Aug 2020 19:46:12 -0600 Subject: [PATCH 06/15] Seems to work except dynamic graphics for logos and QR code --- .../Room/Types/EssentialsHuddleVtc1Room.cs | 1 + .../UI/JoinConstants/UIStringlJoin.cs | 4 ++-- .../EssentialsHuddlePanelAvFunctionsDriver.cs | 23 +++++++++++++++++++ ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 22 ++++++++++++++++++ .../Room/EssentialsRoomBase.cs | 13 ++++++++--- 5 files changed, 58 insertions(+), 5 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index 754409a7..1440b82f 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -342,6 +342,7 @@ namespace PepperDash.Essentials this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight(); this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark(); + this.SourceListKey = PropertiesConfig.SourceListKey; this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem; this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100); diff --git a/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs index 5d9b9a2e..b7ce6b0b 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs @@ -162,9 +162,9 @@ namespace PepperDash.Essentials /// public const uint RoomMcUrl = 3908; /// - /// 3908 - The url for the mobile control QR Code image + /// 3909 - The url for the mobile control QR Code image /// - public const uint RoomMcWQrCodeUrl = 3909; + public const uint RoomMcQrCodeUrl = 3909; /// /// 3911 /// diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs index f7e1d5d4..635982d2 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs @@ -212,6 +212,7 @@ namespace PepperDash.Essentials "Tap Share to begin"; } + /// /// /// @@ -835,12 +836,22 @@ namespace PepperDash.Essentials if (_CurrentRoom == room) return; // Disconnect current (probably never called) + if (_CurrentRoom != null) + _CurrentRoom.ConfigChanged -= room_ConfigChanged; + room.ConfigChanged -= room_ConfigChanged; room.ConfigChanged += room_ConfigChanged; if (room.IsMobileControlEnabled) { StartPageVisibleJoin = UIBoolJoin.StartMCPageVisible; + UpdateMCJoins(room); + + if (_CurrentRoom != null) + _CurrentRoom.MobileControlRoomBridge.UserCodeChanged -= MobileControlRoomBridge_UserCodeChanged; + + room.MobileControlRoomBridge.UserCodeChanged -= MobileControlRoomBridge_UserCodeChanged; + room.MobileControlRoomBridge.UserCodeChanged += MobileControlRoomBridge_UserCodeChanged; } else { @@ -850,6 +861,18 @@ namespace PepperDash.Essentials RefreshCurrentRoom(room); } + void MobileControlRoomBridge_UserCodeChanged(object sender, EventArgs e) + { + UpdateMCJoins(_CurrentRoom); + } + + void UpdateMCJoins(EssentialsHuddleSpaceRoom room) + { + TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl); + TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl); + TriList.SetString(UIStringJoin.RoomUserCode, room.MobileControlRoomBridge.UserCode); + } + /// /// Fires when room config of current room has changed. Meant to refresh room values to propegate any updates to UI /// diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index a3919385..581d7e22 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -969,12 +969,22 @@ namespace PepperDash.Essentials if (_CurrentRoom == room) return; // Disconnect current (probably never called) + if(_CurrentRoom != null) + _CurrentRoom.ConfigChanged -= room_ConfigChanged; + room.ConfigChanged -= room_ConfigChanged; room.ConfigChanged += room_ConfigChanged; if (room.IsMobileControlEnabled) { StartPageVisibleJoin = UIBoolJoin.StartMCPageVisible; + UpdateMCJoins(room); + + if (_CurrentRoom != null) + _CurrentRoom.MobileControlRoomBridge.UserCodeChanged -= MobileControlRoomBridge_UserCodeChanged; + + room.MobileControlRoomBridge.UserCodeChanged -= MobileControlRoomBridge_UserCodeChanged; + room.MobileControlRoomBridge.UserCodeChanged += MobileControlRoomBridge_UserCodeChanged; } else { @@ -984,6 +994,18 @@ namespace PepperDash.Essentials RefreshCurrentRoom(room); } + void MobileControlRoomBridge_UserCodeChanged(object sender, EventArgs e) + { + UpdateMCJoins(_CurrentRoom); + } + + void UpdateMCJoins(EssentialsHuddleVtc1Room room) + { + TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl); + TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl); + TriList.SetString(UIStringJoin.RoomUserCode, room.MobileControlRoomBridge.UserCode); + } + /// /// Fires when room config of current room has changed. Meant to refresh room values to propegate any updates to UI /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs index 1d0f40ff..624d072f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs @@ -138,11 +138,16 @@ namespace PepperDash.Essentials.Core { if (RoomOccupancy != null) OnRoomOccupancyIsSet(); - - SetUpMobileControl(); }); } + public override bool CustomActivate() + { + SetUpMobileControl(); + + return base.CustomActivate(); + } + /// /// If mobile control is enabled, sets the appropriate properties /// @@ -152,12 +157,14 @@ namespace PepperDash.Essentials.Core var mcBridge = DeviceManager.GetDeviceForKey(mcBridgeKey); if (mcBridge == null) { - Debug.Console(1, this, "Mobile Control Bridge Not found for this room."); + Debug.Console(1, this, "*********************Mobile Control Bridge Not found for this room."); + IsMobileControlEnabled = false; return; } else { MobileControlRoomBridge = mcBridge as IMobileControlRoomBridge; + Debug.Console(1, this, "*********************Mobile Control Bridge found and enabled for this room"); IsMobileControlEnabled = true; } } From d6581cab2e902403bae3c9b2fcb3ae621073f205 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 6 Aug 2020 21:16:03 -0600 Subject: [PATCH 07/15] Updates to work out kinks --- .../Room/Config/EssentialsRoomConfig.cs | 6 ++++ .../UI/EssentialsTouchpanelController.cs | 5 +++ .../UI/JoinConstants/UIBoolJoin.cs | 4 +-- .../EssentialsPanelMainInterfaceDriver.cs | 4 +-- .../EssentialsHuddlePanelAvFunctionsDriver.cs | 29 ++++++++++------- ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 31 +++++++++++-------- .../UIDrivers/ScreenSaverController.cs | 2 ++ .../VC/EssentialsVideoCodecUiDriver.cs | 27 +++++++++++----- 8 files changed, 72 insertions(+), 36 deletions(-) diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs index 4991350c..dfaa333d 100644 --- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs @@ -184,6 +184,12 @@ namespace PepperDash.Essentials.Room.Config [JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")] public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; } + + public EssentialsRoomPropertiesConfig() + { + LogoLight = new EssentialsLogoPropertiesConfig(); + LogoDark = new EssentialsLogoPropertiesConfig(); + } } public class EssentialsAvRoomPropertiesConfig : EssentialsRoomPropertiesConfig diff --git a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs index eade64bd..65039872 100644 --- a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs +++ b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs @@ -224,6 +224,8 @@ namespace PepperDash.Essentials var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey); if (room is EssentialsHuddleSpaceRoom) { + // Screen Saver Driver + mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, props); // Header Driver Debug.Console(0, panelController, "Adding header driver"); @@ -272,6 +274,9 @@ namespace PepperDash.Essentials { Debug.Console(0, panelController, "Adding huddle space VTC AV driver"); + // Screen Saver Driver + mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, props); + // Header Driver mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, props); diff --git a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs index a347fd90..d307d088 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs @@ -621,7 +621,7 @@ namespace PepperDash.Essentials /// /// 15030 Visibility for room data popup /// - public const uint RoomHeaderPageVisible = 15030; + public const uint RoomHeaderInfoPageVisible = 15030; /// /// 15031 /// @@ -812,7 +812,7 @@ namespace PepperDash.Essentials /// /// 15093 /// - public const uint RoomHeaderMCPageVisible = 15093; + public const uint RoomHeaderInfoMCPageVisible = 15093; /// /// 15094 diff --git a/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs b/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs index 59994712..651a072a 100644 --- a/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs +++ b/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs @@ -26,7 +26,7 @@ namespace PepperDash.Essentials public PanelDriverBase CurrentChildDriver { get; private set; } - public ScreenSaverController ScreenSaverController { get; private set; } + public ScreenSaverController ScreenSaverController { get; set; } CrestronTouchpanelPropertiesConfig Config; @@ -85,7 +85,7 @@ namespace PepperDash.Essentials { CurrentChildDriver = null; ShowSubDriver(AvDriver as PanelDriverBase); - base.Show(); + base.Show(); } public override void Hide() diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs index 635982d2..42b2cf5c 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs @@ -232,26 +232,31 @@ namespace PepperDash.Essentials { if (CurrentRoom.IsMobileControlEnabled) { - PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderMCPageVisible); + Debug.Console(1, "Showing Mobile Control Header Info"); + PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoMCPageVisible); } else { - PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderPageVisible); + Debug.Console(1, "Showing Non Mobile Control Header Info"); + PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoPageVisible); } }); } else if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose) { - // room name on join 1, concat phone and sip on join 2, no button method - //var addr = roomConf.Addresses; - //if (addr == null) // protect from missing values by using default empties - // addr = new EssentialsRoomAddressPropertiesConfig(); - //// empty string when either missing, pipe when both showing - //TriList.SetString(UIStringJoin.RoomAddressPipeText, - // (string.IsNullOrEmpty(addr.PhoneNumber.Trim()) - // || string.IsNullOrEmpty(addr.SipAddress.Trim())) ? "" : " | "); - //TriList.SetString(UIStringJoin.RoomPhoneText, addr.PhoneNumber); - //TriList.SetString(UIStringJoin.RoomSipText, addr.SipAddress); + TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () => + { + if (CurrentRoom.IsMobileControlEnabled) + { + Debug.Console(1, "Showing Mobile Control Header Info"); + PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoMCPageVisible); + } + else + { + Debug.Console(1, "Showing Non Mobile Control Header Info"); + PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoPageVisible); + } + }); } TriList.SetBool(UIBoolJoin.DateAndTimeVisible, Config.ShowDate && Config.ShowTime); diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 581d7e22..c74fd8e0 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -245,26 +245,31 @@ namespace PepperDash.Essentials { if (CurrentRoom.IsMobileControlEnabled) { - PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderMCPageVisible); + Debug.Console(1, "Showing Mobile Control Header Info"); + PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoMCPageVisible); } else { - PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderPageVisible); + Debug.Console(1, "Showing Non Mobile Control Header Info"); + PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoPageVisible); } }); } else if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose) { - // room name on join 1, concat phone and sip on join 2, no button method - //var addr = roomConf.Addresses; - //if (addr == null) // protect from missing values by using default empties - // addr = new EssentialsRoomAddressPropertiesConfig(); - //// empty string when either missing, pipe when both showing - //TriList.SetString(UIStringJoin.RoomAddressPipeText, - // (string.IsNullOrEmpty(addr.PhoneNumber.Trim()) - // || string.IsNullOrEmpty(addr.SipAddress.Trim())) ? "" : " | "); - //TriList.SetString(UIStringJoin.RoomPhoneText, addr.PhoneNumber); - //TriList.SetString(UIStringJoin.RoomSipText, addr.SipAddress); + TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () => + { + if (CurrentRoom.IsMobileControlEnabled) + { + Debug.Console(1, "Showing Mobile Control Header Info"); + PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoMCPageVisible); + } + else + { + Debug.Console(1, "Showing Non Mobile Control Header Info"); + PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoPageVisible); + } + }); } TriList.SetBool(UIBoolJoin.DateAndTimeVisible, Config.ShowDate && Config.ShowTime); @@ -353,7 +358,7 @@ namespace PepperDash.Essentials TriList.SetBool(UIBoolJoin.LogoDefaultVisible, false); TriList.SetBool(UIBoolJoin.LogoUrlVisible, true); TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _CurrentRoom.LogoUrlLightBkgnd); - TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _CurrentRoom.LogoUrlDarkBkgnd); + TriList.SetString(UIStringJoin.LogoUrlDarkBkgnd, _CurrentRoom.LogoUrlDarkBkgnd); } } diff --git a/PepperDashEssentials/UIDrivers/ScreenSaverController.cs b/PepperDashEssentials/UIDrivers/ScreenSaverController.cs index a082987e..ab903173 100644 --- a/PepperDashEssentials/UIDrivers/ScreenSaverController.cs +++ b/PepperDashEssentials/UIDrivers/ScreenSaverController.cs @@ -31,6 +31,8 @@ namespace PepperDash.Essentials PositionJoins = new List() { UIBoolJoin.MCScreenSaverPosition1Visible, UIBoolJoin.MCScreenSaverPosition2Visible, UIBoolJoin.MCScreenSaverPosition3Visible, UIBoolJoin.MCScreenSaverPosition4Visible }; + + CrestronConsole.AddNewConsoleCommand((o) => Show(), "showscreensaver", "Shows Panel Screensaver", ConsoleAccessLevelEnum.AccessOperator); } public override void Show() diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index f966c4cb..16551067 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -192,17 +192,30 @@ namespace PepperDash.Essentials.UIDrivers.VC /// void Codec_IsReady() { - string roomNumberSipUri = ""; + string roomContactNumbers = ""; + string roomPhoneNumber = ""; if (!string.IsNullOrEmpty(Codec.CodecInfo.SipUri)) // If both values are present, format the string with a pipe divider - roomNumberSipUri = string.Format("{0} | {1}", GetFormattedPhoneNumber(Codec.CodecInfo.SipPhoneNumber), Codec.CodecInfo.SipUri); + { + roomContactNumbers = string.Format("{0} | {1}", GetFormattedPhoneNumber(Codec.CodecInfo.SipPhoneNumber), Codec.CodecInfo.SipUri); + roomPhoneNumber = GetFormattedPhoneNumber(Codec.CodecInfo.SipPhoneNumber); + } else // If only one value present, just show the phone number - roomNumberSipUri = Codec.CodecInfo.SipPhoneNumber; + { + roomPhoneNumber = GetFormattedPhoneNumber(Codec.CodecInfo.SipPhoneNumber); + roomContactNumbers = Codec.CodecInfo.SipPhoneNumber; + } - if(string.IsNullOrEmpty(roomNumberSipUri)) - roomNumberSipUri = string.Format("{0} | {1}", Codec.CodecInfo.E164Alias, Codec.CodecInfo.H323Id); - - TriList.SetString(UIStringJoin.RoomPhoneText, roomNumberSipUri); + if (string.IsNullOrEmpty(roomContactNumbers)) + { + if(!string.IsNullOrEmpty(Codec.CodecInfo.E164Alias)) + roomContactNumbers = string.Format("{0} | {1}", Codec.CodecInfo.E164Alias, Codec.CodecInfo.H323Id); + else + roomContactNumbers = Codec.CodecInfo.H323Id; + } + TriList.SetString(UIStringJoin.RoomAddressPipeText, roomContactNumbers); + TriList.SetString(UIStringJoin.RoomPhoneText, roomPhoneNumber); + TriList.SetString(UIStringJoin.RoomVideoAddressText, Codec.CodecInfo.H323Id); if(HeaderDriver.HeaderButtonsAreSetUp) HeaderDriver.ComputeHeaderCallStatus(Codec); From b7c9677c7a2d229aba69f02bb305bb6f8ace6360 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 6 Aug 2020 22:04:07 -0600 Subject: [PATCH 08/15] Updates to finesse screen saver and get phone/video number display working correclty --- .../EssentialsPanelMainInterfaceDriver.cs | 6 +++-- .../UIDrivers/ScreenSaverController.cs | 23 +++++++++++++--- .../VC/EssentialsVideoCodecUiDriver.cs | 27 +++++++++++++------ 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs b/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs index 651a072a..5793c3bd 100644 --- a/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs +++ b/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs @@ -59,15 +59,17 @@ namespace PepperDash.Essentials void ExtenderTouchDetectionReservedSigs_DeviceExtenderSigChange(Crestron.SimplSharpPro.DeviceExtender currentDeviceExtender, Crestron.SimplSharpPro.SigEventArgs args) { + var timeoutMs = Config.ScreenSaverTimeoutMin * 60 * 1000; + if (args.Sig.BoolValue) { if (InactivityTimer != null) { - InactivityTimer.Reset(); + InactivityTimer.Reset(timeoutMs); } else { - InactivityTimer = new CTimer((o) => InactivityTimerExpired(), Config.ScreenSaverTimeoutMin * 60 * 1000); + InactivityTimer = new CTimer((o) => InactivityTimerExpired(), timeoutMs); } } } diff --git a/PepperDashEssentials/UIDrivers/ScreenSaverController.cs b/PepperDashEssentials/UIDrivers/ScreenSaverController.cs index ab903173..ed46ab25 100644 --- a/PepperDashEssentials/UIDrivers/ScreenSaverController.cs +++ b/PepperDashEssentials/UIDrivers/ScreenSaverController.cs @@ -20,7 +20,7 @@ namespace PepperDash.Essentials List PositionJoins; - int CurrentPositionIndex; + int CurrentPositionIndex = 0; public ScreenSaverController(EssentialsPanelMainInterfaceDriver parent, CrestronTouchpanelPropertiesConfig config) : base(parent.TriList) @@ -39,6 +39,8 @@ namespace PepperDash.Essentials { TriList.SetBool(UIBoolJoin.MCScreenSaverVisible, true); + CurrentPositionIndex = 0; + SetCurrentPosition(); StartPositionTimer(); base.Show(); @@ -64,13 +66,26 @@ namespace PepperDash.Essentials if (PositionTimer == null) { PositionTimer = new CTimer((o) => PositionTimerExpired(), PositionTimeoutMs); - SetCurrentPosition(); } + else + { + PositionTimer.Reset(PositionTimeoutMs); + } + } void PositionTimerExpired() { - if (CurrentPositionIndex <= PositionJoins.Count) + IncrementPositionIndex(); + + SetCurrentPosition(); + + StartPositionTimer(); + } + + void IncrementPositionIndex() + { + if (CurrentPositionIndex < PositionJoins.Count - 1) { CurrentPositionIndex++; } @@ -78,6 +93,8 @@ namespace PepperDash.Essentials { CurrentPositionIndex = 0; } + + Debug.Console(1, "ScreenSaver Position Timer Expired: Setting new position: {0}", CurrentPositionIndex); } // diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index 16551067..8dd917b8 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -194,28 +194,39 @@ namespace PepperDash.Essentials.UIDrivers.VC { string roomContactNumbers = ""; string roomPhoneNumber = ""; + string roomVideoAddress = ""; + + + Debug.Console(1, + @" + Codec.CodecInfo.SipUri: {0} + Codec.CodecInfo.SipPhoneNumber: {1} + Codec.CodecInfo.Ei64Alias: {2} + Codec.CodecInfo.H323Id: {3} + ", Codec.CodecInfo.SipUri, Codec.CodecInfo.SipPhoneNumber, Codec.CodecInfo.E164Alias, Codec.CodecInfo.H323Id); if (!string.IsNullOrEmpty(Codec.CodecInfo.SipUri)) // If both values are present, format the string with a pipe divider { - roomContactNumbers = string.Format("{0} | {1}", GetFormattedPhoneNumber(Codec.CodecInfo.SipPhoneNumber), Codec.CodecInfo.SipUri); - roomPhoneNumber = GetFormattedPhoneNumber(Codec.CodecInfo.SipPhoneNumber); + roomPhoneNumber = Codec.CodecInfo.SipUri; } - else // If only one value present, just show the phone number + else if(!string.IsNullOrEmpty(Codec.CodecInfo.SipPhoneNumber)) // If only one value present, just show the phone number { roomPhoneNumber = GetFormattedPhoneNumber(Codec.CodecInfo.SipPhoneNumber); - roomContactNumbers = Codec.CodecInfo.SipPhoneNumber; } if (string.IsNullOrEmpty(roomContactNumbers)) { if(!string.IsNullOrEmpty(Codec.CodecInfo.E164Alias)) - roomContactNumbers = string.Format("{0} | {1}", Codec.CodecInfo.E164Alias, Codec.CodecInfo.H323Id); - else - roomContactNumbers = Codec.CodecInfo.H323Id; + roomVideoAddress = Codec.CodecInfo.E164Alias; + else if (!string.IsNullOrEmpty(Codec.CodecInfo.H323Id)) + roomVideoAddress = Codec.CodecInfo.H323Id; } + + roomContactNumbers = string.Format("{0} | {1}", roomPhoneNumber, roomVideoAddress); + TriList.SetString(UIStringJoin.RoomAddressPipeText, roomContactNumbers); TriList.SetString(UIStringJoin.RoomPhoneText, roomPhoneNumber); - TriList.SetString(UIStringJoin.RoomVideoAddressText, Codec.CodecInfo.H323Id); + TriList.SetString(UIStringJoin.RoomVideoAddressText, roomVideoAddress); if(HeaderDriver.HeaderButtonsAreSetUp) HeaderDriver.ComputeHeaderCallStatus(Codec); From ddbee2ed04636dfe8d3b077b65983d4fe9d4ff6a Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 7 Aug 2020 08:56:29 -0600 Subject: [PATCH 09/15] Fixed incorrect join for dark background logo. Updates CodecInfo class to correclty poppulate values --- PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs | 2 +- .../UIDrivers/VC/EssentialsVideoCodecUiDriver.cs | 2 +- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs index b7ce6b0b..ea60526b 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs @@ -212,7 +212,7 @@ namespace PepperDash.Essentials /// /// 3925 /// - public const uint LogoUrlDarkBkgnd = 3923; + public const uint LogoUrlDarkBkgnd = 3925; /// /// 3951 diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index 8dd917b8..ecde9277 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -201,7 +201,7 @@ namespace PepperDash.Essentials.UIDrivers.VC @" Codec.CodecInfo.SipUri: {0} Codec.CodecInfo.SipPhoneNumber: {1} - Codec.CodecInfo.Ei64Alias: {2} + Codec.CodecInfo.E164Alias: {2} Codec.CodecInfo.H323Id: {3} ", Codec.CodecInfo.SipUri, Codec.CodecInfo.SipPhoneNumber, Codec.CodecInfo.E164Alias, Codec.CodecInfo.H323Id); 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 802471b3..745af1a6 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 @@ -1699,7 +1699,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { get { - if (CodecConfiguration.Configuration.H323 != null && CodecConfiguration.Configuration.H323.H323Alias.E164 != null) + if (CodecConfiguration.Configuration.H323 != null && CodecConfiguration.Configuration.H323.H323Alias.ID != null) { return CodecConfiguration.Configuration.H323.H323Alias.ID.Value; } From dea858e187ac967eae61939e47f171e14670310f Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 7 Aug 2020 09:11:31 -0600 Subject: [PATCH 10/15] Updates to phone and video address logic --- .../VC/EssentialsVideoCodecUiDriver.cs | 48 +++++++++++++++---- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index ecde9277..2af64755 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -191,6 +191,14 @@ namespace PepperDash.Essentials.UIDrivers.VC /// /// void Codec_IsReady() + { + SetupAddresses(); + + if(HeaderDriver.HeaderButtonsAreSetUp) + HeaderDriver.ComputeHeaderCallStatus(Codec); + } + + void SetupAddresses() { string roomContactNumbers = ""; string roomPhoneNumber = ""; @@ -209,27 +217,47 @@ namespace PepperDash.Essentials.UIDrivers.VC { roomPhoneNumber = Codec.CodecInfo.SipUri; } - else if(!string.IsNullOrEmpty(Codec.CodecInfo.SipPhoneNumber)) // If only one value present, just show the phone number + + if (string.IsNullOrEmpty(roomPhoneNumber)) // If only one value present, just show the phone number { roomPhoneNumber = GetFormattedPhoneNumber(Codec.CodecInfo.SipPhoneNumber); } - if (string.IsNullOrEmpty(roomContactNumbers)) + if (!string.IsNullOrEmpty(Codec.CodecInfo.IpAddress)) { - if(!string.IsNullOrEmpty(Codec.CodecInfo.E164Alias)) - roomVideoAddress = Codec.CodecInfo.E164Alias; - else if (!string.IsNullOrEmpty(Codec.CodecInfo.H323Id)) - roomVideoAddress = Codec.CodecInfo.H323Id; + roomVideoAddress = Codec.CodecInfo.IpAddress; + } + else if (!string.IsNullOrEmpty(Codec.CodecInfo.E164Alias)) + { + roomVideoAddress = Codec.CodecInfo.E164Alias; + } + else if (!string.IsNullOrEmpty(Codec.CodecInfo.H323Id)) + { + roomVideoAddress = Codec.CodecInfo.H323Id; } - roomContactNumbers = string.Format("{0} | {1}", roomPhoneNumber, roomVideoAddress); + Debug.Console(1, + @" Room Contact Numbers: + Phone Number: {0} + Video Number: {1} + ", roomPhoneNumber, roomVideoAddress); + + if (!string.IsNullOrEmpty(roomPhoneNumber) && !string.IsNullOrEmpty(roomVideoAddress)) + { + roomContactNumbers = string.Format("{0} | {1}", roomPhoneNumber, roomVideoAddress); + } + else if (!string.IsNullOrEmpty(roomPhoneNumber)) + { + roomContactNumbers = roomPhoneNumber; + } + else if (!string.IsNullOrEmpty(roomVideoAddress)) + { + roomContactNumbers = roomVideoAddress; + } TriList.SetString(UIStringJoin.RoomAddressPipeText, roomContactNumbers); TriList.SetString(UIStringJoin.RoomPhoneText, roomPhoneNumber); TriList.SetString(UIStringJoin.RoomVideoAddressText, roomVideoAddress); - - if(HeaderDriver.HeaderButtonsAreSetUp) - HeaderDriver.ComputeHeaderCallStatus(Codec); } /// From 302603aa543fc5bc4ac933bdc63ebd78b9e39172 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 7 Aug 2020 09:29:55 -0600 Subject: [PATCH 11/15] Updates to phone and video address logic --- .../UIDrivers/VC/EssentialsVideoCodecUiDriver.cs | 16 +++++++++------- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 3 ++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index 2af64755..7e9ab2e6 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -207,22 +207,24 @@ namespace PepperDash.Essentials.UIDrivers.VC Debug.Console(1, @" - Codec.CodecInfo.SipUri: {0} - Codec.CodecInfo.SipPhoneNumber: {1} - Codec.CodecInfo.E164Alias: {2} - Codec.CodecInfo.H323Id: {3} - ", Codec.CodecInfo.SipUri, Codec.CodecInfo.SipPhoneNumber, Codec.CodecInfo.E164Alias, Codec.CodecInfo.H323Id); + Codec.CodecInfo.IpAddress: {0} + Codec.CodecInfo.SipUri: {1} + Codec.CodecInfo.SipPhoneNumber: {2} + Codec.CodecInfo.E164Alias: {3} + Codec.CodecInfo.H323Id: {4} + ", Codec.CodecInfo.IpAddress, Codec.CodecInfo.SipUri, Codec.CodecInfo.SipPhoneNumber, Codec.CodecInfo.E164Alias, Codec.CodecInfo.H323Id); + // Populate phone number if (!string.IsNullOrEmpty(Codec.CodecInfo.SipUri)) // If both values are present, format the string with a pipe divider { roomPhoneNumber = Codec.CodecInfo.SipUri; } - - if (string.IsNullOrEmpty(roomPhoneNumber)) // If only one value present, just show the phone number + else if (!string.IsNullOrEmpty(Codec.CodecInfo.SipPhoneNumber)) // If only one value present, just show the phone number { roomPhoneNumber = GetFormattedPhoneNumber(Codec.CodecInfo.SipPhoneNumber); } + // Populate video number if (!string.IsNullOrEmpty(Codec.CodecInfo.IpAddress)) { roomVideoAddress = Codec.CodecInfo.IpAddress; 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 745af1a6..b870fa78 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 @@ -1699,7 +1699,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { get { - if (CodecConfiguration.Configuration.H323 != null && CodecConfiguration.Configuration.H323.H323Alias.ID != null) + if (CodecConfiguration.Configuration.H323 != null && CodecConfiguration.Configuration.H323.H323Alias != null + && CodecConfiguration.Configuration.H323.H323Alias.ID != null) { return CodecConfiguration.Configuration.H323.H323Alias.ID.Value; } From aea6942a1f965542fb4e535049ec483d06cc9230 Mon Sep 17 00:00:00 2001 From: Jason Alborough Date: Fri, 14 Aug 2020 15:51:37 -0400 Subject: [PATCH 12/15] Update to support Cisco Codec External Sources using Essentials Room logic. Adds new interface for Codecs IHasExternalSourceSwitching Adds ability to set and clear External Sources in Cisco Spark device class Adds ability to send sources from the source list to the Cisco Spark in the "EssentialsHuddleVtc1Room" room [ ] still needs parsing when source is selected on the Cisco touch 10 --- .../EssentialsHuddleVtc1FusionController.cs | 666 +++++++++--------- .../Room/Types/EssentialsHuddleVtc1Room.cs | 51 +- ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 7 +- .../Room/EssentialsRoomBase.cs | 14 +- .../Codec/IHasExternalSourceSwitching.cs | 17 + .../Essentials Devices Common.csproj | 1 + .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 70 +- .../CiscoSparkCodecPropertiesConfig.cs | 95 +-- 8 files changed, 533 insertions(+), 388 deletions(-) create mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs diff --git a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs index 4b0ef2b2..4159212c 100644 --- a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs +++ b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs @@ -2,340 +2,340 @@ using System.Linq; using Crestron.SimplSharp; using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.Fusion; - - +using Crestron.SimplSharpPro.Fusion; + + using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Fusion; -namespace PepperDash.Essentials.Fusion -{ - public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase - { - BooleanSigData CodecIsInCall; - - public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId) - : base(room, ipId) - { - - } - - /// - /// Called in base class constructor before RVI and GUID files are built - /// - protected override void ExecuteCustomSteps() - { - SetUpCodec(); - } - - /// - /// Creates a static asset for the codec and maps the joins to the main room symbol - /// - void SetUpCodec() - { - try - { - var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec; - - if (codec == null) - { - Debug.Console(1, this, "Cannot link codec to Fusion because codec is null"); - return; - } - - codec.UsageTracker = new UsageTracking(codec); - codec.UsageTracker.UsageIsTracked = true; - codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded; - - var codecPowerOnAction = new Action(b => { if (!b) codec.StandbyDeactivate(); }); - var codecPowerOffAction = new Action(b => { if (!b) codec.StandbyActivate(); }); - - // Map FusionRoom Attributes: - - // Codec volume - var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig); - codecVolume.OutputSig.UserObject = new Action(b => (codec as IBasicVolumeWithFeedback).SetVolume(b)); - (codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig); - - // In Call Status - CodecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly); - codec.CallStatusChange += new EventHandler(codec_CallStatusChange); - - // Online status - if (codec is ICommunicationMonitor) - { - var c = codec as ICommunicationMonitor; - var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly); - codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk; - c.CommunicationMonitor.StatusChange += (o, a) => - { - codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; - }; - Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, "Online - VC 1"); - } - - // Codec IP Address - bool codecHasIpInfo = false; - var codecComm = codec.Communication; - - string codecIpAddress = string.Empty; - int codecIpPort = 0; - - StringSigData codecIpAddressSig; - StringSigData codecIpPortSig; - - if(codecComm is GenericSshClient) - { - codecIpAddress = (codecComm as GenericSshClient).Hostname; - codecIpPort = (codecComm as GenericSshClient).Port; - codecHasIpInfo = true; - } - else if (codecComm is GenericTcpIpClient) - { - codecIpAddress = (codecComm as GenericTcpIpClient).Hostname; - codecIpPort = (codecComm as GenericTcpIpClient).Port; - codecHasIpInfo = true; - } - - if (codecHasIpInfo) - { - codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC", eSigIoMask.InputSigOnly); - codecIpAddressSig.InputSig.StringValue = codecIpAddress; - - codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC", eSigIoMask.InputSigOnly); - codecIpPortSig.InputSig.StringValue = codecIpPort.ToString(); - } - - var tempAsset = new FusionAsset(); - - var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key)); - - if (FusionStaticAssets.ContainsKey(deviceConfig.Uid)) - { - tempAsset = FusionStaticAssets[deviceConfig.Uid]; - } - else - { - // Create a new asset - tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name, "Codec", ""); - FusionStaticAssets.Add(deviceConfig.Uid, tempAsset); - } - - var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId); - codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction; - codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction; - codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig); - - // TODO: Map relevant attributes on asset symbol - - codecAsset.TrySetMakeModel(codec); - codecAsset.TryLinkAssetErrorToCommunication(codec); - } - catch (Exception e) - { - Debug.Console(1, this, "Error setting up codec in Fusion: {0}", e); - } - } - - void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e) - { - var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec; - - CodecIsInCall.InputSig.BoolValue = codec.IsInCall; - } - - // These methods are overridden because they access the room class which is of a different type - - protected override void CreateSymbolAndBasicSigs(uint ipId) - { - Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid); - - FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid); - FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use(); - FusionRoom.ExtenderFusionRoomDataReservedSigs.Use(); - - FusionRoom.Register(); - - FusionRoom.FusionStateChange += FusionRoom_FusionStateChange; - - FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += FusionRoomSchedule_DeviceExtenderSigChange; - FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange; - FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange; - - CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator); - CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator); - CrestronConsole.AddNewConsoleCommand(CreateAsHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator); - - // Room to fusion room - Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); - - // Moved to - CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", eSigIoMask.InputSigOnly); - // Don't think we need to get current status of this as nothing should be alive yet. - (Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange; - - - FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource); - FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey)); - // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig); - - - CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler; - } - - protected override void SetUpSources() - { - // Sources - var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleVtc1Room).SourceListKey); - if (dict != null) - { - // NEW PROCESS: - // Make these lists and insert the fusion attributes by iterating these - var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls); - uint i = 1; - foreach (var kvp in setTopBoxes) - { - TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice); - i++; - if (i > 5) // We only have five spots - break; - } - - var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls); - i = 1; - foreach (var kvp in discPlayers) - { - TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice); - i++; - if (i > 5) // We only have five spots - break; - } - - var laptops = dict.Where(d => d.Value.SourceDevice is Core.Devices.Laptop); - i = 1; - foreach (var kvp in laptops) - { - TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice); - i++; - if (i > 10) // We only have ten spots??? - break; - } - - foreach (var kvp in dict) - { - var usageDevice = kvp.Value.SourceDevice as IUsageTracking; - - if (usageDevice != null) - { - usageDevice.UsageTracker = new UsageTracking(usageDevice as Device); - usageDevice.UsageTracker.UsageIsTracked = true; - usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler(UsageTracker_DeviceUsageEnded); - } - } - - } - else - { - Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'", - (Room as EssentialsHuddleVtc1Room).SourceListKey, Room.Key); - } - } - - protected override void SetUpDisplay() - { - try - { - //Setup Display Usage Monitoring - - var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase); - - // Consider updating this in multiple display systems - - foreach (DisplayBase display in displays) - { - display.UsageTracker = new UsageTracking(display); - display.UsageTracker.UsageIsTracked = true; - display.UsageTracker.DeviceUsageEnded += new EventHandler(UsageTracker_DeviceUsageEnded); - } - - var defaultDisplay = (Room as EssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase; - if (defaultDisplay == null) - { - Debug.Console(1, this, "Cannot link null display to Fusion because default display is null"); - return; - } - - var dispPowerOnAction = new Action(b => { if (!b) defaultDisplay.PowerOn(); }); - var dispPowerOffAction = new Action(b => { if (!b) defaultDisplay.PowerOff(); }); - - // Display to fusion room sigs - FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction; - FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction; - defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig); - if (defaultDisplay is IDisplayUsage) - (defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig); - - - - MapDisplayToRoomJoins(1, 158, defaultDisplay); - - - var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key)); - - //Check for existing asset in GUIDs collection - - var tempAsset = new FusionAsset(); - - if (FusionStaticAssets.ContainsKey(deviceConfig.Uid)) - { - tempAsset = FusionStaticAssets[deviceConfig.Uid]; - } - else - { - // Create a new asset - tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), defaultDisplay.Name, "Display", ""); - FusionStaticAssets.Add(deviceConfig.Uid, tempAsset); - } - - var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId); - dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction; - dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction; - defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig); - // NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig); - // Use extension methods - dispAsset.TrySetMakeModel(defaultDisplay); - dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay); - } - catch (Exception e) - { - Debug.Console(1, this, "Error setting up display in Fusion: {0}", e); - } - - } - - protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display) - { - string displayName = string.Format("Display {0} - ", displayIndex); - - - if (display == (Room as EssentialsHuddleVtc1Room).DefaultDisplay) - { - // Power on - var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig); - defaultDisplayPowerOn.OutputSig.UserObject = new Action(b => { if (!b) display.PowerOn(); }); - display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig); - - // Power Off - var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig); - defaultDisplayPowerOn.OutputSig.UserObject = new Action(b => { if (!b) display.PowerOff(); }); ; - display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig); - - // 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", Room.SourceListKey); }); ; - } - } - } +namespace PepperDash.Essentials.Fusion +{ + public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase + { + BooleanSigData CodecIsInCall; + + public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId) + : base(room, ipId) + { + + } + + /// + /// Called in base class constructor before RVI and GUID files are built + /// + protected override void ExecuteCustomSteps() + { + SetUpCodec(); + } + + /// + /// Creates a static asset for the codec and maps the joins to the main room symbol + /// + void SetUpCodec() + { + try + { + var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec; + + if (codec == null) + { + Debug.Console(1, this, "Cannot link codec to Fusion because codec is null"); + return; + } + + codec.UsageTracker = new UsageTracking(codec); + codec.UsageTracker.UsageIsTracked = true; + codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded; + + var codecPowerOnAction = new Action(b => { if (!b) codec.StandbyDeactivate(); }); + var codecPowerOffAction = new Action(b => { if (!b) codec.StandbyActivate(); }); + + // Map FusionRoom Attributes: + + // Codec volume + var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig); + codecVolume.OutputSig.UserObject = new Action(b => (codec as IBasicVolumeWithFeedback).SetVolume(b)); + (codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig); + + // In Call Status + CodecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly); + codec.CallStatusChange += new EventHandler(codec_CallStatusChange); + + // Online status + if (codec is ICommunicationMonitor) + { + var c = codec as ICommunicationMonitor; + var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly); + codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk; + c.CommunicationMonitor.StatusChange += (o, a) => + { + codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; + }; + Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, "Online - VC 1"); + } + + // Codec IP Address + bool codecHasIpInfo = false; + var codecComm = codec.Communication; + + string codecIpAddress = string.Empty; + int codecIpPort = 0; + + StringSigData codecIpAddressSig; + StringSigData codecIpPortSig; + + if(codecComm is GenericSshClient) + { + codecIpAddress = (codecComm as GenericSshClient).Hostname; + codecIpPort = (codecComm as GenericSshClient).Port; + codecHasIpInfo = true; + } + else if (codecComm is GenericTcpIpClient) + { + codecIpAddress = (codecComm as GenericTcpIpClient).Hostname; + codecIpPort = (codecComm as GenericTcpIpClient).Port; + codecHasIpInfo = true; + } + + if (codecHasIpInfo) + { + codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC", eSigIoMask.InputSigOnly); + codecIpAddressSig.InputSig.StringValue = codecIpAddress; + + codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC", eSigIoMask.InputSigOnly); + codecIpPortSig.InputSig.StringValue = codecIpPort.ToString(); + } + + var tempAsset = new FusionAsset(); + + var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key)); + + if (FusionStaticAssets.ContainsKey(deviceConfig.Uid)) + { + tempAsset = FusionStaticAssets[deviceConfig.Uid]; + } + else + { + // Create a new asset + tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name, "Codec", ""); + FusionStaticAssets.Add(deviceConfig.Uid, tempAsset); + } + + var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId); + codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction; + codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction; + codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig); + + // TODO: Map relevant attributes on asset symbol + + codecAsset.TrySetMakeModel(codec); + codecAsset.TryLinkAssetErrorToCommunication(codec); + } + catch (Exception e) + { + Debug.Console(1, this, "Error setting up codec in Fusion: {0}", e); + } + } + + void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e) + { + var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec; + + CodecIsInCall.InputSig.BoolValue = codec.IsInCall; + } + + // These methods are overridden because they access the room class which is of a different type + + protected override void CreateSymbolAndBasicSigs(uint ipId) + { + Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid); + + FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid); + FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use(); + FusionRoom.ExtenderFusionRoomDataReservedSigs.Use(); + + FusionRoom.Register(); + + FusionRoom.FusionStateChange += FusionRoom_FusionStateChange; + + FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += FusionRoomSchedule_DeviceExtenderSigChange; + FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange; + FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange; + + CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator); + CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator); + CrestronConsole.AddNewConsoleCommand(CreateAsHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator); + + // Room to fusion room + Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); + + // Moved to + CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", eSigIoMask.InputSigOnly); + // Don't think we need to get current status of this as nothing should be alive yet. + (Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange; + + + FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource); + FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey)); + // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig); + + + CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler; + } + + protected override void SetUpSources() + { + // Sources + var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleVtc1Room).SourceListKey); + if (dict != null) + { + // NEW PROCESS: + // Make these lists and insert the fusion attributes by iterating these + var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls); + uint i = 1; + foreach (var kvp in setTopBoxes) + { + TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice); + i++; + if (i > 5) // We only have five spots + break; + } + + var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls); + i = 1; + foreach (var kvp in discPlayers) + { + TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice); + i++; + if (i > 5) // We only have five spots + break; + } + + var laptops = dict.Where(d => d.Value.SourceDevice is Core.Devices.Laptop); + i = 1; + foreach (var kvp in laptops) + { + TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice); + i++; + if (i > 10) // We only have ten spots??? + break; + } + + foreach (var kvp in dict) + { + var usageDevice = kvp.Value.SourceDevice as IUsageTracking; + + if (usageDevice != null) + { + usageDevice.UsageTracker = new UsageTracking(usageDevice as Device); + usageDevice.UsageTracker.UsageIsTracked = true; + usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler(UsageTracker_DeviceUsageEnded); + } + } + + } + else + { + Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'", + (Room as EssentialsHuddleVtc1Room).SourceListKey, Room.Key); + } + } + + protected override void SetUpDisplay() + { + try + { + //Setup Display Usage Monitoring + + var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase); + + // Consider updating this in multiple display systems + + foreach (DisplayBase display in displays) + { + display.UsageTracker = new UsageTracking(display); + display.UsageTracker.UsageIsTracked = true; + display.UsageTracker.DeviceUsageEnded += new EventHandler(UsageTracker_DeviceUsageEnded); + } + + var defaultDisplay = (Room as EssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase; + if (defaultDisplay == null) + { + Debug.Console(1, this, "Cannot link null display to Fusion because default display is null"); + return; + } + + var dispPowerOnAction = new Action(b => { if (!b) defaultDisplay.PowerOn(); }); + var dispPowerOffAction = new Action(b => { if (!b) defaultDisplay.PowerOff(); }); + + // Display to fusion room sigs + FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction; + FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction; + defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig); + if (defaultDisplay is IDisplayUsage) + (defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig); + + + + MapDisplayToRoomJoins(1, 158, defaultDisplay); + + + var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key)); + + //Check for existing asset in GUIDs collection + + var tempAsset = new FusionAsset(); + + if (FusionStaticAssets.ContainsKey(deviceConfig.Uid)) + { + tempAsset = FusionStaticAssets[deviceConfig.Uid]; + } + else + { + // Create a new asset + tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), defaultDisplay.Name, "Display", ""); + FusionStaticAssets.Add(deviceConfig.Uid, tempAsset); + } + + var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId); + dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction; + dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction; + defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig); + // NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig); + // Use extension methods + dispAsset.TrySetMakeModel(defaultDisplay); + dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay); + } + catch (Exception e) + { + Debug.Console(1, this, "Error setting up display in Fusion: {0}", e); + } + + } + + protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display) + { + string displayName = string.Format("Display {0} - ", displayIndex); + + + if (display == (Room as EssentialsHuddleVtc1Room).DefaultDisplay) + { + // Power on + var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig); + defaultDisplayPowerOn.OutputSig.UserObject = new Action(b => { if (!b) display.PowerOn(); }); + display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig); + + // Power Off + var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig); + defaultDisplayPowerOn.OutputSig.UserObject = new Action(b => { if (!b) display.PowerOff(); }); ; + display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig); + + // 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", Room.SourceListKey); }); ; + } + } + } } \ No newline at end of file diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index 1440b82f..06ad71cd 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -50,6 +50,24 @@ namespace PepperDash.Essentials //************************ + public override string SourceListKey + { + get + { + return _SourceListKey; + } + set + { + _SourceListKey = value; + if(VideoCodec is IHasExternalSourceSwitching) + { + if((VideoCodec as IHasExternalSourceSwitching).ExternalSourceListEnabled) + { + SetCodecExternalSources(); + } + } + } + } protected override Func OnFeedbackFunc { @@ -206,9 +224,14 @@ namespace PepperDash.Essentials VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase; + + if (VideoCodec == null) throw new ArgumentNullException("codec cannot be null"); + + //todo Do the thing here JTA + AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase; if (AudioCodec == null) @@ -298,6 +321,7 @@ namespace PepperDash.Essentials VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate(); + VideoCodec.IsReadyChange += (o, a) => this.SetCodecExternalSources(); if (AudioCodec != null) AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate(); @@ -346,11 +370,10 @@ namespace PepperDash.Essentials this.SourceListKey = PropertiesConfig.SourceListKey; this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem; this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100); - + return base.CustomActivate(); } - /// /// /// @@ -672,6 +695,30 @@ namespace PepperDash.Essentials (room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff"); } + private void SetCodecExternalSources() + { + + string codecTieLine = ""; + codecTieLine = ConfigReader.ConfigObject.TieLines.SingleOrDefault(x => x.DestinationKey == VideoCodec.Key).DestinationPort; + (VideoCodec as IHasExternalSourceSwitching).ClearExternalSources(); + (VideoCodec as IHasExternalSourceSwitching).RunRouteAction = RunRouteAction; + var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order);; + + foreach (var kvp in srcList) + { + var srcConfig = kvp.Value; + Debug.Console(1, "**** KEY {0}", kvp.Key); + + if (kvp.Key != "codecOsd" && kvp.Key != "roomOff") + { + + (VideoCodec as IHasExternalSourceSwitching).AddExternalSource(codecTieLine, srcConfig.PreferredName); + + } + } + } + + #region IPrivacy Members diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index c74fd8e0..5a99f6e4 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -1047,12 +1047,15 @@ namespace PepperDash.Essentials /// void SetupSourceList() { - + var inCall = CurrentRoom.InCallFeedback.BoolValue; var config = ConfigReader.ConfigObject.SourceLists; + + if (config.ContainsKey(_CurrentRoom.SourceListKey)) { var srcList = config[_CurrentRoom.SourceListKey].OrderBy(kv => kv.Value.Order); + // Setup sources list SourceStagingSrl.Clear(); @@ -1076,6 +1079,8 @@ namespace PepperDash.Essentials b => { if (!b) UiSelectSource(routeKey); }); SourceStagingSrl.AddItem(item); // add to the SRL item.RegisterForSourceChange(_CurrentRoom); + Debug.Console(1, "**** KEY {0}", kvp.Key); + } SourceStagingSrl.Count = (ushort)(i - 1); } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs index 624d072f..4cf36470 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs @@ -51,7 +51,19 @@ namespace PepperDash.Essentials.Core /// /// The config name of the source list /// - public string SourceListKey { get; set; } + /// + protected string _SourceListKey; + public virtual string SourceListKey { + get + { + return _SourceListKey; + } + set + { + _SourceListKey = value; + + } + } /// /// Timer used for informing the UIs of a shutdown diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs new file mode 100644 index 00000000..1870e756 --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; +namespace PepperDash.Essentials.Devices.Common.Codec +{ + public interface IHasExternalSourceSwitching + { + bool ExternalSourceListEnabled { get; } + void AddExternalSource(string connectorId, string name); + void ClearExternalSources(); + Action RunRouteAction { set;} + } + +} \ 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 e33e54fd..6055f9ab 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 @@ -112,6 +112,7 @@ + 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 b870fa78..b90ab896 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 @@ -15,16 +15,16 @@ using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Routing; using PepperDash.Essentials.Devices.Common.Cameras; using PepperDash.Essentials.Devices.Common.Codec; -using PepperDash.Essentials.Core; using PepperDash.Essentials.Devices.Common.VideoCodec; namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration }; + public enum eExternalSourceType {camera, desktop, document_camera, mediaplayer, PC, whiteboard, other} public class CiscoSparkCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectory, IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfView, - ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets + ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets, IHasExternalSourceSwitching { public event EventHandler DirectoryResultReturned; @@ -348,6 +348,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CallHistory = new CodecCallHistory(); + if (props.Favorites != null) { CallFavorites = new CodecCallFavorites(); @@ -398,6 +399,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco SetUpCameras(); CreateOsdSource(); + + if (props.ExternalSourceListEnabled != null) + { + ExternalSourceListEnabled = props.ExternalSourceListEnabled; + } } /// @@ -472,7 +478,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco prefix + "/Bookings" + Delimiter + prefix + "/Event/CallDisconnect" + Delimiter + prefix + "/Event/Bookings" + Delimiter + - prefix + "/Event/CameraPresetListUpdated" + Delimiter; + prefix + "/Event/CameraPresetListUpdated" + Delimiter + + prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter; return base.CustomActivate(); } @@ -629,6 +636,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } } } + //TODO JTA FInish Parsing for External Sources + if (args.Text == "ExternalSource") + { + RunRouteAction("", ""); + } } @@ -1802,9 +1814,57 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco SendText(string.Format("xCommand Call FarEndControl RoomPreset Activate CallId: {0} PresetId: {1}", GetCallId(), preset)); } - } - /// + #region IHasExternalSourceSwitching Members + + /// + /// + /// + public bool ExternalSourceListEnabled + { + get; + private set; + } + + public void AddExternalSource(string connectorId, string name) + { + int id = 2; + if (connectorId.ToLower() == "hdmiin3") + { + id = 3; + } + SendText(string.Format("xCommand UserInterface Presentation ExternalSource Add ConnectorId: {0} SourceIdentifier: \"{1}\" Name: \"{2}\" Type: desktop", id, name, name)); + Debug.Console(2, this, "Adding ExternalSource {0} {1}", connectorId, name); + + } + + /// + /// + /// + public void ClearExternalSources() + { + SendText("xCommand UserInterface Presentation ExternalSource RemoveAll"); + + } + + + public Action RunRouteAction { private get; set; } + + + + + + + #endregion + #region ExternalDevices + + + + #endregion + } + + + /// /// Represents a codec command that might need to have a friendly label applied for UI feedback purposes /// public class CodecCommandWithLabel diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodecPropertiesConfig.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodecPropertiesConfig.cs index 521b9e5c..2f335780 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodecPropertiesConfig.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodecPropertiesConfig.cs @@ -1,47 +1,50 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Core; -using PepperDash.Essentials.Core; - -using Newtonsoft.Json; - -namespace PepperDash.Essentials.Devices.Common.Codec -{ - public class CiscoSparkCodecPropertiesConfig - { - [JsonProperty("communicationMonitorProperties")] - public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; } - - [JsonProperty("favorites")] - public List Favorites { get; set; } - - /// - /// Valid values: "Local" or "Corporate" - /// - [JsonProperty("phonebookMode")] - public string PhonebookMode { get; set; } - - [JsonProperty("showSelfViewByDefault")] - public bool ShowSelfViewByDefault { get; set; } - - [JsonProperty("sharing")] - public SharingProperties Sharing { get; set; } - - /// - /// Optionsal property to set the limit of any phonebook queries for directory or searching - /// - [JsonProperty("phonebookResultsLimit")] - public uint PhonebookResultsLimit { get; set; } - - } - - public class SharingProperties - { - [JsonProperty("autoShareContentWhileInCall")] - public bool AutoShareContentWhileInCall { get; set; } - } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Core; +using PepperDash.Essentials.Core; + +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + public class CiscoSparkCodecPropertiesConfig + { + [JsonProperty("communicationMonitorProperties")] + public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; } + + [JsonProperty("favorites")] + public List Favorites { get; set; } + + /// + /// Valid values: "Local" or "Corporate" + /// + [JsonProperty("phonebookMode")] + public string PhonebookMode { get; set; } + + [JsonProperty("showSelfViewByDefault")] + public bool ShowSelfViewByDefault { get; set; } + + [JsonProperty("sharing")] + public SharingProperties Sharing { get; set; } + + [JsonProperty("externalSourceListEnabled")] + public bool ExternalSourceListEnabled { get; set; } + + /// + /// Optionsal property to set the limit of any phonebook queries for directory or searching + /// + [JsonProperty("phonebookResultsLimit")] + public uint PhonebookResultsLimit { get; set; } + + } + + public class SharingProperties + { + [JsonProperty("autoShareContentWhileInCall")] + public bool AutoShareContentWhileInCall { get; set; } + } } \ No newline at end of file From f0d10fb1f962f0ab3cdb8351781b55fcc4d153b7 Mon Sep 17 00:00:00 2001 From: Jason Alborough Date: Mon, 17 Aug 2020 14:52:49 -0400 Subject: [PATCH 13/15] Finalized IHasExternalSourceSwitching adding method for setting the ExternalSource State Adds arguments for External Source type it the AddExternalSource() Adds subscription and parsing for External Source events --- .../Room/Types/EssentialsHuddleVtc1Room.cs | 9 +- .../Devices/IrOutputPortController.cs | 240 +++++++++--------- .../Codec/IHasExternalSourceSwitching.cs | 5 +- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 44 +++- .../VideoCodec/CiscoCodec/xEvent.cs | 31 ++- 5 files changed, 193 insertions(+), 136 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index 06ad71cd..0c048ed1 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -695,6 +695,10 @@ namespace PepperDash.Essentials (room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff"); } + + /// + /// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch + /// private void SetCodecExternalSources() { @@ -707,12 +711,13 @@ namespace PepperDash.Essentials foreach (var kvp in srcList) { var srcConfig = kvp.Value; - Debug.Console(1, "**** KEY {0}", kvp.Key); if (kvp.Key != "codecOsd" && kvp.Key != "roomOff") { - (VideoCodec as IHasExternalSourceSwitching).AddExternalSource(codecTieLine, srcConfig.PreferredName); + (VideoCodec as IHasExternalSourceSwitching).AddExternalSource(codecTieLine, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop); + (VideoCodec as IHasExternalSourceSwitching).SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready); + } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IrOutputPortController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IrOutputPortController.cs index ecfca4f8..83241e79 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IrOutputPortController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IrOutputPortController.cs @@ -1,45 +1,45 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; +using System; +using System.Collections.Generic; +using System.Linq; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Newtonsoft.Json.Linq; -using PepperDash.Essentials.Core.Config; - - -using PepperDash.Core; - -namespace PepperDash.Essentials.Core -{ - - /// - /// IR port wrapper. May act standalone - /// - public class IrOutputPortController : Device - { - uint IrPortUid; - IROutputPort IrPort; - - public ushort StandardIrPulseTime { get; set; } - public string DriverFilepath { get; private set; } - public bool DriverIsLoaded { get; private set; } - - /// - /// Constructor for IrDevice base class. If a null port is provided, this class will - /// still function without trying to talk to a port. - /// - public IrOutputPortController(string key, IROutputPort port, string irDriverFilepath) - : base(key) - { - //if (port == null) throw new ArgumentNullException("port"); - IrPort = port; - if (port == null) - { - Debug.Console(0, this, "WARNING No valid IR Port assigned to controller. IR will not function"); - return; - } - LoadDriver(irDriverFilepath); +using PepperDash.Essentials.Core.Config; + + +using PepperDash.Core; + +namespace PepperDash.Essentials.Core +{ + + /// + /// IR port wrapper. May act standalone + /// + public class IrOutputPortController : Device + { + uint IrPortUid; + IROutputPort IrPort; + + public ushort StandardIrPulseTime { get; set; } + public string DriverFilepath { get; private set; } + public bool DriverIsLoaded { get; private set; } + + /// + /// Constructor for IrDevice base class. If a null port is provided, this class will + /// still function without trying to talk to a port. + /// + public IrOutputPortController(string key, IROutputPort port, string irDriverFilepath) + : base(key) + { + //if (port == null) throw new ArgumentNullException("port"); + IrPort = port; + if (port == null) + { + Debug.Console(0, this, "WARNING No valid IR Port assigned to controller. IR will not function"); + return; + } + LoadDriver(irDriverFilepath); } public IrOutputPortController(string key, Func postActivationFunc, @@ -54,85 +54,85 @@ namespace PepperDash.Essentials.Core - /// - /// Loads the IR driver at path - /// - /// - public void LoadDriver(string path) - { - if (string.IsNullOrEmpty(path)) path = DriverFilepath; - try - { - IrPortUid = IrPort.LoadIRDriver(path); - DriverFilepath = path; - StandardIrPulseTime = 200; - DriverIsLoaded = true; - } - catch - { - DriverIsLoaded = false; - var message = string.Format("WARNING IR Driver '{0}' failed to load", path); - Debug.Console(0, this, message); - ErrorLog.Error(message); - } - } - - - /// - /// Starts and stops IR command on driver. Safe for missing commands - /// - public virtual void PressRelease(string command, bool state) - { - Debug.Console(2, this, "IR:'{0}'={1}", command, state); - if (IrPort == null) - { - Debug.Console(2, this, "WARNING No IR Port assigned to controller"); - return; - } - if (!DriverIsLoaded) - { - Debug.Console(2, this, "WARNING IR driver is not loaded"); - return; - } - if (state) - { - if (IrPort.IsIRCommandAvailable(IrPortUid, command)) - IrPort.Press(IrPortUid, command); - else - NoIrCommandError(command); - } - else - IrPort.Release(); - } - - /// - /// Pulses a command on driver. Safe for missing commands - /// - public virtual void Pulse(string command, ushort time) - { - if (IrPort == null) - { - Debug.Console(2, this, "WARNING No IR Port assigned to controller"); - return; - } - if (!DriverIsLoaded) - { - Debug.Console(2, this, "WARNING IR driver is not loaded"); - return; - } - if (IrPort.IsIRCommandAvailable(IrPortUid, command)) - IrPort.PressAndRelease(IrPortUid, command, time); - else - NoIrCommandError(command); - } - - /// - /// Notifies the console when a bad command is used. - /// - protected void NoIrCommandError(string command) - { - Debug.Console(2, this, "Device {0}: IR Driver {1} does not contain command {2}", - Key, IrPort.IRDriverFileNameByIRDriverId(IrPortUid), command); + /// + /// Loads the IR driver at path + /// + /// + public void LoadDriver(string path) + { + if (string.IsNullOrEmpty(path)) path = DriverFilepath; + try + { + IrPortUid = IrPort.LoadIRDriver(path); + DriverFilepath = path; + StandardIrPulseTime = 200; + DriverIsLoaded = true; + } + catch + { + DriverIsLoaded = false; + var message = string.Format("WARNING IR Driver '{0}' failed to load", path); + Debug.Console(0, this, message); + ErrorLog.Error(message); + } } - } + + + /// + /// Starts and stops IR command on driver. Safe for missing commands + /// + public virtual void PressRelease(string command, bool state) + { + Debug.Console(2, this, "IR:'{0}'={1}", command, state); + if (IrPort == null) + { + Debug.Console(2, this, "WARNING No IR Port assigned to controller"); + return; + } + if (!DriverIsLoaded) + { + Debug.Console(2, this, "WARNING IR driver is not loaded"); + return; + } + if (state) + { + if (IrPort.IsIRCommandAvailable(IrPortUid, command)) + IrPort.Press(IrPortUid, command); + else + NoIrCommandError(command); + } + else + IrPort.Release(); + } + + /// + /// Pulses a command on driver. Safe for missing commands + /// + public virtual void Pulse(string command, ushort time) + { + if (IrPort == null) + { + Debug.Console(2, this, "WARNING No IR Port assigned to controller"); + return; + } + if (!DriverIsLoaded) + { + Debug.Console(2, this, "WARNING IR driver is not loaded"); + return; + } + if (IrPort.IsIRCommandAvailable(IrPortUid, command)) + IrPort.PressAndRelease(IrPortUid, command, time); + else + NoIrCommandError(command); + } + + /// + /// Notifies the console when a bad command is used. + /// + protected void NoIrCommandError(string command) + { + Debug.Console(2, this, "Device {0}: IR Driver {1} does not contain command {2}", + Key, IrPort.IRDriverFileNameByIRDriverId(IrPortUid), command); + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs index 1870e756..d86f628e 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs @@ -4,12 +4,15 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco; + namespace PepperDash.Essentials.Devices.Common.Codec { public interface IHasExternalSourceSwitching { bool ExternalSourceListEnabled { get; } - void AddExternalSource(string connectorId, string name); + void AddExternalSource(string connectorId, string key, string name, eExternalSourceType type); + void SetExternalSourceState(string key, eExternalSourceMode mode); void ClearExternalSources(); Action RunRouteAction { set;} } 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 b90ab896..108aab0b 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 @@ -21,6 +21,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration }; public enum eExternalSourceType {camera, desktop, document_camera, mediaplayer, PC, whiteboard, other} + public enum eExternalSourceMode {Ready, NotReady, Hiddon, Error} public class CiscoSparkCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectory, IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfView, @@ -636,11 +637,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } } } - //TODO JTA FInish Parsing for External Sources - if (args.Text == "ExternalSource") - { - RunRouteAction("", ""); - } + } @@ -865,6 +862,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { GetBookings(null); } + + else if (response.IndexOf("\"UserInterface\":{") > -1 || response.IndexOf("\"UserInterface\": {") > -1) // External Source Trigger + { + CiscoCodecEvents.RootObject eventReceived = new CiscoCodecEvents.RootObject(); + JsonConvert.PopulateObject(response, eventReceived); + Debug.Console(2, this, "*** Got an External Source Selection {0} {1}", eventReceived, eventReceived.Event.UserInterface, eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value); + RunRouteAction(eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value, null); + } } else if (response.IndexOf("\"CommandResponse\":{") > -1 || response.IndexOf("\"CommandResponse\": {") > -1) { @@ -1818,7 +1823,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco #region IHasExternalSourceSwitching Members /// - /// + /// Weather the Cisco supports External Source Lists or not /// public bool ExternalSourceListEnabled { @@ -1826,20 +1831,37 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco private set; } - public void AddExternalSource(string connectorId, string name) + /// + /// Adds an external source to the Cisco + /// + /// + /// + /// + public void AddExternalSource(string connectorId, string key, string name, eExternalSourceType type) { int id = 2; if (connectorId.ToLower() == "hdmiin3") { id = 3; } - SendText(string.Format("xCommand UserInterface Presentation ExternalSource Add ConnectorId: {0} SourceIdentifier: \"{1}\" Name: \"{2}\" Type: desktop", id, name, name)); + SendText(string.Format("xCommand UserInterface Presentation ExternalSource Add ConnectorId: {0} SourceIdentifier: \"{1}\" Name: \"{2}\" Type: {3}", id, key, name, type.ToString())); + // SendText(string.Format("xCommand UserInterface Presentation ExternalSource State Set SourceIdentifier: \"{0}\" State: Ready", key)); Debug.Console(2, this, "Adding ExternalSource {0} {1}", connectorId, name); } + /// - /// + /// Sets the state of the External Source + /// + /// + /// + public void SetExternalSourceState(string key, eExternalSourceMode mode) + { + SendText(string.Format("xCommand UserInterface Presentation ExternalSource State Set SourceIdentifier: \"{0}\" State: {1}", key, mode.ToString())); + } + /// + /// Clears all external sources on the codec /// public void ClearExternalSources() { @@ -1847,7 +1869,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } - + /// + /// Action that will run when the External Source is selected. + /// public Action RunRouteAction { private get; set; } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xEvent.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xEvent.cs index 342a8848..23594ce2 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xEvent.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xEvent.cs @@ -126,11 +126,36 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public Encryption Encryption { get; set; } public RequestedURI RequestedURI { get; set; } public PeopleCountAverage PeopleCountAverage { get; set; } - } - + } + public class UserInterface + { + public string id { get; set; } + public Presentation Presentation { get; set; } + } + public class Presentation + { + public string id { get; set; } + public ExternalSource ExternalSource { get; set; } + } + public class ExternalSource + { + public string id { get; set; } + public Selected Selected { get; set; } + } + public class Selected + { + public string id { get; set; } + public SourceIdentifier SourceIdentifier { get; set; } + } + public class SourceIdentifier + { + public string id { get; set; } + public string Value { get; set; } + } public class Event { - public CallDisconnect CallDisconnect { get; set; } + public CallDisconnect CallDisconnect { get; set; } + public UserInterface UserInterface { get; set; } } public class RootObject From 4e2683f8fca462ddc0ff5a0ecb04fcb2fb8930f7 Mon Sep 17 00:00:00 2001 From: Jason Alborough Date: Mon, 17 Aug 2020 14:57:33 -0400 Subject: [PATCH 14/15] Removes ToDo's --- PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index 0c048ed1..99278b32 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -228,9 +228,6 @@ namespace PepperDash.Essentials if (VideoCodec == null) throw new ArgumentNullException("codec cannot be null"); - - - //todo Do the thing here JTA AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase; From 67f0ae92ef06860c6d4036862cfcff8b2b8e84f2 Mon Sep 17 00:00:00 2001 From: Jason Alborough Date: Tue, 18 Aug 2020 10:00:53 -0400 Subject: [PATCH 15/15] Adds null check before running RunRouteAction event in Cisco Spark class. Fixes spelling error and other minor cleanup. --- .../Room/Types/EssentialsHuddleVtc1Room.cs | 38 ++++++++++--------- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 8 +++- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index 99278b32..ca137a27 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -59,13 +59,8 @@ namespace PepperDash.Essentials set { _SourceListKey = value; - if(VideoCodec is IHasExternalSourceSwitching) - { - if((VideoCodec as IHasExternalSourceSwitching).ExternalSourceListEnabled) - { - SetCodecExternalSources(); - } - } + SetCodecExternalSources(); + } } @@ -698,28 +693,35 @@ namespace PepperDash.Essentials /// private void SetCodecExternalSources() { - - string codecTieLine = ""; - codecTieLine = ConfigReader.ConfigObject.TieLines.SingleOrDefault(x => x.DestinationKey == VideoCodec.Key).DestinationPort; - (VideoCodec as IHasExternalSourceSwitching).ClearExternalSources(); - (VideoCodec as IHasExternalSourceSwitching).RunRouteAction = RunRouteAction; - var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order);; + var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching; + + if (videoCodecWithExternalSwitching == null) + { + return; + } + else + { + string codecTieLine = ""; + codecTieLine = ConfigReader.ConfigObject.TieLines.SingleOrDefault(x => x.DestinationKey == VideoCodec.Key).DestinationPort; + videoCodecWithExternalSwitching.ClearExternalSources(); + videoCodecWithExternalSwitching.RunRouteAction = RunRouteAction; + var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ; foreach (var kvp in srcList) { var srcConfig = kvp.Value; - - if (kvp.Key != "codecOsd" && kvp.Key != "roomOff") + + if (kvp.Key != DefaultCodecRouteString && kvp.Key != "roomOff") { - (VideoCodec as IHasExternalSourceSwitching).AddExternalSource(codecTieLine, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop); - (VideoCodec as IHasExternalSourceSwitching).SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready); + videoCodecWithExternalSwitching.AddExternalSource(codecTieLine, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop); + videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready); } } } - + } #region IPrivacy Members 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 108aab0b..9759cfdd 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 @@ -21,7 +21,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration }; public enum eExternalSourceType {camera, desktop, document_camera, mediaplayer, PC, whiteboard, other} - public enum eExternalSourceMode {Ready, NotReady, Hiddon, Error} + public enum eExternalSourceMode {Ready, NotReady, Hidden, Error} public class CiscoSparkCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectory, IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfView, @@ -868,7 +868,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CiscoCodecEvents.RootObject eventReceived = new CiscoCodecEvents.RootObject(); JsonConvert.PopulateObject(response, eventReceived); Debug.Console(2, this, "*** Got an External Source Selection {0} {1}", eventReceived, eventReceived.Event.UserInterface, eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value); - RunRouteAction(eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value, null); + + if (RunRouteAction != null) + { + RunRouteAction(eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value, null); + } } } else if (response.IndexOf("\"CommandResponse\":{") > -1 || response.IndexOf("\"CommandResponse\": {") > -1)