mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 14:17:45 +00:00
Merge pull request #2870 from Teagan42/AddFixToWunderground
Fix PyDoc and other issues with Wunderground - approved by robbie
This commit is contained in:
commit
85d632c272
@ -1,4 +1,9 @@
|
|||||||
"""Support for Wunderground weather service."""
|
"""
|
||||||
|
Support for WUnderground weather service.
|
||||||
|
|
||||||
|
For more details about this platform, please refer to the documentation at
|
||||||
|
https://home-assistant.io/components/sensor.wunderground/
|
||||||
|
"""
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
import requests
|
import requests
|
||||||
@ -6,8 +11,9 @@ import requests
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
from homeassistant.helpers.config_validation import ensure_list
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.util import Throttle
|
from homeassistant.util import Throttle
|
||||||
|
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||||
from homeassistant.const import (CONF_PLATFORM, CONF_MONITORED_CONDITIONS,
|
from homeassistant.const import (CONF_PLATFORM, CONF_MONITORED_CONDITIONS,
|
||||||
CONF_API_KEY, TEMP_FAHRENHEIT, TEMP_CELSIUS,
|
CONF_API_KEY, TEMP_FAHRENHEIT, TEMP_CELSIUS,
|
||||||
STATE_UNKNOWN)
|
STATE_UNKNOWN)
|
||||||
@ -50,26 +56,23 @@ SENSOR_TYPES = {
|
|||||||
'solarradiation': ['Solar Radiation', None]
|
'solarradiation': ['Solar Radiation', None]
|
||||||
}
|
}
|
||||||
|
|
||||||
PLATFORM_SCHEMA = vol.Schema({
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
vol.Required(CONF_PLATFORM): "wunderground",
|
vol.Required(CONF_PLATFORM): "wunderground",
|
||||||
vol.Required(CONF_API_KEY): vol.Coerce(str),
|
vol.Required(CONF_API_KEY): cv.string,
|
||||||
CONF_PWS_ID: vol.Coerce(str),
|
vol.Optional(CONF_PWS_ID): cv.string,
|
||||||
vol.Required(CONF_MONITORED_CONDITIONS,
|
vol.Required(CONF_MONITORED_CONDITIONS,
|
||||||
default=[]): vol.All(ensure_list, [vol.In(SENSOR_TYPES)]),
|
default=[]): vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
"""Setup the Wunderground sensor."""
|
"""Setup the WUnderground sensor."""
|
||||||
rest = WUndergroundData(hass,
|
rest = WUndergroundData(hass,
|
||||||
config.get(CONF_API_KEY),
|
config.get(CONF_API_KEY),
|
||||||
config.get(CONF_PWS_ID, None))
|
config.get(CONF_PWS_ID, None))
|
||||||
sensors = []
|
sensors = []
|
||||||
for variable in config['monitored_conditions']:
|
for variable in config[CONF_MONITORED_CONDITIONS]:
|
||||||
if variable in SENSOR_TYPES:
|
sensors.append(WUndergroundSensor(rest, variable))
|
||||||
sensors.append(WUndergroundSensor(rest, variable))
|
|
||||||
else:
|
|
||||||
_LOGGER.error('Wunderground sensor: "%s" does not exist', variable)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
rest.update()
|
rest.update()
|
||||||
@ -83,13 +86,12 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||||||
|
|
||||||
|
|
||||||
class WUndergroundSensor(Entity):
|
class WUndergroundSensor(Entity):
|
||||||
"""Implementing the Wunderground sensor."""
|
"""Implementing the WUnderground sensor."""
|
||||||
|
|
||||||
def __init__(self, rest, condition):
|
def __init__(self, rest, condition):
|
||||||
"""Initialize the sensor."""
|
"""Initialize the sensor."""
|
||||||
self.rest = rest
|
self.rest = rest
|
||||||
self._condition = condition
|
self._condition = condition
|
||||||
self._unit_of_measurement = None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
@ -123,7 +125,7 @@ class WUndergroundSensor(Entity):
|
|||||||
|
|
||||||
|
|
||||||
class WUndergroundData(object):
|
class WUndergroundData(object):
|
||||||
"""Get data from Wundeground."""
|
"""Get data from WUnderground."""
|
||||||
|
|
||||||
def __init__(self, hass, api_key, pws_id=None):
|
def __init__(self, hass, api_key, pws_id=None):
|
||||||
"""Initialize the data object."""
|
"""Initialize the data object."""
|
||||||
@ -137,7 +139,7 @@ class WUndergroundData(object):
|
|||||||
def _build_url(self):
|
def _build_url(self):
|
||||||
url = _RESOURCE.format(self._api_key)
|
url = _RESOURCE.format(self._api_key)
|
||||||
if self._pws_id:
|
if self._pws_id:
|
||||||
url = url + 'pws:' + self._pws_id
|
url = url + 'pws:{}'.format(self._pws_id)
|
||||||
else:
|
else:
|
||||||
url = url + '{},{}'.format(self._latitude, self._longitude)
|
url = url + '{},{}'.format(self._latitude, self._longitude)
|
||||||
|
|
||||||
@ -145,7 +147,7 @@ class WUndergroundData(object):
|
|||||||
|
|
||||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Get the latest data from wunderground."""
|
"""Get the latest data from WUnderground."""
|
||||||
try:
|
try:
|
||||||
result = requests.get(self._build_url(), timeout=10).json()
|
result = requests.get(self._build_url(), timeout=10).json()
|
||||||
if "error" in result['response']:
|
if "error" in result['response']:
|
||||||
@ -154,6 +156,6 @@ class WUndergroundData(object):
|
|||||||
else:
|
else:
|
||||||
self.data = result["current_observation"]
|
self.data = result["current_observation"]
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
_LOGGER.error("Check Wunderground API %s", err.args)
|
_LOGGER.error("Check WUnderground API %s", err.args)
|
||||||
self.data = None
|
self.data = None
|
||||||
raise
|
raise
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
"""The tests for the forecast.io platform."""
|
"""The tests for the WUnderground platform."""
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from homeassistant.components.sensor import wunderground
|
from homeassistant.components.sensor import wunderground
|
||||||
@ -28,17 +28,20 @@ ICON_URL = 'http://icons.wxug.com/i/c/k/clear.gif'
|
|||||||
|
|
||||||
|
|
||||||
def mocked_requests_get(*args, **kwargs):
|
def mocked_requests_get(*args, **kwargs):
|
||||||
|
"""Mock requests.get invocations."""
|
||||||
|
|
||||||
class MockResponse:
|
class MockResponse:
|
||||||
|
"""Class to represent a mocked response."""
|
||||||
def __init__(self, json_data, status_code):
|
def __init__(self, json_data, status_code):
|
||||||
|
"""Initialize the mock response class."""
|
||||||
self.json_data = json_data
|
self.json_data = json_data
|
||||||
self.status_code = status_code
|
self.status_code = status_code
|
||||||
|
|
||||||
def json(self):
|
def json(self):
|
||||||
|
"""Return the json of the response."""
|
||||||
return self.json_data
|
return self.json_data
|
||||||
|
|
||||||
if str(args[0]).startswith('http://api.wunderground.com/api/foo/'):
|
if str(args[0]).startswith('http://api.wunderground.com/api/foo/'):
|
||||||
# Return valid response
|
|
||||||
print('VALID RESPONSE')
|
|
||||||
return MockResponse({
|
return MockResponse({
|
||||||
"response": {
|
"response": {
|
||||||
"version": "0.1",
|
"version": "0.1",
|
||||||
@ -60,8 +63,6 @@ def mocked_requests_get(*args, **kwargs):
|
|||||||
}
|
}
|
||||||
}, 200)
|
}, 200)
|
||||||
else:
|
else:
|
||||||
# Return invalid api key
|
|
||||||
print('INVALID RESPONSE')
|
|
||||||
return MockResponse({
|
return MockResponse({
|
||||||
"response": {
|
"response": {
|
||||||
"version": "0.1",
|
"version": "0.1",
|
||||||
@ -77,7 +78,7 @@ def mocked_requests_get(*args, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
class TestWundergroundSetup(unittest.TestCase):
|
class TestWundergroundSetup(unittest.TestCase):
|
||||||
"""Test the wunderground platform."""
|
"""Test the WUnderground platform."""
|
||||||
|
|
||||||
DEVICES = []
|
DEVICES = []
|
||||||
|
|
||||||
@ -98,12 +99,10 @@ class TestWundergroundSetup(unittest.TestCase):
|
|||||||
|
|
||||||
@unittest.mock.patch('requests.get', side_effect=mocked_requests_get)
|
@unittest.mock.patch('requests.get', side_effect=mocked_requests_get)
|
||||||
def test_setup(self, req_mock):
|
def test_setup(self, req_mock):
|
||||||
"""Test that the component is loaded if passed in PSW Id."""
|
"""Test that the component is loaded if passed in PWS Id."""
|
||||||
print('1')
|
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
wunderground.setup_platform(self.hass, VALID_CONFIG_PWS,
|
wunderground.setup_platform(self.hass, VALID_CONFIG_PWS,
|
||||||
self.add_devices, None))
|
self.add_devices, None))
|
||||||
print('2')
|
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
wunderground.setup_platform(self.hass, VALID_CONFIG,
|
wunderground.setup_platform(self.hass, VALID_CONFIG,
|
||||||
self.add_devices,
|
self.add_devices,
|
||||||
@ -123,9 +122,9 @@ class TestWundergroundSetup(unittest.TestCase):
|
|||||||
|
|
||||||
@unittest.mock.patch('requests.get', side_effect=mocked_requests_get)
|
@unittest.mock.patch('requests.get', side_effect=mocked_requests_get)
|
||||||
def test_sensor(self, req_mock):
|
def test_sensor(self, req_mock):
|
||||||
|
"""Test the WUnderground sensor class and methods."""
|
||||||
wunderground.setup_platform(self.hass, VALID_CONFIG, self.add_devices,
|
wunderground.setup_platform(self.hass, VALID_CONFIG, self.add_devices,
|
||||||
None)
|
None)
|
||||||
print(str(self.DEVICES))
|
|
||||||
for device in self.DEVICES:
|
for device in self.DEVICES:
|
||||||
self.assertTrue(str(device.name).startswith('PWS_'))
|
self.assertTrue(str(device.name).startswith('PWS_'))
|
||||||
if device.name == 'PWS_weather':
|
if device.name == 'PWS_weather':
|
||||||
|
Loading…
x
Reference in New Issue
Block a user