From 9e6d6d273c55edf47713d20901a4fb27fa308eee Mon Sep 17 00:00:00 2001 From: Tobias Kurze Date: Thu, 26 Oct 2023 13:07:11 +0200 Subject: [PATCH] added comfort functions for audio channel mute control --- backend/recorder_adapters/extron_smp.py | 359 +++++++++++++++++++++--- 1 file changed, 318 insertions(+), 41 deletions(-) diff --git a/backend/recorder_adapters/extron_smp.py b/backend/recorder_adapters/extron_smp.py index b52a380..799c9c0 100644 --- a/backend/recorder_adapters/extron_smp.py +++ b/backend/recorder_adapters/extron_smp.py @@ -34,6 +34,10 @@ class SMP35x(TelnetAdapter, RecorderAdapter): A class representing the Extron SMP recorder. """ + @classmethod + def get_recorder_params(cls) -> dict: + return {"_requires_user": False, "_requires_password": True} + S = TypeVar("S", bound=enum.IntEnum) def _get_number_from_enum( @@ -1478,7 +1482,7 @@ class SMP35x(TelnetAdapter, RecorderAdapter): Resets the layout preset to its default value. Args: - preset_number (Union[UserEncoderLayoutPresetNumber, int]): + preset_number (Union[UserEncoderLayoutPresetNumber, int]): The number of the preset to reset. Returns: @@ -1494,42 +1498,48 @@ class SMP35x(TelnetAdapter, RecorderAdapter): ### Picture adjustments skipped - def mute_output(self, output_number: int): + def mute_output(self, output_number: Union[OutputChannel, int]): """ - Output_number: - 1 = Channel A - 2 = Channel B - :param output_number: - :return: + Mutes the specified output channel on the Extron SMP device. + + Args: + output_number (Union[OutputChannel, int]): + The output channel to mute. This can be either an + OutputChannel enum value or an integer representing the channel number. + + Returns: + str: A response string from the device indicating + whether the mute command was successful. """ - if output_number not in range(1, 3): - raise LrcException("output_number must be a value between 1 and 2!") + output_number = self._get_number_from_enum(output_number, SMP35x.OutputChannel) self.tn.write(f"{output_number}*1B\n") return TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line()) - def unmute_output(self, output_number: int): + def unmute_output(self, output_number: Union[OutputChannel, int]): """ - Output_number: - 1 = Channel A - 2 = Channel B - :param output_number: - :return: + Unmute the specified output channel. + + Args: + output_number (Union[OutputChannel, int]): The output channel to unmute. + + Returns: + str: The response from the device. """ - if output_number not in range(1, 3): - raise LrcException("output_number must be a value between 1 and 2!") + output_number = self._get_number_from_enum(output_number, SMP35x.OutputChannel) self.tn.write(f"{output_number}*0B\n") return TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line()) - def is_muted(self, output_number: int): + def is_muted(self, output_number: Union[OutputChannel, int]) -> bool: """ - Output_number: - 1 = Channel A - 2 = Channel B - :param output_number: - :return: + Returns a boolean indicating whether the specified output channel is currently muted. + + Args: + output_number (Union[OutputChannel, int]): The output channel to check for muting. + + Returns: + bool: True if the output channel is muted, False otherwise. """ - if output_number not in range(1, 3): - raise LrcException("output_number must be a value between 1 and 2!") + output_number = self._get_number_from_enum(output_number, SMP35x.OutputChannel) self.tn.write(f"{output_number}B\n") return ( int(TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line())) @@ -1542,11 +1552,7 @@ class SMP35x(TelnetAdapter, RecorderAdapter): ### some advanced options skipped - @classmethod - def get_recorder_params(cls) -> dict: - return {"_requires_user": False, "_requires_password": True} - - def get_input_hdcp_status(self, input_number: int): + def get_input_hdcp_status(self, input_number: Union[InputNumber, int]): """ returns: 0 = no sink / source detected @@ -1555,68 +1561,272 @@ class SMP35x(TelnetAdapter, RecorderAdapter): :param input_number: from 1 to 5 :return: """ - if input_number not in range(1, 6): - raise LrcException("input_number must be a value between 1 and 6!") + input_number = self._get_number_from_enum(input_number, SMP35x.InputNumber) self.tn.write(f"{self.esc_char}I{input_number}HDCP\n") return TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line()) - def set_input_authorization_hdcp_on(self, input_number: int): - if input_number not in range(1, 6): - raise LrcException("input_number must be a value between 1 and 6!") + def set_input_authorization_hdcp_on(self, input_number: Union[InputNumber, int]): + """ + Sets the input authorization HDCP on for the specified input number. + + Args: + input_number (Union[InputNumber, int]): The input number to set the authorization HDCP on for. + + Returns: + str: The response string from the TelnetAdapter. + + Raises: + N/A + """ + input_number = self._get_number_from_enum(input_number, SMP35x.InputNumber) self.tn.write(f"{self.esc_char}E{input_number}*1HDCP\n") return TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line()) - def set_input_authorization_hdcp_off(self, input_number: int): - if input_number not in range(1, 6): - raise LrcException("input_number must be a value between 1 and 6!") + def set_input_authorization_hdcp_off(self, input_number: Union[InputNumber, int]): + """ + Sets the input authorization for the specified input number to HDCP off. + + Args: + input_number (Union[InputNumber, int]): The input number to set the authorization for. + + Returns: + str: The response string from the device. + """ + input_number = self._get_number_from_enum(input_number, SMP35x.InputNumber) self.tn.write(f"{self.esc_char}E{input_number}*0HDCP\n") return TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line()) - def get_input_authorization_hdcp_status(self, input_number: int): - if input_number not in range(1, 6): - raise LrcException("input_number must be a value between 1 and 6!") + def get_input_authorization_hdcp_status( + self, input_number: Union[InputNumber, int] + ): + """ + Gets the HDCP status for the specified input. + + Args: + input_number (Union[InputNumber, int]): The input number to get the HDCP status for. + + Returns: + str: The HDCP status of the input. + """ + input_number = self._get_number_from_enum(input_number, SMP35x.InputNumber) self.tn.write(f"{self.esc_char}E{input_number}HDCP\n") return TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line()) def enable_hdcp_notification(self): + """ + Enables HDCP notification on the Extron SMP device. + + Returns: + str: The response from the device. + """ self.tn.write(f"{self.esc_char}N1HDCP\n") return TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line()) def disable_hdcp_notification(self): + """ + Disables HDCP notification on the Extron SMP device. + + Returns: + str: The response from the device. + """ self.tn.write(f"{self.esc_char}N0HDCP\n") return TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line()) def get_hdcp_notification_status(self): + """ + Sends a command to the Extron SMP device to retrieve the current HDCP notification status. + + Returns: + str: The HDCP notification status response from the device. + """ self.tn.write(f"{self.esc_char}NHDCP\n") return TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line()) # background image settings + def set_background_image(self, filename: str): + """ + Sets the background image of the Extron SMP recorder to the specified file. + + Args: + filename (str): The filename of the image to set as the background. + + Returns: + str: The response from the recorder after setting the background image. + """ self.tn.write(f"{self.esc_char}{filename}RF\n") return TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line()) def get_background_image_filename(self): + """ + Sends a command to the Extron SMP device to retrieve the filename of the current background image. + + Returns: + str: The filename of the current background image. + """ self.tn.write(f"{self.esc_char}RF\n") return TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line()) def mute_background_image(self): + """ + Mutes the background image of the Extron SMP recorder. + + Returns: + str: The response from the recorder after muting the background image. + """ self.tn.write(f"{self.esc_char}0RF\n") return TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line()) # Audio settings def mute_audio_channel(self, channel_number: Union["SMP35x.AudioChannels", int]): + """ + Mutes the specified audio channel. + + Args: + channel_number (Union[SMP35x.AudioChannels, int]): + The audio channel to mute. This can be either an integer + representing the channel number (1-8), or a member of the SMP35x.AudioChannels enum. + + Returns: + str: The response from the device after muting the channel. + """ num = self._get_number_from_enum(channel_number, SMP35x.AudioChannels) self.tn.write(f"{self.esc_char}M{num}*1AU\n") return TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line()) + def mute_analog_audio_channel_a(self): + """ + Mutes both the left and right analog audio channels for input A. + + :return: The response from the device after muting the audio channels. + :rtype: str + """ + self.mute_audio_channel(SMP35x.AudioChannels.ANALOG_INPUT_A_LEFT) + self.mute_audio_channel(SMP35x.AudioChannels.ANALOG_INPUT_A_RIGHT) + + def mute_analog_audio_channel_b(self): + """ + Mutes both the left and right analog audio channels for input B. + + :return: The response from the device after muting the audio channels. + :rtype: str + """ + self.mute_audio_channel(SMP35x.AudioChannels.ANALOG_INPUT_B_LEFT) + self.mute_audio_channel(SMP35x.AudioChannels.ANALOG_INPUT_B_RIGHT) + + def mute_digital_audio_channel_a(self): + """ + Mutes both the left and right digital audio channels for input A. + + :return: The response from the device after muting the audio channels. + :rtype: str + """ + self.mute_audio_channel(SMP35x.AudioChannels.DIGITAL_INPUT_A_LEFT) + self.mute_audio_channel(SMP35x.AudioChannels.DIGITAL_INPUT_A_RIGHT) + + def mute_digital_audio_channel_b(self): + """ + Mutes both the left and right digital audio channels for input B. + + :return: The response from the device after muting the audio channels. + :rtype: str + """ + self.mute_audio_channel(SMP35x.AudioChannels.DIGITAL_INPUT_B_LEFT) + self.mute_audio_channel(SMP35x.AudioChannels.DIGITAL_INPUT_B_RIGHT) + + def mute_all_audio_channels(self): + """ + Mutes all audio channels on the Extron SMP device. + + :return: The response from the device after muting the audio channels. + :rtype: str + """ + self.mute_analog_audio_channel_a() + self.mute_analog_audio_channel_b() + self.mute_digital_audio_channel_a() + self.mute_digital_audio_channel_b() + def unmute_audio_channel(self, channel_number: Union["SMP35x.AudioChannels", int]): + """ + Unmute the specified audio channel. + + Args: + channel_number (Union[SMP35x.AudioChannels, int]): + The audio channel to unmute. This can be either an integer + representing the channel number, or a member of the SMP35x.AudioChannels enum. + + Returns: + str: The response from the device after sending the unmute command. + """ num = self._get_number_from_enum(channel_number, SMP35x.AudioChannels) self.tn.write(f"{self.esc_char}M{num}*0AU\n") return TelnetAdapter._get_response_str(self.tn.read_until_non_empty_line()) + def unmute_analog_audio_channel_a(self): + """ + Unmutes both the left and right analog audio channels for input A. + + :return: The response from the device after unmuting the audio channels. + :rtype: str + """ + self.unmute_audio_channel(SMP35x.AudioChannels.ANALOG_INPUT_A_LEFT) + self.unmute_audio_channel(SMP35x.AudioChannels.ANALOG_INPUT_A_RIGHT) + + def unmute_analog_audio_channel_b(self): + """ + Unmutes both the left and right analog audio channels for input B. + + :return: The response from the device after unmuting the audio channels. + :rtype: str + """ + self.unmute_audio_channel(SMP35x.AudioChannels.ANALOG_INPUT_B_LEFT) + self.unmute_audio_channel(SMP35x.AudioChannels.ANALOG_INPUT_B_RIGHT) + + def unmute_digital_audio_channel_a(self): + """ + Unmutes both the left and right digital audio channels for input A. + + :return: The response from the device after unmuting the audio channels. + :rtype: str + """ + self.unmute_audio_channel(SMP35x.AudioChannels.DIGITAL_INPUT_A_LEFT) + self.unmute_audio_channel(SMP35x.AudioChannels.DIGITAL_INPUT_A_RIGHT) + + def unmute_digital_audio_channel_b(self): + """ + Unmutes both the left and right digital audio channels for input B. + + :return: The response from the device after unmuting the audio channels. + :rtype: str + """ + self.unmute_audio_channel(SMP35x.AudioChannels.DIGITAL_INPUT_B_LEFT) + self.unmute_audio_channel(SMP35x.AudioChannels.DIGITAL_INPUT_B_RIGHT) + + def unmute_all_audio_channels(self): + """ + Unmutes all audio channels on the Extron SMP device. + + :return: The response from the device after unmuting the audio channels. + :rtype: str + """ + self.unmute_analog_audio_channel_a() + self.unmute_analog_audio_channel_b() + self.unmute_digital_audio_channel_a() + self.unmute_digital_audio_channel_b() + def is_audio_channel_muted( self, channel_number: Union["SMP35x.AudioChannels", int] ): + """ + Returns a boolean indicating whether the specified audio channel is currently muted. + + Args: + channel_number (Union[SMP35x.AudioChannels, int]): The audio channel number to check. + This can be either an integer value or a member of the SMP35x.AudioChannels enum. + + Returns: + bool: True if the audio channel is muted, False otherwise. + """ num = self._get_number_from_enum(channel_number, SMP35x.AudioChannels) self.tn.write(f"{self.esc_char}M{num}AU\n") return ( @@ -1624,6 +1834,73 @@ class SMP35x(TelnetAdapter, RecorderAdapter): > 0 ) + def is_analog_audio_channel_a_muted(self): + """ + Returns a boolean indicating whether both + the left and right analog audio channels for input A are muted. + + :return: A boolean indicating whether both the + left and right analog audio channels for input A are muted. + """ + analog_input_a_left = self.is_audio_channel_muted( + SMP35x.AudioChannels.ANALOG_INPUT_A_LEFT + ) + analog_input_a_right = self.is_audio_channel_muted( + SMP35x.AudioChannels.ANALOG_INPUT_A_RIGHT + ) + return analog_input_a_left and analog_input_a_right + + def is_analog_audio_channel_b_muted(self): + """ + Returns a boolean indicating whether both the + left and right channels of analog input B are muted. + + :return: A boolean indicating whether both the + left and right channels of analog input B are muted. + :rtype: bool + """ + analog_input_b_left = self.is_audio_channel_muted( + SMP35x.AudioChannels.ANALOG_INPUT_B_LEFT + ) + analog_input_b_right = self.is_audio_channel_muted( + SMP35x.AudioChannels.ANALOG_INPUT_B_RIGHT + ) + return analog_input_b_left and analog_input_b_right + + def is_digital_audio_channel_a_muted(self): + """ + Returns a boolean indicating whether both the + left and right channels of digital input A are muted. + + :return: A boolean indicating whether both the + left and right channels of digital input A are muted. + :rtype: bool + """ + digital_input_a_left = self.is_audio_channel_muted( + SMP35x.AudioChannels.DIGITAL_INPUT_A_LEFT + ) + digital_input_a_right = self.is_audio_channel_muted( + SMP35x.AudioChannels.DIGITAL_INPUT_A_RIGHT + ) + return digital_input_a_left and digital_input_a_right + + def is_digital_audio_channel_b_muted(self): + """ + Returns a boolean indicating whether both the + left and right channels of digital input B are muted. + + :return: A boolean indicating whether both the + left and right channels of digital input B are muted. + :rtype: bool + """ + digital_input_b_left = self.is_audio_channel_muted( + SMP35x.AudioChannels.DIGITAL_INPUT_B_LEFT + ) + digital_input_b_right = self.is_audio_channel_muted( + SMP35x.AudioChannels.DIGITAL_INPUT_B_RIGHT + ) + return digital_input_b_left and digital_input_b_right + def main(): smp = SMP35x(HOST, PW, True)