from UniTAP.libs.lib_tsi.tsi_io import PortIO from UniTAP.libs.lib_tsi.tsi import * from .cec_types import * from .cec_private_types import * from typing import Union class CecTx: def __init__(self, port_io: PortIO): self.__io = port_io self.__version = self.__read_version() self.__commands = [] @property def version(self) -> (int, int): """ Read CEC version from the TX side. Returns: object of tuple of `int` type """ return self.__version def enable(self, state: bool): """ Enable/Disable CEC. Args: state (`bool`) """ self.__io.set(TSI_HDTX_CEC_CONTROL, state, c_uint32) def is_enabled(self) -> bool: """ Return state of CEC (enabled or not). Returns: object of `bool` type """ return self.__io.get(TSI_HDTX_CEC_CONTROL, c_uint32)[1] & 0x1 == 1 @property def logical_address(self) -> LogicalAddressEnum: """ Set/Get CEC logical address. Returns: object of `LogicalAddressEnum` type """ return LogicalAddressEnum(self.__io.get(TSI_HDTX_CEC_LOGICAL_ADDRESS, c_uint32)[1]) @logical_address.setter def logical_address(self, address: LogicalAddressEnum): self.__io.set(TSI_HDTX_CEC_LOGICAL_ADDRESS, address.value, c_uint32) @property def destination(self) -> LogicalAddressEnum: """ Set/Get CEC destination address. Returns: object of `LogicalAddressEnum` type """ return LogicalAddressEnum(self.__io.get(TSI_HDTX_CEC_DESTINATION, c_uint32)[1]) @destination.setter def destination(self, address: LogicalAddressEnum): self.__io.set(TSI_HDTX_CEC_DESTINATION, address.value, c_uint32) @property def phy_address(self) -> int: """ Set/Get CEC physical address. Returns: object of `int` type """ return self.__io.get(TSI_HDTX_CEC_PHYSICAL_ADDRESS, c_uint32)[1] @phy_address.setter def phy_address(self, address: int): self.__io.set(TSI_HDTX_CEC_PHYSICAL_ADDRESS, address, c_uint32) @property def op_code(self) -> int: """ Set/Get CEC operation code. Returns: object of `int` type """ return self.__io.get(TSI_HDTX_CEC_OP_CODE, c_uint32)[1] @op_code.setter def op_code(self, code: int): self.__io.set(TSI_HDTX_CEC_OP_CODE, code, c_uint32) @property def op_code_param(self) -> Union[int, list]: """ Set/Get CEC additional parameter for operation code. Returns: object of `int` type """ return self.__io.get(TSI_HDTX_CEC_OP_CODE_PARAM, c_uint32)[1] @op_code_param.setter def op_code_param(self, code_param: Union[int, list]): data_count = len(code_param) if isinstance(code_param, list) else 1 self.__io.set(TSI_HDTX_CEC_OP_CODE_PARAM, code_param, c_uint32, data_count=data_count) @property def device_type(self) -> DeviceType: """ Set/Get CEC Device type. Returns: object of `DeviceType` type """ data = self.__io.get(TSI_HDTX_CEC_DEVICE_TYPE, DeviceTypePrivate)[1] return DeviceType(data.cecSwitch, data.audioSystem, data.pbDevice, data.tuner, data.recDev, data.tv) @device_type.setter def device_type(self, dev_type: Union[DeviceTypeEnum, DeviceType, int]): if isinstance(dev_type, DeviceType): dev_type_value = DeviceTypePrivate() dev_type_value.value = dev_type value = dev_type_value.value elif isinstance(dev_type, DeviceTypeEnum): value = dev_type.value elif isinstance(dev_type, int): value = dev_type & 0xFF else: raise TypeError(f"Unsupported type: {type(dev_type)}") self.__io.set(TSI_HDTX_CEC_DEVICE_TYPE, value, c_uint32) @property def status(self) -> CECStatus: """ Get CEC status. Returns: object of `CECStatus` type """ data = self.__io.get(TSI_HDTX_CEC_STATUS_R, CECStatusPrivate)[1] return CECStatus(data.bufferOverflowed) @property def command_number(self) -> int: """ Get CEC command number. Returns: object of `int` type """ return self.__io.get(TSI_HDTX_CEC_RECEIVED_CNT_R, c_uint32)[1] @property def data(self) -> list: """ Get CEC raw data. Returns: object of `list` type """ data_size = self.__io.get(TSI_HDTX_CEC_DATA_SIZE_R, c_uint32)[1] return self.__io.get(TSI_HDTX_CEC_DATA_RECEIVED_R, c_uint32, data_size)[1] def reset_data(self, command: CecResetDataCommand): """ Get CEC reset data. Returns: object of `CecResetDataCommand` type """ self.__io.set(TSI_HDTX_CEC_DATA_RESET_W, command.value, c_uint32) def __read_version(self) -> (int, int): version = self.__io.get(TSI_HDTX_CEC_VERSION_R, CECVersion)[1] return version.minor, version.major def add_command(self, command: CECCommand = CECCommand()): """ Add CEC command in list. Args: command (`CECCommand`) """ self.__commands.append(command) def delete_command(self, index: int = 0): """ Delete CEC command in list by index. Args: index (`int`) """ self.__commands.pop(index) def send_command(self, logical_address: LogicalAddressEnum = LogicalAddressEnum.Tv, destination: LogicalAddressEnum = LogicalAddressEnum.Broadcast, phy_address: int = 0x0, op_code: int = 0x0, op_code_param: Union[int, list] = 0x0, device_type: Union[DeviceTypeEnum, DeviceType, int] = DeviceTypeEnum.TV): """ Send CEC command with the transferred parameters. Args: logical_address (`LogicalAddressEnum`) destination (`LogicalAddressEnum`) phy_address (`int`) op_code (`int`) op_code_param (`int`) device_type (`DeviceTypeEnum` | `DeviceType`) """ self.enable(True) self.logical_address = logical_address self.phy_address = phy_address self.op_code = op_code self.op_code_param = op_code_param self.device_type = device_type self.destination = destination self.__send_cec_command() def send_command_by_index(self, index: int): """ Send CEC command from the list by index. Args: index (`int`) """ if len(self.__commands) > 0 and 0 <= index < len(self.__commands): self.__send_command(self.__commands[index]) def send_commands(self): """ Send all saved commands. """ for command in self.__commands: self.__send_command(command) def __send_command(self, command: CECCommand = CECCommand()): self.logical_address = command.logical_address self.destination = command.destination self.phy_address = command.phy_address self.op_code = command.op_code self.op_code_param = command.op_code_param self.device_type = command.device_type self.__send_cec_command() def __send_cec_command(self): self.__io.set(TSI_HDTX_CEC_COMMAND, 1, c_uint32) @property def commands(self) -> list: """ Get CEC command list. Returns: object of `list` type """ return self.__commands def clear_commands(self): """ Clear saved commands. """ self.__commands.clear()