diff --git a/homeassistant/components/sensor/openweathermap.py b/homeassistant/components/sensor/openweathermap.py new file mode 100644 index 00000000000..ed5520a3817 --- /dev/null +++ b/homeassistant/components/sensor/openweathermap.py @@ -0,0 +1,174 @@ +""" +homeassistant.components.sensor.openweathermap +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +OpenWeatherMap (OWM) service. + +Configuration: + +To use the OpenWeatherMap sensor you will need to add something like the +following to your config/configuration.yaml + +sensor: + platform: openweathermap + api_key: YOUR_APP_KEY + monitored_variables: + - type: 'weather' + - type: 'temperature' + - type: 'wind_speed' + - type: 'humidity' + - type: 'pressure' + - type: 'clouds' + - type: 'rain' + - type: 'snow' + +VARIABLES: + +api_key +*Required +To retrieve this value log into your account at http://openweathermap.org/ + +monitored_variables +*Required +An array specifying the variables to monitor. + +These are the variables for the monitored_variables array: + +type +*Required +The variable you wish to monitor, see the configuration example above for a +list of all available variables + +Details for the API : http://bugs.openweathermap.org/projects/api/wiki + +Only metric measurements are supported at the moment. + +""" +import logging + +from homeassistant.const import (CONF_API_KEY, TEMP_CELCIUS, TEMP_FAHRENHEIT) +from homeassistant.helpers.entity import Entity + +_LOGGER = logging.getLogger(__name__) +_THROTTLED_REFRESH = None +SENSOR_TYPES = { + 'weather': ['Condition', ''], + 'temperature': ['Temperature', ''], + 'wind_speed': ['Wind speed', 'm/s'], + 'humidity': ['Humidity', '%'], + 'pressure': ['Pressure', 'hPa'], + 'clouds': ['Cloud coverage', '%'], + 'rain': ['Rain', 'mm'], + 'snow': ['Snow', 'mm'] +} + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """ Get the OpenWeatherMap sensor. """ + + if None in (hass.config.latitude, hass.config.longitude): + _LOGGER.error("Latitude or longitude not set in Home Assistant config") + return False + + try: + from pyowm import OWM + + except ImportError: + _LOGGER.exception( + "Unable to import pyowm. " + "Did you maybe not install the 'PyOWM' package?") + + return None + + SENSOR_TYPES['temperature'][1] = hass.config.temperature_unit + unit = hass.config.temperature_unit + owm = OWM(config.get(CONF_API_KEY, None)) + obs = owm.weather_at_coords(hass.config.latitude, hass.config.longitude) + + if not owm: + _LOGGER.error( + "Connection error " + "Please check your settings for OpenWeatherMap.") + return None + + dev = [] + for variable in config['monitored_variables']: + if variable['type'] not in SENSOR_TYPES: + _LOGGER.error('Sensor type: "%s" does not exist', variable['type']) + else: + dev.append(OpenWeatherMapSensor(variable['type'], obs, unit)) + + add_devices(dev) + + +# pylint: disable=too-few-public-methods +class OpenWeatherMapSensor(Entity): + """ Implements an OpenWeatherMap sensor. """ + + def __init__(self, sensor_type, weather_data, unit): + self.client_name = 'Weather - ' + self._name = SENSOR_TYPES[sensor_type][0] + self.owa_client = weather_data + self._unit = unit + self.type = sensor_type + self._state = None + self._unit_of_measurement = SENSOR_TYPES[sensor_type][1] + self.update() + + @property + def name(self): + return self.client_name + ' ' + self._name + + @property + def state(self): + """ Returns the state of the device. """ + return self._state + + @property + def unit_of_measurement(self): + """ Unit of measurement of this entity, if any. """ + return self._unit_of_measurement + + # pylint: disable=too-many-branches + def update(self): + """ Gets the latest data from OWM and updates the states. """ + data = self.owa_client.get_weather() + + if self.type == 'weather': + self._state = data.get_detailed_status() + + if self.type == 'temperature': + if self._unit == TEMP_CELCIUS: + self._state = round(data.get_temperature('celsius')['temp'], + 1) + elif self._unit == TEMP_FAHRENHEIT: + self._state = round(data.get_temperature('fahrenheit')['temp'], + 1) + else: + self._state = round(data.get_temperature()['temp'], 1) + + elif self.type == 'wind_speed': + self._state = data.get_wind()['speed'] + + elif self.type == 'humidity': + self._state = data.get_humidity() + + elif self.type == 'pressure': + self._state = round(data.get_pressure()['press'], 0) + + elif self.type == 'clouds': + self._state = data.get_clouds() + + elif self.type == 'rain': + if data.get_rain(): + self._state = round(data.get_rain()['3h'], 0) + else: + self._state = 'not raining' + self._unit_of_measurement = '' + + elif self.type == 'snow': + if data.get_snow(): + self._state = round(data.get_snow(), 0) + else: + self._state = 'not snowing' + self._unit_of_measurement = ''