Update bravia-tv backend (#34376)

* bravia-tv version bump

* Fix Auth Cookies

    - Fix authentication cookie expiration.
    - Remove obsolete error handling (since bravia-tv==1.0.2)
    - Remove obsolete mac address references. (since bravia-tv==1.0.2)
    - Update tests.

* fix async_refresh_playing_info

* Improve code format

Co-Authored-By: Martin Hjelmare <marhje52@gmail.com>

* Config_entry needs mac address for HA restart

    This was mistakenly taken out. Home-Assistant needs to store mac address in
    case restarted. TV needs to be on to acquire mac address. This is neccesary
    to allow TV to be turned on by Home-Assistant after Home-Assistant is
    restarted.

* Skip update() during state changes

    It is best for performance to skip updates during state change because
    bravia.turn_on() will commonly push async_update() beyond it's update
    interval.

* update tests

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
David Nielsen 2020-04-21 10:46:12 -04:00 committed by GitHub
parent 60f79c848a
commit 08e74352ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 78 additions and 74 deletions

View File

@ -3,10 +3,9 @@ import asyncio
from bravia_tv import BraviaRC from bravia_tv import BraviaRC
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_PIN from homeassistant.const import CONF_HOST, CONF_MAC
from homeassistant.exceptions import ConfigEntryNotReady
from .const import CLIENTID_PREFIX, DOMAIN, NICKNAME from .const import DOMAIN
PLATFORMS = ["media_player"] PLATFORMS = ["media_player"]
@ -20,17 +19,9 @@ async def async_setup_entry(hass, config_entry):
"""Set up a config entry.""" """Set up a config entry."""
host = config_entry.data[CONF_HOST] host = config_entry.data[CONF_HOST]
mac = config_entry.data[CONF_MAC] mac = config_entry.data[CONF_MAC]
pin = config_entry.data[CONF_PIN]
braviarc = BraviaRC(host, mac)
await hass.async_add_executor_job(braviarc.connect, pin, CLIENTID_PREFIX, NICKNAME)
if not braviarc.is_connected():
raise ConfigEntryNotReady
hass.data.setdefault(DOMAIN, {}) hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][config_entry.entry_id] = braviarc hass.data[DOMAIN][config_entry.entry_id] = BraviaRC(host, mac)
for component in PLATFORMS: for component in PLATFORMS:
hass.async_create_task( hass.async_create_task(

View File

@ -56,11 +56,10 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
if not self.braviarc.is_connected(): if not self.braviarc.is_connected():
raise CannotConnect() raise CannotConnect()
try: system_info = await self.hass.async_add_executor_job(
system_info = await self.hass.async_add_executor_job( self.braviarc.get_system_info
self.braviarc.get_system_info )
) if not system_info:
except (KeyError, TypeError):
raise ModelNotSupported() raise ModelNotSupported()
await self.async_set_unique_id(system_info[ATTR_CID].lower()) await self.async_set_unique_id(system_info[ATTR_CID].lower())

View File

@ -2,7 +2,7 @@
"domain": "braviatv", "domain": "braviatv",
"name": "Sony Bravia TV", "name": "Sony Bravia TV",
"documentation": "https://www.home-assistant.io/integrations/braviatv", "documentation": "https://www.home-assistant.io/integrations/braviatv",
"requirements": ["bravia-tv==1.0.1"], "requirements": ["bravia-tv==1.0.2"],
"codeowners": ["@robbiet480", "@bieniu"], "codeowners": ["@robbiet480", "@bieniu"],
"config_flow": true "config_flow": true
} }

View File

@ -1,4 +1,5 @@
"""Support for interface with a Bravia TV.""" """Support for interface with a Bravia TV."""
import asyncio
import logging import logging
import voluptuous as vol import voluptuous as vol
@ -144,44 +145,39 @@ class BraviaTVDevice(MediaPlayerDevice):
self._unique_id = unique_id self._unique_id = unique_id
self._device_info = device_info self._device_info = device_info
self._ignored_sources = ignored_sources self._ignored_sources = ignored_sources
self._state_lock = asyncio.Lock()
self._need_refresh = True
def update(self): async def async_update(self):
"""Update TV info.""" """Update TV info."""
if not self._braviarc.is_connected(): if self._state_lock.locked():
if self._braviarc.get_power_status() != "off": return
self._braviarc.connect(self._pin, CLIENTID_PREFIX, NICKNAME)
if not self._braviarc.is_connected(): if self._state == STATE_OFF:
self._need_refresh = True
power_status = await self.hass.async_add_executor_job(
self._braviarc.get_power_status
)
if power_status == "active":
if self._need_refresh:
connected = await self.hass.async_add_executor_job(
self._braviarc.connect, self._pin, CLIENTID_PREFIX, NICKNAME
)
self._need_refresh = False
else:
connected = self._braviarc.is_connected()
if not connected:
return return
# Retrieve the latest data. self._state = STATE_ON
try: if (
if self._state == STATE_ON: await self._async_refresh_volume()
# refresh volume info: and await self._async_refresh_channels()
self._refresh_volume() ):
self._refresh_channels() await self._async_refresh_playing_info()
return
power_status = self._braviarc.get_power_status() self._state = STATE_OFF
if power_status == "active":
self._state = STATE_ON
playing_info = self._braviarc.get_playing_info()
self._reset_playing_info()
if playing_info is None or not playing_info:
self._channel_name = "App"
else:
self._program_name = playing_info.get("programTitle")
self._channel_name = playing_info.get("title")
self._program_media_type = playing_info.get("programMediaType")
self._channel_number = playing_info.get("dispNum")
self._content_uri = playing_info.get("uri")
self._source = self._get_source()
self._duration = playing_info.get("durationSec")
self._start_date_time = playing_info.get("startDateTime")
else:
self._state = STATE_OFF
except Exception as exception_instance: # pylint: disable=broad-except
_LOGGER.error(exception_instance)
self._state = STATE_OFF
def _get_source(self): def _get_source(self):
"""Return the name of the source.""" """Return the name of the source."""
@ -189,32 +185,48 @@ class BraviaTVDevice(MediaPlayerDevice):
if value == self._content_uri: if value == self._content_uri:
return key return key
def _reset_playing_info(self): async def _async_refresh_volume(self):
self._program_name = None
self._channel_name = None
self._program_media_type = None
self._channel_number = None
self._source = None
self._content_uri = None
self._duration = None
self._start_date_time = None
def _refresh_volume(self):
"""Refresh volume information.""" """Refresh volume information."""
volume_info = self._braviarc.get_volume_info() volume_info = await self.hass.async_add_executor_job(
self._braviarc.get_volume_info
)
if volume_info is not None: if volume_info is not None:
self._volume = volume_info.get("volume") self._volume = volume_info.get("volume")
self._min_volume = volume_info.get("minVolume") self._min_volume = volume_info.get("minVolume")
self._max_volume = volume_info.get("maxVolume") self._max_volume = volume_info.get("maxVolume")
self._muted = volume_info.get("mute") self._muted = volume_info.get("mute")
return True
return False
def _refresh_channels(self): async def _async_refresh_channels(self):
"""Refresh source and channels list."""
if not self._source_list: if not self._source_list:
self._content_mapping = self._braviarc.load_source_list() self._content_mapping = await self.hass.async_add_executor_job(
self._braviarc.load_source_list
)
self._source_list = [] self._source_list = []
if not self._content_mapping:
return False
for key in self._content_mapping: for key in self._content_mapping:
if key not in self._ignored_sources: if key not in self._ignored_sources:
self._source_list.append(key) self._source_list.append(key)
return True
async def _async_refresh_playing_info(self):
"""Refresh Playing information."""
playing_info = await self.hass.async_add_executor_job(
self._braviarc.get_playing_info
)
self._program_name = playing_info.get("programTitle")
self._channel_name = playing_info.get("title")
self._program_media_type = playing_info.get("programMediaType")
self._channel_number = playing_info.get("dispNum")
self._content_uri = playing_info.get("uri")
self._source = self._get_source()
self._duration = playing_info.get("durationSec")
self._start_date_time = playing_info.get("startDateTime")
if not playing_info:
self._channel_name = "App"
@property @property
def name(self): def name(self):
@ -292,13 +304,15 @@ class BraviaTVDevice(MediaPlayerDevice):
"""Set volume level, range 0..1.""" """Set volume level, range 0..1."""
self._braviarc.set_volume_level(volume) self._braviarc.set_volume_level(volume)
def turn_on(self): async def async_turn_on(self):
"""Turn the media player on.""" """Turn the media player on."""
self._braviarc.turn_on() async with self._state_lock:
await self.hass.async_add_executor_job(self._braviarc.turn_on)
def turn_off(self): async def async_turn_off(self):
"""Turn off media player.""" """Turn off media player."""
self._braviarc.turn_off() async with self._state_lock:
await self.hass.async_add_executor_job(self._braviarc.turn_off)
def volume_up(self): def volume_up(self):
"""Volume up the media player.""" """Volume up the media player."""

View File

@ -355,7 +355,7 @@ bomradarloop==0.1.4
boto3==1.9.252 boto3==1.9.252
# homeassistant.components.braviatv # homeassistant.components.braviatv
bravia-tv==1.0.1 bravia-tv==1.0.2
# homeassistant.components.broadlink # homeassistant.components.broadlink
broadlink==0.13.2 broadlink==0.13.2

View File

@ -137,7 +137,7 @@ bellows-homeassistant==0.15.2
bomradarloop==0.1.4 bomradarloop==0.1.4
# homeassistant.components.braviatv # homeassistant.components.braviatv
bravia-tv==1.0.1 bravia-tv==1.0.2
# homeassistant.components.broadlink # homeassistant.components.broadlink
broadlink==0.13.2 broadlink==0.13.2

View File

@ -89,7 +89,7 @@ async def test_import_model_unsupported(hass):
"""Test that errors are shown when the TV is not supported during import.""" """Test that errors are shown when the TV is not supported during import."""
with patch("bravia_tv.BraviaRC.connect", return_value=True), patch( with patch("bravia_tv.BraviaRC.connect", return_value=True), patch(
"bravia_tv.BraviaRC.is_connected", return_value=True "bravia_tv.BraviaRC.is_connected", return_value=True
), patch("bravia_tv.BraviaRC.get_system_info", side_effect=KeyError): ), patch("bravia_tv.BraviaRC.get_system_info", return_value={}):
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data=IMPORT_CONFIG_IP, DOMAIN, context={"source": SOURCE_IMPORT}, data=IMPORT_CONFIG_IP,
) )
@ -150,7 +150,7 @@ async def test_authorize_model_unsupported(hass):
"""Test that errors are shown when the TV is not supported at the authorize step.""" """Test that errors are shown when the TV is not supported at the authorize step."""
with patch("bravia_tv.BraviaRC.connect", return_value=True), patch( with patch("bravia_tv.BraviaRC.connect", return_value=True), patch(
"bravia_tv.BraviaRC.is_connected", return_value=True "bravia_tv.BraviaRC.is_connected", return_value=True
), patch("bravia_tv.BraviaRC.get_system_info", side_effect=KeyError): ), patch("bravia_tv.BraviaRC.get_system_info", return_value={}):
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data={CONF_HOST: "10.10.10.12"}, DOMAIN, context={"source": SOURCE_USER}, data={CONF_HOST: "10.10.10.12"},
) )