From a94571fd10cedfbc9acd971a98caef6b6a379df4 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Wed, 5 Oct 2016 21:42:58 +0200 Subject: [PATCH] Change name of Forecast.io platform to Dark Sky (#3698) * Rename Forecast.io platform to Dark Sky * Upgrade to python-forecastio to 1.3.5 * Update to reflect name change (Forecast.io -> Dark Sky) * Rename forecast to darksky --- .coveragerc | 2 +- .../sensor/{forecast.py => darksky.py} | 36 +++++++++---------- requirements_all.txt | 4 +-- .../{test_forecast.py => test_darksky.py} | 28 +++++++++------ .../fixtures/{forecast.json => darksky.json} | 0 5 files changed, 38 insertions(+), 32 deletions(-) rename homeassistant/components/sensor/{forecast.py => darksky.py} (92%) rename tests/components/sensor/{test_forecast.py => test_darksky.py} (66%) rename tests/fixtures/{forecast.json => darksky.json} (100%) diff --git a/.coveragerc b/.coveragerc index 467950e16e8..80bc6905c21 100644 --- a/.coveragerc +++ b/.coveragerc @@ -220,6 +220,7 @@ omit = homeassistant/components/sensor/bom.py homeassistant/components/sensor/coinmarketcap.py homeassistant/components/sensor/cpuspeed.py + homeassistant/components/sensor/darksky.py homeassistant/components/sensor/deutsche_bahn.py homeassistant/components/sensor/dht.py homeassistant/components/sensor/dte_energy_bridge.py @@ -229,7 +230,6 @@ omit = homeassistant/components/sensor/fastdotcom.py homeassistant/components/sensor/fitbit.py homeassistant/components/sensor/fixer.py - homeassistant/components/sensor/forecast.py homeassistant/components/sensor/fritzbox_callmonitor.py homeassistant/components/sensor/glances.py homeassistant/components/sensor/google_travel_time.py diff --git a/homeassistant/components/sensor/forecast.py b/homeassistant/components/sensor/darksky.py similarity index 92% rename from homeassistant/components/sensor/forecast.py rename to homeassistant/components/sensor/darksky.py index e0beb65c045..241ab5f4655 100644 --- a/homeassistant/components/sensor/forecast.py +++ b/homeassistant/components/sensor/darksky.py @@ -1,8 +1,8 @@ """ -Support for Forecast.io weather service. +Support for Dark Sky weather service. For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/sensor.forecast/ +https://home-assistant.io/components/sensor.darksky/ """ import logging from datetime import timedelta @@ -18,14 +18,14 @@ from homeassistant.helpers.entity import Entity from homeassistant.util import Throttle import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['python-forecastio==1.3.4'] +REQUIREMENTS = ['python-forecastio==1.3.5'] _LOGGER = logging.getLogger(__name__) CONF_UNITS = 'units' CONF_UPDATE_INTERVAL = 'update_interval' -DEFAULT_NAME = 'Forecast.io' +DEFAULT_NAME = 'Dark Sky' # Sensor types are defined like so: # Name, si unit, us unit, ca unit, uk unit, uk2 unit @@ -91,7 +91,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ # pylint: disable=too-many-arguments def setup_platform(hass, config, add_devices, discovery_info=None): - """Setup the Forecast.io sensor.""" + """Setup the Dark Sky sensor.""" # Validate the configuration if None in (hass.config.latitude, hass.config.longitude): _LOGGER.error("Latitude or longitude not set in Home Assistant config") @@ -107,7 +107,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): # Create a data fetcher to support all of the configured sensors. Then make # the first call to init the data and confirm we can connect. try: - forecast_data = ForeCastData( + forecast_data = DarkSkyData( api_key=config.get(CONF_API_KEY, None), latitude=hass.config.latitude, longitude=hass.config.longitude, @@ -122,14 +122,14 @@ def setup_platform(hass, config, add_devices, discovery_info=None): sensors = [] for variable in config[CONF_MONITORED_CONDITIONS]: - sensors.append(ForeCastSensor(forecast_data, variable, name)) + sensors.append(DarkSkySensor(forecast_data, variable, name)) add_devices(sensors) # pylint: disable=too-few-public-methods -class ForeCastSensor(Entity): - """Implementation of a Forecast.io sensor.""" +class DarkSkySensor(Entity): + """Implementation of a Dark Sky sensor.""" def __init__(self, forecast_data, sensor_type, name): """Initialize the sensor.""" @@ -180,10 +180,10 @@ class ForeCastSensor(Entity): # pylint: disable=too-many-branches,too-many-statements def update(self): - """Get the latest data from Forecast.io and updates the states.""" + """Get the latest data from Dark Sky and updates the states.""" # Call the API for new forecast data. Each sensor will re-trigger this - # same exact call, but thats fine. We cache results for a short period - # of time to prevent hitting API limits. Note that forecast.io will + # same exact call, but that's fine. We cache results for a short period + # of time to prevent hitting API limits. Note that Dark Sky will # charge users for too many calls in 1 day, so take care when updating. self.forecast_data.update() self.update_unit_of_measurement() @@ -197,7 +197,8 @@ class ForeCastSensor(Entity): hourly = self.forecast_data.data_hourly self._state = getattr(hourly, 'summary', '') elif self.type in ['daily_summary', - 'temperature_min', 'temperature_max', + 'temperature_min', + 'temperature_max', 'apparent_temperature_min', 'apparent_temperature_max', 'precip_intensity_max']: @@ -247,11 +248,10 @@ def convert_to_camel(data): return components[0] + "".join(x.title() for x in components[1:]) -class ForeCastData(object): - """Gets the latest data from Forecast.io.""" +class DarkSkyData(object): + """Get the latest data from Darksky.""" # pylint: disable=too-many-instance-attributes - def __init__(self, api_key, latitude, longitude, units, interval): """Initialize the data object.""" self._api_key = api_key @@ -276,14 +276,14 @@ class ForeCastData(object): self.update() def _update(self): - """Get the latest data from Forecast.io.""" + """Get the latest data from Dark Sky.""" import forecastio try: self.data = forecastio.load_forecast( self._api_key, self.latitude, self.longitude, units=self.units) except (ConnectError, HTTPError, Timeout, ValueError) as error: - raise ValueError("Unable to init Forecast.io. - %s", error) + raise ValueError("Unable to init Dark Sky. %s", error) self.unit_system = self.data.json['flags']['units'] def _update_currently(self): diff --git a/requirements_all.txt b/requirements_all.txt index 7bcdf36634c..0a9468acacb 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -373,8 +373,8 @@ pysnmp==4.3.2 # homeassistant.components.digital_ocean python-digitalocean==1.9.0 -# homeassistant.components.sensor.forecast -python-forecastio==1.3.4 +# homeassistant.components.sensor.darksky +python-forecastio==1.3.5 # homeassistant.components.sensor.hp_ilo python-hpilo==3.8 diff --git a/tests/components/sensor/test_forecast.py b/tests/components/sensor/test_darksky.py similarity index 66% rename from tests/components/sensor/test_forecast.py rename to tests/components/sensor/test_darksky.py index f11a0ebccbe..f44f7385e5b 100644 --- a/tests/components/sensor/test_forecast.py +++ b/tests/components/sensor/test_darksky.py @@ -1,4 +1,4 @@ -"""The tests for the forecast.io platform.""" +"""The tests for the Dark Sky platform.""" import re import unittest from unittest.mock import MagicMock, patch @@ -8,13 +8,14 @@ from requests.exceptions import HTTPError import requests_mock from datetime import timedelta -from homeassistant.components.sensor import forecast +from homeassistant.components.sensor import darksky +from homeassistant.bootstrap import setup_component from tests.common import load_fixture, get_test_home_assistant -class TestForecastSetup(unittest.TestCase): - """Test the forecast.io platform.""" +class TestDarkSkySetup(unittest.TestCase): + """Test the Dark Sky platform.""" def setUp(self): """Initialize values for this testcase class.""" @@ -30,33 +31,38 @@ class TestForecastSetup(unittest.TestCase): self.hass.config.latitude = self.lat self.hass.config.longitude = self.lon + def test_setup_with_config(self): + """Test the platform setup with configuration.""" + self.assertTrue( + setup_component(self.hass, 'sensor', {'darksky': self.config})) + def test_setup_no_latitude(self): """Test that the component is not loaded without required config.""" self.hass.config.latitude = None - self.assertFalse(forecast.setup_platform(self.hass, {}, MagicMock())) + self.assertFalse(darksky.setup_platform(self.hass, {}, MagicMock())) @patch('forecastio.api.get_forecast') def test_setup_bad_api_key(self, mock_get_forecast): """Test for handling a bad API key.""" - # The forecast API wrapper that we use raises an HTTP error + # The Dark Sky API wrapper that we use raises an HTTP error # when you try to use a bad (or no) API key. - url = 'https://api.forecast.io/forecast/{}/{},{}?units=auto'.format( + url = 'https://api.darksky.net/forecast/{}/{},{}?units=auto'.format( self.key, str(self.lat), str(self.lon) ) msg = '400 Client Error: Bad Request for url: {}'.format(url) mock_get_forecast.side_effect = HTTPError(msg,) - response = forecast.setup_platform(self.hass, self.config, MagicMock()) + response = darksky.setup_platform(self.hass, self.config, MagicMock()) self.assertFalse(response) @requests_mock.Mocker() @patch('forecastio.api.get_forecast', wraps=forecastio.api.get_forecast) def test_setup(self, m, mock_get_forecast): """Test for successfully setting up the forecast.io platform.""" - uri = ('https://api.forecast.io\/forecast\/(\w+)\/' + uri = ('https://api.darksky.net\/forecast\/(\w+)\/' '(-?\d+\.?\d*),(-?\d+\.?\d*)') m.get(re.compile(uri), - text=load_fixture('forecast.json')) - forecast.setup_platform(self.hass, self.config, MagicMock()) + text=load_fixture('darksky.json')) + darksky.setup_platform(self.hass, self.config, MagicMock()) self.assertTrue(mock_get_forecast.called) self.assertEqual(mock_get_forecast.call_count, 1) diff --git a/tests/fixtures/forecast.json b/tests/fixtures/darksky.json similarity index 100% rename from tests/fixtures/forecast.json rename to tests/fixtures/darksky.json