def test_ascmd(self): pa = PhysicalAddress("8f:ab") self.assertEqual(pa.ascmd, "8f:ab") pa = PhysicalAddress("00:00") self.assertEqual(pa.ascmd, "00:00") pa = PhysicalAddress("00:10") self.assertEqual(pa.ascmd, "00:10")
def test_str(self): pa = PhysicalAddress("8f:ab") self.assertEqual(("%s" % pa), "8.f.a.b") pa = PhysicalAddress("00:00") self.assertEqual(("%s" % pa), "0.0.0.0") pa = PhysicalAddress("00:10") self.assertEqual(("%s" % pa), "0.0.1.0")
def test_aslist(self): pa = PhysicalAddress("8f:ab") self.assertEqual(pa.asattr, [0x8f, 0xab]) pa = PhysicalAddress("00:00") self.assertEqual(pa.asattr, [0x0, 0x0]) pa = PhysicalAddress("00:10") self.assertEqual(pa.asattr, [0x0, 0x10])
def test_asint(self): pa = PhysicalAddress("8f:ab") self.assertEqual(pa.asint, 0x8fab) pa = PhysicalAddress("00:00") self.assertEqual(pa.asint, 0x0000) pa = PhysicalAddress("00:10") self.assertEqual(pa.asint, 0x0010)
def test_str(): pa = PhysicalAddress("8f:ab") assert ("%s" % pa) == "8.f.a.b" pa = PhysicalAddress("00:00") assert ("%s" % pa) == "0.0.0.0" pa = PhysicalAddress("00:10") assert ("%s" % pa) == "0.0.1.0"
def test_ascmd(): pa = PhysicalAddress("8f:ab") assert pa.ascmd == "8f:ab" pa = PhysicalAddress("00:00") assert pa.ascmd == "00:00" pa = PhysicalAddress("00:10") assert pa.ascmd == "00:10"
def test_asint(): pa = PhysicalAddress("8f:ab") assert pa.asint == 0x8FAB pa = PhysicalAddress("00:00") assert pa.asint == 0x0000 pa = PhysicalAddress("00:10") assert pa.asint == 0x0010
def test_aslist(): pa = PhysicalAddress("8f:ab") assert pa.asattr == [0x8F, 0xAB] pa = PhysicalAddress("00:00") assert pa.asattr == [0x0, 0x0] pa = PhysicalAddress("00:10") assert pa.asattr == [0x0, 0x10]
def _select_device(call): """Select the active device.""" from pycec.network import PhysicalAddress addr = call.data[ATTR_DEVICE] if not addr: _LOGGER.error("Device not found: %s", call.data[ATTR_DEVICE]) return if addr in device_aliases: addr = device_aliases[addr] else: entity = hass.states.get(addr) _LOGGER.debug("Selecting entity %s", entity) if entity is not None: addr = entity.attributes["physical_address"] _LOGGER.debug("Address acquired: %s", addr) if addr is None: _LOGGER.error( "Device %s has not physical address", call.data[ATTR_DEVICE] ) return if not isinstance(addr, (PhysicalAddress,)): addr = PhysicalAddress(addr) hdmi_network.active_source(addr) _LOGGER.info("Selected %s (%s)", call.data[ATTR_DEVICE], addr)
def parse_mapping(mapping, parents=None): """Parse configuration device mapping.""" if parents is None: parents = [] for addr, val in mapping.items(): if isinstance(addr, (str, )) and isinstance(val, (str, )): yield (addr, PhysicalAddress(val)) else: cur = parents + [addr] if isinstance(val, dict): yield from parse_mapping(val, cur) elif isinstance(val, str): yield (val, pad_physical_address(cur))
def test_creation(self): pa = PhysicalAddress('8F:65') self.assertEqual(0x8f65, pa.asint) pa = PhysicalAddress('0F:60') self.assertEqual(0x0f60, pa.asint) pa = PhysicalAddress('2.F.6.5') self.assertEqual(0x2f65, pa.asint) self.assertEqual('2.f.6.5', pa.asstr) pa = PhysicalAddress('0.F.6.0') self.assertEqual(0x0f60, pa.asint) pa = PhysicalAddress([2, 15, 6, 4]) self.assertEqual(0x2f64, pa.asint) pa = PhysicalAddress([0, 15, 6, 0]) self.assertEqual(0x0f60, pa.asint) pa = PhysicalAddress(0x0f60) self.assertEqual(0x0f60, pa.asint)
def test_creation(): pa = PhysicalAddress("8F:65") assert 0x8F65 == pa.asint pa = PhysicalAddress("0F:60") assert 0x0F60 == pa.asint pa = PhysicalAddress("2.F.6.5") assert 0x2F65 == pa.asint assert "2.f.6.5" == pa.asstr pa = PhysicalAddress("0.F.6.0") assert 0x0F60 == pa.asint pa = PhysicalAddress([2, 15, 6, 4]) assert 0x2F64 == pa.asint pa = PhysicalAddress([0, 15, 6, 0]) assert 0x0F60 == pa.asint pa = PhysicalAddress(0x0F60) assert 0x0F60 == pa.asint
def setup(hass: HomeAssistant, base_config: ConfigType) -> bool: # noqa: C901 """Set up the CEC capability.""" # Parse configuration into a dict of device name to physical address # represented as a list of four elements. device_aliases = {} devices = base_config[DOMAIN].get(CONF_DEVICES, {}) _LOGGER.debug("Parsing config %s", devices) device_aliases.update(parse_mapping(devices)) _LOGGER.debug("Parsed devices: %s", device_aliases) platform = base_config[DOMAIN].get(CONF_PLATFORM, SWITCH) loop = ( # Create own thread if more than 1 CPU hass.loop if multiprocessing.cpu_count() < 2 else None) host = base_config[DOMAIN].get(CONF_HOST) display_name = base_config[DOMAIN].get(CONF_DISPLAY_NAME, DEFAULT_DISPLAY_NAME) if host: adapter = TcpAdapter(host, name=display_name, activate_source=False) else: adapter = CecAdapter(name=display_name[:12], activate_source=False) hdmi_network = HDMINetwork(adapter, loop=loop) def _adapter_watchdog(now=None): _LOGGER.debug("Reached _adapter_watchdog") event.async_call_later(hass, WATCHDOG_INTERVAL, _adapter_watchdog) if not adapter.initialized: _LOGGER.info("Adapter not initialized; Trying to restart") hass.bus.fire(EVENT_HDMI_CEC_UNAVAILABLE) adapter.init() @callback def _async_initialized_callback(*_: Any): """Add watchdog on initialization.""" return event.async_call_later(hass, WATCHDOG_INTERVAL, _adapter_watchdog) hdmi_network.set_initialized_callback(_async_initialized_callback) def _volume(call: ServiceCall) -> None: """Increase/decrease volume and mute/unmute system.""" mute_key_mapping = { ATTR_TOGGLE: KEY_MUTE_TOGGLE, ATTR_ON: KEY_MUTE_ON, ATTR_OFF: KEY_MUTE_OFF, } for cmd, att in call.data.items(): if cmd == CMD_UP: _process_volume(KEY_VOLUME_UP, att) elif cmd == CMD_DOWN: _process_volume(KEY_VOLUME_DOWN, att) elif cmd == CMD_MUTE: hdmi_network.send_command( KeyPressCommand(mute_key_mapping[att], dst=ADDR_AUDIOSYSTEM)) hdmi_network.send_command( KeyReleaseCommand(dst=ADDR_AUDIOSYSTEM)) _LOGGER.info("Audio muted") else: _LOGGER.warning("Unknown command %s", cmd) def _process_volume(cmd, att): if isinstance(att, (str, )): att = att.strip() if att == CMD_PRESS: hdmi_network.send_command( KeyPressCommand(cmd, dst=ADDR_AUDIOSYSTEM)) elif att == CMD_RELEASE: hdmi_network.send_command(KeyReleaseCommand(dst=ADDR_AUDIOSYSTEM)) else: att = 1 if att == "" else int(att) for _ in range(0, att): hdmi_network.send_command( KeyPressCommand(cmd, dst=ADDR_AUDIOSYSTEM)) hdmi_network.send_command( KeyReleaseCommand(dst=ADDR_AUDIOSYSTEM)) def _tx(call: ServiceCall) -> None: """Send CEC command.""" data = call.data if ATTR_RAW in data: command = CecCommand(data[ATTR_RAW]) else: if ATTR_SRC in data: src = data[ATTR_SRC] else: src = ADDR_UNREGISTERED if ATTR_DST in data: dst = data[ATTR_DST] else: dst = ADDR_BROADCAST if ATTR_CMD in data: cmd = data[ATTR_CMD] else: _LOGGER.error("Attribute 'cmd' is missing") return if ATTR_ATT in data: if isinstance(data[ATTR_ATT], (list, )): att = data[ATTR_ATT] else: att = reduce(lambda x, y: f"{x}:{y:x}", data[ATTR_ATT]) else: att = "" command = CecCommand(cmd, dst, src, att) hdmi_network.send_command(command) def _standby(call: ServiceCall) -> None: hdmi_network.standby() def _power_on(call: ServiceCall) -> None: hdmi_network.power_on() def _select_device(call: ServiceCall) -> None: """Select the active device.""" if not (addr := call.data[ATTR_DEVICE]): _LOGGER.error("Device not found: %s", call.data[ATTR_DEVICE]) return if addr in device_aliases: addr = device_aliases[addr] else: entity = hass.states.get(addr) _LOGGER.debug("Selecting entity %s", entity) if entity is not None: addr = entity.attributes["physical_address"] _LOGGER.debug("Address acquired: %s", addr) if addr is None: _LOGGER.error("Device %s has not physical address", call.data[ATTR_DEVICE]) return if not isinstance(addr, (PhysicalAddress, )): addr = PhysicalAddress(addr) hdmi_network.active_source(addr) _LOGGER.info("Selected %s (%s)", call.data[ATTR_DEVICE], addr)
def test_raises(): with pytest.raises(AttributeError): PhysicalAddress([0] * 8)