Esempio n. 1
0
 def __init__(self, client: Client, name: str, zone: int,
              turn_on: ConfigType):
     """Initialize device."""
     super().__init__()
     self._client = client
     self._state = State(client, zone)
     self._name = name
     self._turn_on = turn_on
     self._support = (SUPPORT_SELECT_SOURCE | SUPPORT_VOLUME_SET
                      | SUPPORT_VOLUME_MUTE | SUPPORT_VOLUME_STEP
                      | SUPPORT_TURN_OFF)
     if zone == 1:
         self._support |= SUPPORT_SELECT_SOUND_MODE
Esempio n. 2
0
async def test_power_off(zn):
    client = MagicMock(spec=Client)
    state = State(client, zn)

    assert state.get_power() is None
    await state.set_power(False)
    if zn == 1:
        code = RC5Codes.POWER_OFF
    else:
        code = RC5Codes.POWER_OFF_ZONE2

    client.send.assert_called_with(
        zn, CommandCodes.SIMULATE_RC5_IR_COMMAND, code.value
    )
    assert state.get_power() == False
Esempio n. 3
0
async def test_power_off(zn, api_model):
    client = MagicMock(spec=Client)
    state = State(client, zn, api_model)

    assert state.get_power() is None
    await state.set_power(False)
    if api_model == ApiModel.APISA_SERIES:
        client.request.assert_called_with(
            zn, CommandCodes.POWER, bytes([0x00])
        )
    else:
        # zn, api_model, power
        code = PARAMS_TO_RC5COMMAND[zn, api_model, False]
        client.send.assert_called_with(
            zn, CommandCodes.SIMULATE_RC5_IR_COMMAND, code
        )
    assert state.get_power() == False
Esempio n. 4
0
async def async_setup_entry(
    hass: HomeAssistantType,
    config_entry: config_entries.ConfigEntry,
    async_add_entities,
):
    """Set up the configuration entry."""
    data = hass.data[DOMAIN_DATA_ENTRIES][config_entry.entry_id]
    client = data["client"]
    config = data["config"]

    async_add_entities([
        ArcamFmj(
            State(client, zone),
            zone_config[CONF_NAME],
            zone_config.get(SERVICE_TURN_ON),
        ) for zone, zone_config in config[CONF_ZONE].items()
    ])

    return True
Esempio n. 5
0
async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up the configuration entry."""

    client = get_entry_client(hass, config_entry)

    async_add_entities(
        [
            ArcamFmj(
                config_entry.title,
                State(client, zone),
                config_entry.unique_id or config_entry.entry_id,
            ) for zone in (1, 2)
        ],
        True,
    )
Esempio n. 6
0
async def test_power_on(zn):
    client = MagicMock(spec=Client)
    state = State(client, zn)
    response = ResponsePacket(
        zn,
        CommandCodes.SIMULATE_RC5_IR_COMMAND,
        AnswerCodes.STATUS_UPDATE,
        bytes([0x01]),
    )
    client.request.return_value = response

    await state.set_power(True)
    if zn == 1:
        code = RC5Codes.POWER_ON
    else:
        code = RC5Codes.POWER_ON_ZONE2

    client.request.assert_called_with(
        zn, CommandCodes.SIMULATE_RC5_IR_COMMAND, code.value
    )
Esempio n. 7
0
async def async_setup_entry(
    hass: HomeAssistantType,
    config_entry: config_entries.ConfigEntry,
    async_add_entities,
):
    """Set up the configuration entry."""

    client = get_entry_client(hass, config_entry)

    async_add_entities(
        [
            ArcamFmj(
                config_entry.title,
                State(client, zone),
                config_entry.unique_id or config_entry.entry_id,
            ) for zone in [1, 2]
        ],
        True,
    )

    return True
Esempio n. 8
0
async def test_power_on(zn, api_model):
    client = MagicMock(spec=Client)
    state = State(client, zn, api_model)
    response = ResponsePacket(
        zn,
        CommandCodes.SIMULATE_RC5_IR_COMMAND,
        AnswerCodes.STATUS_UPDATE,
        bytes([0x01]),
    )
    client.request.return_value = response
    await state.set_power(True)
    if api_model == ApiModel.APISA_SERIES:
        client.request.assert_called_with(
            zn, CommandCodes.POWER, bytes([0x01])
        )
    else:
        # zn, api_model, power
        code = PARAMS_TO_RC5COMMAND[zn, api_model, True]
        client.request.assert_called_with(
            zn, CommandCodes.SIMULATE_RC5_IR_COMMAND, code
        )
Esempio n. 9
0
async def async_setup_entry(
    opp: OpenPeerPower,
    config_entry: config_entries.ConfigEntry,
    async_add_entities,
):
    """Set up the configuration entry."""

    client = get_entry_client(opp, config_entry)

    async_add_entities(
        [
            ArcamFmj(
                config_entry.title,
                State(client, zone),
                config_entry.unique_id or config_entry.entry_id,
            ) for zone in [1, 2]
        ],
        True,
    )

    return True
Esempio n. 10
0
async def test_state(loop, server, client):
    state = State(client, 0x01)
    await state.update()
    assert state.get(CommandCodes.POWER) == bytes([0x00])
    assert state.get(CommandCodes.VOLUME) == bytes([0x01])
Esempio n. 11
0
class ArcamFmj(MediaPlayerDevice):
    """Representation of a media device."""
    def __init__(self, client: Client, name: str, zone: int,
                 turn_on: ConfigType):
        """Initialize device."""
        super().__init__()
        self._client = client
        self._state = State(client, zone)
        self._name = name
        self._turn_on = turn_on
        self._support = (SUPPORT_SELECT_SOURCE | SUPPORT_VOLUME_SET
                         | SUPPORT_VOLUME_MUTE | SUPPORT_VOLUME_STEP
                         | SUPPORT_TURN_OFF)
        if zone == 1:
            self._support |= SUPPORT_SELECT_SOUND_MODE

    def _get_2ch(self):
        """Return if source is 2 channel or not"""
        audio_format, _ = self._state.get_incoming_audio_format()
        return bool(audio_format in (IncomingAudioFormat.PCM,
                                     IncomingAudioFormat.ANALOGUE_DIRECT,
                                     None))

    @property
    def should_poll(self) -> bool:
        """No need to poll."""
        return False

    @property
    def name(self):
        """Return the name of the controlled device."""
        return self._name

    @property
    def state(self):
        """Return the state of the device."""
        if self._state.get_power():
            return STATE_ON
        return STATE_OFF

    @property
    def supported_features(self):
        """Flag media player features that are supported."""
        support = self._support
        if (self._state.get_power() is not None or self._turn_on):
            support |= SUPPORT_TURN_ON
        return support

    async def async_added_to_hass(self):
        """Once registed add listener for events."""

        await self._state.start()

        def _data(host):
            if host == self._client.host:
                self.async_schedule_update_ha_state()

        def _started(host):
            if host == self._client.host:
                self.async_schedule_update_ha_state(force_refresh=True)

        def _stopped(host):
            if host == self._client.host:
                self.async_schedule_update_ha_state(force_refresh=True)

        self.hass.helpers.dispatcher.async_dispatcher_connect(
            SIGNAL_CLIENT_DATA, _data)

        self.hass.helpers.dispatcher.async_dispatcher_connect(
            SIGNAL_CLIENT_STARTED, _started)

        self.hass.helpers.dispatcher.async_dispatcher_connect(
            SIGNAL_CLIENT_STOPPED, _stopped)

    async def async_update(self):
        """Force update state"""
        _LOGGER.info("Update state %s", self.name)
        await self._state.update()

    async def async_mute_volume(self, mute):
        """Send mute command."""
        await self._state.set_mute(mute)
        self.async_schedule_update_ha_state()

    async def async_select_source(self, source):
        """Select a specific source."""
        value = SourceCodes[source]
        await self._state.set_source(value)
        self.async_schedule_update_ha_state()

    async def async_select_sound_mode(self, sound_mode):
        """Select a specific source."""
        if self._get_2ch():
            await self._state.set_decode_mode_2ch(DecodeMode2CH[sound_mode])
        else:
            await self._state.set_decode_mode_mch(DecodeModeMCH[sound_mode])
        self.async_schedule_update_ha_state()

    async def async_set_volume_level(self, volume):
        """Set volume level, range 0..1."""
        await self._state.set_volume(round(volume * 99.0))
        self.async_schedule_update_ha_state()

    async def async_volume_up(self):
        """Turn volume up for media player."""
        await self._state.inc_volume()
        self.async_schedule_update_ha_state()

    async def async_volume_down(self):
        """Turn volume up for media player."""
        await self._state.dec_volume()
        self.async_schedule_update_ha_state()

    async def async_turn_on(self):
        """Turn the media player on."""
        if self._state.get_power() is not None:
            _LOGGER.info("Turning on device using connection")
            await self._state.set_power(True)
        elif self._turn_on:
            _LOGGER.info("Turning on device using service call")
            await async_call_from_config(self.hass,
                                         self._turn_on,
                                         variables=None,
                                         blocking=True,
                                         validate_config=False)
        else:
            _LOGGER.error("Unable to turn on")

    async def async_turn_off(self):
        """Turn the media player off."""
        await self._state.set_power(False)

    @property
    def source(self):
        """Return the current input source."""
        value = self._state.get_source()
        if value is None:
            return None
        return value.name

    @property
    def source_list(self):
        """List of available input sources."""
        return [x.name for x in self._state.get_source_list()]

    @property
    def sound_mode(self):
        """Name of the current sound mode."""
        if self._state.zn != 1:
            return None

        if self._get_2ch():
            value = self._state.get_decode_mode_2ch()
        else:
            value = self._state.get_decode_mode_mch()
        if value:
            return value.name
        return None

    @property
    def sound_mode_list(self):
        """List of available sound modes."""
        if self._state.zn != 1:
            return None

        if self._get_2ch():
            return [x.name for x in DecodeMode2CH]
        return [x.name for x in DecodeModeMCH]

    @property
    def is_volume_muted(self):
        """Boolean if volume is currently muted."""
        value = self._state.get_mute()
        if value is None:
            return None
        return value

    @property
    def volume_level(self):
        value = self._state.get_volume()
        if value:
            return value / 99.0
        return None

    @property
    def media_content_type(self):
        """Content type of current playing media."""
        source = self._state.get_source()
        if source == SourceCodes.DAB:
            value = MEDIA_TYPE_MUSIC
        elif source == SourceCodes.FM:
            value = MEDIA_TYPE_MUSIC
        else:
            value = None
        return value

    @property
    def media_channel(self):
        """Channel currently playing."""
        source = self._state.get_source()
        if source == SourceCodes.DAB:
            value = self._state.get_dab_station()
        elif source == SourceCodes.FM:
            value = self._state.get_rds_information()
        else:
            value = None
        return value

    @property
    def media_artist(self):
        """Artist of current playing media, music track only."""
        source = self._state.get_source()
        if source == SourceCodes.DAB:
            value = self._state.get_dls_pdt()
        else:
            value = None
        return value

    @property
    def media_title(self):
        """Title of current playing media."""
        source = self._state.get_source()
        if source is None:
            return None

        channel = self.media_channel

        if channel:
            value = "{} - {}".format(source.name, channel)
        else:
            value = source.name
        return value