Add unique_id to directv entities (#31838)

* add unique_id to directv entities.

* add addiitional debug and fix tests.

* fix lint error.

* rework unique_id and flow a bit.

* review adjustments.

* review adjustments

* review adjustments

* review adjustments.

* review adjustments

* review adjustments

* review adjustments

* review adjustments

* lint

* use serial number for host unit and mac address for client units

* fix elsif

* update test with realistic client id

* lint
This commit is contained in:
Chris Talkington 2020-02-23 12:26:34 -06:00 committed by GitHub
parent 1007283da5
commit 8dd80e0e3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 30 deletions

View File

@ -77,23 +77,24 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the DirecTV platform."""
known_devices = hass.data.get(DATA_DIRECTV, set())
hosts = []
entities = []
if CONF_HOST in config:
name = config[CONF_NAME]
host = config[CONF_HOST]
port = config[CONF_PORT]
device = config[CONF_DEVICE]
_LOGGER.debug(
"Adding configured device %s with client address %s ",
config.get(CONF_NAME),
config.get(CONF_DEVICE),
)
hosts.append(
[
config.get(CONF_NAME),
config.get(CONF_HOST),
config.get(CONF_PORT),
config.get(CONF_DEVICE),
]
"Adding configured device %s with client address %s", name, device,
)
dtv = DIRECTV(host, port, device)
dtv_version = _get_receiver_version(dtv)
entities.append(DirecTvDevice(name, device, dtv, dtv_version,))
known_devices.add((host, device))
elif discovery_info:
host = discovery_info.get("host")
name = "DirecTV_{}".format(discovery_info.get("serial", ""))
@ -102,7 +103,9 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
_LOGGER.debug("Doing discovery of DirecTV devices on %s", host)
dtv = DIRECTV(host, DEFAULT_PORT)
try:
dtv_version = _get_receiver_version(dtv)
resp = dtv.get_locations()
except requests.exceptions.RequestException as ex:
# Bail out and just go forward with uPnP data
@ -116,6 +119,8 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
if "locationName" not in loc or "clientAddr" not in loc:
continue
loc_name = str.title(loc["locationName"])
# Make sure that this device is not already configured
# Comparing based on host (IP) and clientAddr.
if (host, loc["clientAddr"]) in known_devices:
@ -123,42 +128,47 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
"Discovered device %s on host %s with "
"client address %s is already "
"configured",
str.title(loc["locationName"]),
loc_name,
host,
loc["clientAddr"],
)
else:
_LOGGER.debug(
"Adding discovered device %s with client address %s",
str.title(loc["locationName"]),
loc_name,
loc["clientAddr"],
)
hosts.append(
[
str.title(loc["locationName"]),
host,
DEFAULT_PORT,
entities.append(
DirecTvDevice(
loc_name,
loc["clientAddr"],
]
DIRECTV(host, DEFAULT_PORT, loc["clientAddr"]),
dtv_version,
)
)
known_devices.add((host, loc["clientAddr"]))
dtvs = []
add_entities(entities)
for host in hosts:
dtvs.append(DirecTvDevice(*host))
hass.data.setdefault(DATA_DIRECTV, set()).add((host[1], host[3]))
add_entities(dtvs)
def _get_receiver_version(client):
"""Return the version of the DirectTV receiver."""
try:
return client.get_version()
except requests.exceptions.RequestException as ex:
_LOGGER.debug("Request exception %s trying to get receiver version", ex)
return None
class DirecTvDevice(MediaPlayerDevice):
"""Representation of a DirecTV receiver on the network."""
def __init__(self, name, host, port, device):
def __init__(self, name, device, dtv, version_info=None):
"""Initialize the device."""
self.dtv = DIRECTV(host, port, device)
self.dtv = dtv
self._name = name
self._unique_id = None
self._is_standby = True
self._current = None
self._last_update = None
@ -170,6 +180,11 @@ class DirecTvDevice(MediaPlayerDevice):
self._available = False
self._first_error_timestamp = None
if device != "0":
self._unique_id = device
elif version_info:
self._unique_id = "".join(version_info.get("receiverId").split())
if self._is_client:
_LOGGER.debug("Created DirecTV client %s for device %s", self._name, device)
else:
@ -257,6 +272,11 @@ class DirecTvDevice(MediaPlayerDevice):
"""Return the name of the device."""
return self._name
@property
def unique_id(self):
"""Return a unique ID to use for this media player."""
return self._unique_id
# MediaPlayerDevice properties and methods
@property
def state(self):

View File

@ -60,6 +60,7 @@ import homeassistant.util.dt as dt_util
from tests.common import async_fire_time_changed
ATTR_UNIQUE_ID = "unique_id"
CLIENT_ENTITY_ID = "media_player.client_dvr"
MAIN_ENTITY_ID = "media_player.main_dvr"
IP_ADDRESS = "127.0.0.1"
@ -138,7 +139,7 @@ def main_dtv():
def dtv_side_effect(client_dtv, main_dtv):
"""Fixture to create DIRECTV instance for main and client."""
def mock_dtv(ip, port, client_addr):
def mock_dtv(ip, port, client_addr="0"):
if client_addr != "0":
mocked_dtv = client_dtv
else:
@ -174,7 +175,7 @@ def platforms(hass, dtv_side_effect, mock_now):
"name": "Client DVR",
"host": IP_ADDRESS,
"port": DEFAULT_PORT,
"device": "1",
"device": "2CA17D1CD30X",
},
]
}
@ -272,6 +273,20 @@ class MockDirectvClass:
return test_locations
def get_serial_num(self):
"""Mock for get_serial_num method."""
test_serial_num = {
"serialNum": "9999999999",
"status": {
"code": 200,
"commandResult": 0,
"msg": "OK.",
"query": "/info/getSerialNum",
},
}
return test_serial_num
def get_standby(self):
"""Mock for get_standby method."""
return self._standby
@ -290,6 +305,24 @@ class MockDirectvClass:
}
return test_attributes
def get_version(self):
"""Mock for get_version method."""
test_version = {
"accessCardId": "0021-1495-6572",
"receiverId": "0288 7745 5858",
"status": {
"code": 200,
"commandResult": 0,
"msg": "OK.",
"query": "/info/getVersion",
},
"stbSoftwareVersion": "0x4ed7",
"systemTime": 1281625203,
"version": "1.2",
}
return test_version
def key_press(self, keypress):
"""Mock for key_press method."""
if keypress == "poweron":
@ -391,6 +424,17 @@ async def test_setup_platform_discover_client(hass):
assert len(hass.states.async_entity_ids("media_player")) == 3
async def test_unique_id(hass, platforms):
"""Test unique id."""
entity_registry = await hass.helpers.entity_registry.async_get_registry()
main = entity_registry.async_get(MAIN_ENTITY_ID)
assert main.unique_id == "028877455858"
client = entity_registry.async_get(CLIENT_ENTITY_ID)
assert client.unique_id == "2CA17D1CD30X"
async def test_supported_features(hass, platforms):
"""Test supported features."""
# Features supported for main DVR