diff --git a/homeassistant/components/sensor/google_wifi.py b/homeassistant/components/sensor/google_wifi.py index d878f4f8d20b3f..ba3dbfeacc8e72 100644 --- a/homeassistant/components/sensor/google_wifi.py +++ b/homeassistant/components/sensor/google_wifi.py @@ -37,32 +37,32 @@ MONITORED_CONDITIONS = { ATTR_CURRENT_VERSION: [ - 'Current Version', + ['software', 'softwareVersion'], None, 'mdi:checkbox-marked-circle-outline' ], ATTR_NEW_VERSION: [ - 'New Version', + ['software', 'updateNewVersion'], None, 'mdi:update' ], ATTR_UPTIME: [ - 'Uptime', + ['system', 'uptime'], 'days', 'mdi:timelapse' ], ATTR_LAST_RESTART: [ - 'Last Network Restart', + ['system', 'uptime'], None, 'mdi:restart' ], ATTR_LOCAL_IP: [ - 'Local IP Address', + ['wan', 'localIpAddress'], None, 'mdi:access-point-network' ], ATTR_STATUS: [ - 'Status', + ['wan', 'online'], None, 'mdi:google' ] @@ -80,13 +80,14 @@ def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Google Wifi sensor.""" name = config.get(CONF_NAME) host = config.get(CONF_HOST) + conditions = config.get(CONF_MONITORED_CONDITIONS) - api = GoogleWifiAPI(host) + api = GoogleWifiAPI(host, conditions) + dev = [] + for condition in conditions: + dev.append(GoogleWifiSensor(hass, api, name, condition)) - sensors = [GoogleWifiSensor(hass, api, name, condition) - for condition in config[CONF_MONITORED_CONDITIONS]] - - add_devices(sensors, True) + add_devices(dev, True) class GoogleWifiSensor(Entity): @@ -141,13 +142,13 @@ def update(self): class GoogleWifiAPI(object): """Get the latest data and update the states.""" - def __init__(self, host): + def __init__(self, host, conditions): """Initialize the data object.""" uri = 'http://' resource = "{}{}{}".format(uri, host, ENDPOINT) - self._request = requests.Request('GET', resource).prepare() self.raw_data = None + self.conditions = conditions self.data = { ATTR_CURRENT_VERSION: STATE_UNKNOWN, ATTR_NEW_VERSION: STATE_UNKNOWN, @@ -163,39 +164,49 @@ def __init__(self, host): def update(self): """Get the latest data from the router.""" try: - _LOGGER.error("Before request") with requests.Session() as sess: response = sess.send( self._request, timeout=10) self.raw_data = response.json() - _LOGGER.error(self.raw_data) self.data_format() self.availiable = True except ValueError: - _LOGGER.error("Unable to fetch data from Google Wifi") + _LOGGER.error('Unable to fetch data from Google Wifi') self.availiable = False self.raw_data = None def data_format(self): """Format raw data into easily accessible dict.""" - for key, value in self.raw_data.items(): - if key == 'software': - self.data[ATTR_CURRENT_VERSION] = value['softwareVersion'] - if value['updateNewVersion'] == '0.0.0.0': - self.data[ATTR_NEW_VERSION] = 'Latest' - else: - self.data[ATTR_NEW_VERSION] = value['updateNewVersion'] - elif key == 'system': - self.data[ATTR_UPTIME] = value['uptime'] / (3600 * 24) - last_restart = dt.now() - timedelta(seconds=value['uptime']) - self.data[ATTR_LAST_RESTART] = \ - last_restart.strftime("%Y-%m-%d %H:%M:%S") - elif key == 'wan': - if value['online']: - self.data[ATTR_STATUS] = 'Online' - else: - self.data[ATTR_STATUS] = 'Offline' - if not value['ipAddress']: - self.data[ATTR_LOCAL_IP] = STATE_UNKNOWN - else: - self.data[ATTR_LOCAL_IP] = value['localIpAddress'] + for attr_key in self.conditions: + value = MONITORED_CONDITIONS[attr_key] + try: + primary_key = value[0][0] + sensor_key = value[0][1] + if primary_key in self.raw_data: + sensor_value = self.raw_data[primary_key][sensor_key] + # Format sensor for better readability + if (attr_key == ATTR_NEW_VERSION and + sensor_value == '0.0.0.0'): + sensor_value = 'Latest' + elif attr_key == ATTR_UPTIME: + sensor_value /= 3600 * 24 + elif attr_key == ATTR_LAST_RESTART: + last_restart = (dt.now() - + timedelta(seconds=sensor_value)) + sensor_value = last_restart.strftime(('%Y-%m-%d ' + '%H:%M:%S')) + elif attr_key == ATTR_STATUS: + if sensor_value: + sensor_value = 'Online' + else: + sensor_value = 'Offline' + elif attr_key == ATTR_LOCAL_IP: + if not self.raw_data['wan']['online']: + sensor_value = STATE_UNKNOWN + + self.data[attr_key] = sensor_value + except KeyError: + _LOGGER.error('Router does not support %s field. ' + 'Please remove %s from monitored_conditions.', + sensor_key, attr_key) + self.data[attr_key] = STATE_UNKNOWN diff --git a/tests/components/sensor/test_google_wifi.py b/tests/components/sensor/test_google_wifi.py index 978ec99236c224..b45261b6daa092 100644 --- a/tests/components/sensor/test_google_wifi.py +++ b/tests/components/sensor/test_google_wifi.py @@ -26,6 +26,10 @@ '"wan": {"localIpAddress":"next", "online":false,' '"ipAddress":false}}') +MOCK_DATA_MISSING = ('{"software": {},' + '"system": {},' + '"wan": {}}') + class TestGoogleWifiSetup(unittest.TestCase): """Tests for setting up the Google Wifi switch platform.""" @@ -47,9 +51,11 @@ def test_setup_minimum(self, mock_req): mock_req.get(resource, status_code=200) self.assertTrue(setup_component(self.hass, 'sensor', { 'sensor': { - 'platform': 'google_wifi' + 'platform': 'google_wifi', + 'monitored_conditions': ['uptime'] } })) + assert_setup_component(1, 'sensor') @requests_mock.Mocker() def test_setup_get(self, mock_req): @@ -95,7 +101,9 @@ def setup_api(self, data, mock_req): now = datetime(1970, month=1, day=1) with patch('homeassistant.util.dt.now', return_value=now): mock_req.get(resource, text=data, status_code=200) - self.api = google_wifi.GoogleWifiAPI("localhost") + conditions = google_wifi.MONITORED_CONDITIONS.keys() + self.api = google_wifi.GoogleWifiAPI("localhost", + conditions) self.name = NAME self.sensor_dict = dict() for condition, cond_list in google_wifi.MONITORED_CONDITIONS.items(): @@ -188,6 +196,18 @@ def test_update_when_value_changed(self, mock_req): else: self.assertEqual('next', sensor.state) + @requests_mock.Mocker() + def test_when_api_data_missing(self, mock_req): + """Test state logs an error when data is missing.""" + self.setup_api(MOCK_DATA_MISSING, mock_req) + now = datetime(1970, month=1, day=1) + with patch('homeassistant.util.dt.now', return_value=now): + for name in self.sensor_dict: + sensor = self.sensor_dict[name]['sensor'] + self.fake_delay(2) + sensor.update() + self.assertEqual(STATE_UNKNOWN, sensor.state) + def test_update_when_unavailiable(self): """Test state updates when Google Wifi unavailiable.""" self.api.update = Mock('google_wifi.GoogleWifiAPI.update',