Skip to content

Commit

Permalink
Merge 3f31a36 into ab8cf4f
Browse files Browse the repository at this point in the history
  • Loading branch information
fabaff committed Dec 11, 2018
2 parents ab8cf4f + 3f31a36 commit da5a883
Show file tree
Hide file tree
Showing 5 changed files with 276 additions and 0 deletions.
176 changes: 176 additions & 0 deletions homeassistant/components/air_pollutants/__init__.py
@@ -0,0 +1,176 @@
"""
Component for handling Air Pollutants data for your location.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/air_pollutants/
"""
from datetime import timedelta
import logging

from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
from homeassistant.helpers.entity import Entity

_LOGGER = logging.getLogger(__name__)

ATTR_AIR_POLLUTANTS_AQI = 'air_quality_index'
ATTR_AIR_POLLUTANTS_ATTRIBUTION = 'attribution'
ATTR_AIR_POLLUTANTS_C02 = 'carbon_dioxide'
ATTR_AIR_POLLUTANTS_CO = 'carbon_monoxide'
ATTR_AIR_POLLUTANTS_N2O = 'nitrogen_oxide'
ATTR_AIR_POLLUTANTS_NO = 'nitrogen_monoxide'
ATTR_AIR_POLLUTANTS_NO2 = 'nitrogen_dioxide'
ATTR_AIR_POLLUTANTS_OZONE = 'ozone'
ATTR_AIR_POLLUTANTS_PM_0_1 = 'particulate_matter_0_1'
ATTR_AIR_POLLUTANTS_PM_10 = 'particulate_matter_10'
ATTR_AIR_POLLUTANTS_PM_2_5 = 'particulate_matter_2_5'
ATTR_AIR_POLLUTANTS_SO2 = 'sulphur_dioxide'

DOMAIN = 'air_pollutants'

ENTITY_ID_FORMAT = DOMAIN + '.{}'

SCAN_INTERVAL = timedelta(seconds=30)


async def async_setup(hass, config):
"""Set up the air pollutants component."""
component = hass.data[DOMAIN] = EntityComponent(
_LOGGER, DOMAIN, hass, SCAN_INTERVAL)
await component.async_setup(config)
return True


async def async_setup_entry(hass, entry):
"""Set up a config entry."""
return await hass.data[DOMAIN].async_setup_entry(entry)


async def async_unload_entry(hass, entry):
"""Unload a config entry."""
return await hass.data[DOMAIN].async_unload_entry(entry)


class AirPollutantsEntity(Entity):
"""ABC for air pollutants data."""

@property
def particulate_matter_2_5(self):
"""Return the particulate matter 2.5 level."""
raise NotImplementedError()

@property
def particulate_matter_10(self):
"""Return the particulate matter 10 level."""
return None

@property
def particulate_matter_0_1(self):
"""Return the particulate matter 0.1 level."""
return None

@property
def temperature_unit(self):
"""Return the unit of measurement of the temperature."""
return None

@property
def air_quality_index(self):
"""Return the Air Quality Index (AQI)."""
return None

@property
def ozone(self):
"""Return the O3 (ozone) level."""
return None

@property
def carbon_monoxide(self):
"""Return the CO (carbon monoxide) level."""
return None

@property
def carbon_dioxide(self):
"""Return the CO2 (carbon dioxide) level."""
return None

@property
def attribution(self):
"""Return the attribution."""
return None

@property
def sulphur_dioxide(self):
"""Return the SO2 (sulphur dioxide) level."""
return None

@property
def nitrogen_oxide(self):
"""Return the N2O (nitrogen oxide) level."""
return None

@property
def nitrogen_monoxide(self):
"""Return the NO (nitrogen monoxide) level."""
return None

@property
def nitrogen_dioxide(self):
"""Return the NO2 (nitrogen dioxide) level."""
return None

@property
def state_attributes(self):
"""Return the state attributes."""
data = {}

air_quality_index = self.air_quality_index
if air_quality_index is not None:
data[ATTR_AIR_POLLUTANTS_AQI] = air_quality_index

ozone = self.ozone
if ozone is not None:
data[ATTR_AIR_POLLUTANTS_OZONE] = ozone

particulate_matter_0_1 = self.particulate_matter_0_1
if particulate_matter_0_1 is not None:
data[ATTR_AIR_POLLUTANTS_PM_0_1] = particulate_matter_0_1

particulate_matter_10 = self.particulate_matter_10
if particulate_matter_10 is not None:
data[ATTR_AIR_POLLUTANTS_PM_10] = particulate_matter_10

sulphur_dioxide = self.sulphur_dioxide
if sulphur_dioxide is not None:
data[ATTR_AIR_POLLUTANTS_SO2] = sulphur_dioxide

nitrogen_oxide = self.nitrogen_oxide
if nitrogen_oxide is not None:
data[ATTR_AIR_POLLUTANTS_N2O] = nitrogen_oxide

nitrogen_monoxide = self.nitrogen_monoxide
if nitrogen_monoxide is not None:
data[ATTR_AIR_POLLUTANTS_NO] = nitrogen_monoxide

nitrogen_dioxide = self.nitrogen_dioxide
if nitrogen_dioxide is not None:
data[ATTR_AIR_POLLUTANTS_NO2] = nitrogen_dioxide

carbon_dioxide = self.carbon_dioxide
if carbon_dioxide is not None:
data[ATTR_AIR_POLLUTANTS_C02] = carbon_dioxide

carbon_monoxide = self.carbon_monoxide
if carbon_monoxide is not None:
data[ATTR_AIR_POLLUTANTS_CO] = carbon_monoxide

attribution = self.attribution
if attribution is not None:
data[ATTR_AIR_POLLUTANTS_ATTRIBUTION] = attribution

return data

@property
def state(self):
"""Return the current state."""
return self.particulate_matter_2_5
56 changes: 56 additions & 0 deletions homeassistant/components/air_pollutants/demo.py
@@ -0,0 +1,56 @@
"""
Demo platform that offers fake air pollutants data.
For more details about this platform, please refer to the documentation
https://home-assistant.io/components/demo/
"""
from homeassistant.components.air_pollutants import AirPollutantsEntity


def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Air Pollutants."""
add_entities([
DemoAirPollutants('Home', 14, 23, 100),
DemoAirPollutants('Office', 4, 16, None)
])


class DemoAirPollutants(AirPollutantsEntity):
"""Representation of Air Pollutants data."""

def __init__(self, name, pm_2_5, pm_10, n2o):
"""Initialize the Demo Air Pollutants."""
self._name = name
self._pm_2_5 = pm_2_5
self._pm_10 = pm_10
self._n2o = n2o

@property
def name(self):
"""Return the name of the sensor."""
return '{} {}'.format('Demo Air Pollutants', self._name)

@property
def should_poll(self):
"""No polling needed for Demo Air Pollutants."""
return False

@property
def particulate_matter_2_5(self):
"""Return the particulate matter 2.5 level."""
return self._pm_2_5

@property
def particulate_matter_10(self):
"""Return the particulate matter 10 level."""
return self._pm_10

@property
def nitrogen_oxide(self):
"""Return the nitrogen oxide (N2O) level."""
return self._n2o

@property
def attribution(self):
"""Return the attribution."""
return 'Powered by Home Assistant'
1 change: 1 addition & 0 deletions homeassistant/components/demo.py
Expand Up @@ -15,6 +15,7 @@
DOMAIN = 'demo'

COMPONENTS_WITH_DEMO_PLATFORM = [
'air_pollutants',
'alarm_control_panel',
'binary_sensor',
'calendar',
Expand Down
1 change: 1 addition & 0 deletions tests/components/air_pollutants/__init__.py
@@ -0,0 +1 @@
"""The tests for Air Pollutants platforms."""
42 changes: 42 additions & 0 deletions tests/components/air_pollutants/test_air_pollutants.py
@@ -0,0 +1,42 @@
"""The tests for the Air Pollutants component."""
from homeassistant.components.air_pollutants import (
ATTR_AIR_POLLUTANTS_ATTRIBUTION, ATTR_AIR_POLLUTANTS_N2O,
ATTR_AIR_POLLUTANTS_OZONE, ATTR_AIR_POLLUTANTS_PM_10)
from homeassistant.setup import async_setup_component


async def test_state(hass):
"""Test Air Pollutants state."""
config = {
'air_pollutants': {
'platform': 'demo',
}
}

assert await async_setup_component(hass, 'air_pollutants', config)

state = hass.states.get('air_pollutants.demo_air_pollutants_home')
assert state is not None

assert state.state == '14'


async def test_attributes(hass):
"""Test Air Pollutants attributes."""
config = {
'air_pollutants': {
'platform': 'demo',
}
}

assert await async_setup_component(hass, 'air_pollutants', config)

state = hass.states.get('air_pollutants.demo_air_pollutants_office')
assert state is not None

data = state.attributes
assert data.get(ATTR_AIR_POLLUTANTS_PM_10) == 16
assert data.get(ATTR_AIR_POLLUTANTS_N2O) is None
assert data.get(ATTR_AIR_POLLUTANTS_OZONE) is None
assert data.get(ATTR_AIR_POLLUTANTS_ATTRIBUTION) == \
'Powered by Home Assistant'

0 comments on commit da5a883

Please sign in to comment.