From 9c8e10936b0682696f1a9add2aceeb141f4de9d6 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 18 Dec 2018 09:15:07 +0100 Subject: [PATCH] Add openSenseMap air pollutants platform (#19357) * Add openSenseMap air pollutants platform * Fix issues (Docstring, log entries and check) * Use SCAN_INTERVAL and name handling --- .coveragerc | 1 + .../components/air_pollutants/opensensemap.py | 105 ++++++++++++++++++ requirements_all.txt | 3 + 3 files changed, 109 insertions(+) create mode 100644 homeassistant/components/air_pollutants/opensensemap.py diff --git a/.coveragerc b/.coveragerc index 552d7fa7460..4e1bdc43ecd 100644 --- a/.coveragerc +++ b/.coveragerc @@ -431,6 +431,7 @@ omit = homeassistant/components/spider.py homeassistant/components/*/spider.py + homeassistant/components/air_pollutants/opensensemap.py homeassistant/components/alarm_control_panel/alarmdotcom.py homeassistant/components/alarm_control_panel/canary.py homeassistant/components/alarm_control_panel/concord232.py diff --git a/homeassistant/components/air_pollutants/opensensemap.py b/homeassistant/components/air_pollutants/opensensemap.py new file mode 100644 index 00000000000..ae4625bbbe9 --- /dev/null +++ b/homeassistant/components/air_pollutants/opensensemap.py @@ -0,0 +1,105 @@ +""" +Support for openSenseMap Air Pollutants data. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/air_pollutants_opensensemap/ +""" +from datetime import timedelta +import logging + +import voluptuous as vol + +from homeassistant.components.air_pollutants import ( + PLATFORM_SCHEMA, AirPollutantsEntity) +from homeassistant.const import CONF_NAME +from homeassistant.helpers.aiohttp_client import async_get_clientsession +import homeassistant.helpers.config_validation as cv +from homeassistant.util import Throttle + +REQUIREMENTS = ['opensensemap-api==0.1.3'] + +_LOGGER = logging.getLogger(__name__) + +ATTRIBUTION = 'Data provided by openSenseMap' + +CONF_STATION_ID = 'station_id' + +SCAN_INTERVAL = timedelta(minutes=10) + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_STATION_ID): cv.string, + vol.Optional(CONF_NAME): cv.string, +}) + + +async def async_setup_platform( + hass, config, async_add_entities, discovery_info=None): + """Set up the openSenseMap air pollutants platform.""" + from opensensemap_api import OpenSenseMap + + name = config.get(CONF_NAME) + station_id = config[CONF_STATION_ID] + + session = async_get_clientsession(hass) + osm_api = OpenSenseMapData(OpenSenseMap(station_id, hass.loop, session)) + + await osm_api.async_update() + + if 'name' not in osm_api.api.data: + _LOGGER.error("Station %s is not available", station_id) + return + + station_name = osm_api.api.data['name'] if name is None else name + + async_add_entities([OpenSenseMapPollutants(station_name, osm_api)], True) + + +class OpenSenseMapPollutants(AirPollutantsEntity): + """Implementation of an openSenseMap air pollutants entity.""" + + def __init__(self, name, osm): + """Initialize the air pollutants entity.""" + self._name = name + self._osm = osm + + @property + def name(self): + """Return the name of the air pollutants entity.""" + return self._name + + @property + def particulate_matter_2_5(self): + """Return the particulate matter 2.5 level.""" + return self._osm.api.pm2_5 + + @property + def particulate_matter_10(self): + """Return the particulate matter 10 level.""" + return self._osm.api.pm10 + + @property + def attribution(self): + """Return the attribution.""" + return ATTRIBUTION + + async def async_update(self): + """Get the latest data from the openSenseMap API.""" + await self._osm.async_update() + + +class OpenSenseMapData: + """Get the latest data and update the states.""" + + def __init__(self, api): + """Initialize the data object.""" + self.api = api + + @Throttle(SCAN_INTERVAL) + async def async_update(self): + """Get the latest data from the Pi-hole.""" + from opensensemap_api.exceptions import OpenSenseMapError + + try: + await self.api.get_data() + except OpenSenseMapError as err: + _LOGGER.error("Unable to fetch data: %s", err) diff --git a/requirements_all.txt b/requirements_all.txt index 8221f0370cc..7be17c6e4f6 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -732,6 +732,9 @@ openevsewifi==0.4 # homeassistant.components.media_player.openhome openhomedevice==0.4.2 +# homeassistant.components.air_pollutants.opensensemap +opensensemap-api==0.1.3 + # homeassistant.components.switch.orvibo orvibo==1.1.1