diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/README.md b/README.md index 4a17fb2..dcabe1b 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,28 @@ -# homeassistant-airthings -Quick n' dirty hack to get Airthings Wave Plus sensor into Home Assistant. Beware, very untested. Only works with Airthings Wave Plus. +# Airthings Wave Plus Environment Sensor for Home Assistant + +This was developed by [@gkreitz](https://github.com/gkreitz) and forked from (https://github.com/gkreitz/homeassistant-airthings) + +Quick n' dirty hack to get [Airthings Wave Plus](https://amazon.com/Airthings-2930-Quality-Detection-Dashboard/dp/B07JB8QWH6?tag=rynoshark-20) indoor air quality sensors into Home Assistant. + +**Beware, very untested. Only works with Airthings Wave Plus.** I wanted something to read my Airthings Wave Plus, so I built this. Far from production quality. Magic hardcoded constants. Reads data the wrong way to work around a bug. Tested on a single device. Only supports a single Wave Plus. Does not construct a unique id for the sensor. Figured I may as well upload in case it's useful to someone else. ## Installation + 1. Find out the MAC address of your Airthings Wave Plus. See https://airthings.com/us/raspberry-pi/ for how to find MAC address. -1. Put `__init__.py`, `sensor.py`, `manifest.json` into `/custom_components/airthings/` on your home assistant installation (where `` is the directory where your config file resides). +1. This fork made for intergation through HACS. 1. Add the following to your `configuration.yaml` (or modify your `sensor` heading, if you already have one): + ```yaml sensor: - - platform: airthings + - platform: airthings_wave_plus mac: 00:11:22:AA:BB:CC # replace with MAC of your Airthings Wave+ ``` -Then restart home assistant and if everything works, you'll have some new sensors named `sensor.airthings_{co2,humidity,longterm_radon,pressure,shortterm_radon,temperature,voc}` +Then restart Home Assistant and if everything works, you'll have some new sensors named `sensor.airthings_{co2,humidity,longterm_radon,pressure,shortterm_radon,temperature,voc}` + +### See Also + +* [Airthings Wave Plus discussion forum on Home Assistant](https://community.home-assistant.io/t/air-quality-monitor-radon-meter-airthings-wave-plus/102836) +* [Airthings for Home Assistant](https://github.com/custom-components/sensor.airthings_wave) (does not support Wave Plus) diff --git a/__init__.py b/custom_components/airthings_wave_plus/__init__.py similarity index 100% rename from __init__.py rename to custom_components/airthings_wave_plus/__init__.py diff --git a/manifest.json b/custom_components/airthings_wave_plus/manifest.json similarity index 72% rename from manifest.json rename to custom_components/airthings_wave_plus/manifest.json index 7c2e8fb..408e05f 100644 --- a/manifest.json +++ b/custom_components/airthings_wave_plus/manifest.json @@ -1,6 +1,6 @@ { - "domain": "airthings", - "name": "Airthings Wave+", + "domain": "airthings_wave_plus", + "name": "Airthings Wave Plus", "documentation": "https://github.com/gkreitz/homeassistant-airthings", "dependencies": [], "requirements": ["pygatt[GATTTOOL]==4.0.3"], diff --git a/sensor.py b/custom_components/airthings_wave_plus/sensor.py similarity index 65% rename from sensor.py rename to custom_components/airthings_wave_plus/sensor.py index 38ae7aa..cbf078e 100644 --- a/sensor.py +++ b/custom_components/airthings_wave_plus/sensor.py @@ -12,7 +12,8 @@ _LOGGER = logging.getLogger(__name__) -DOMAIN = 'airthings' +DOMAIN = 'airthings_wave_plus' + CONF_MAC = 'mac' PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ @@ -20,28 +21,32 @@ }) MIN_TIME_BETWEEN_UPDATES = datetime.timedelta(minutes=15) + SENSOR_TYPES = [ - ['temperature', 'Temperature', TEMP_CELSIUS, None, DEVICE_CLASS_TEMPERATURE], - ['co2', 'CO2', 'ppm', 'mdi:cloud', None], - ['pressure', 'Pressure', 'mbar', 'mdi:gauge', DEVICE_CLASS_PRESSURE], - ['humidity', 'Humidity', '%', None, DEVICE_CLASS_HUMIDITY], - ['voc', 'VOC', 'ppm', 'mdi:cloud', None], - ['short_radon', 'Short-term Radon', 'Bq/m3', 'mdi:cloud', None], - ['long_radon', 'Long-term Radon', 'Bq/m3', 'mdi:cloud', None], + # key name unit icon device class + [ 'temperature', 'Temperature', TEMP_CELSIUS, None, DEVICE_CLASS_TEMPERATURE ], + [ 'co2', 'CO2', 'ppm', 'mdi:cloud', None ], + [ 'pressure', 'Pressure', 'mbar', 'mdi:gauge', DEVICE_CLASS_PRESSURE ], + [ 'humidity', 'Humidity', '%', None, DEVICE_CLASS_HUMIDITY ], + [ 'voc', 'VOC', 'ppm', 'mdi:cloud', None ], + [ 'short_radon', 'Short-term Radon', 'Bq/m3', 'mdi:cloud', None ], + [ 'long_radon', 'Long-term Radon', 'Bq/m3', 'mdi:cloud', None ], ] - def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the sensor platform.""" - _LOGGER.debug("Starting airthings") reader = AirthingsWavePlusDataReader(config.get(CONF_MAC)) - add_devices([ AirthingsSensorEntity(reader, key,name,unit,icon,device_class) for [key, name, unit, icon, device_class] in SENSOR_TYPES]) + + sensors = [] + for [key, name, unit, icon, device_class] in SENSOR_TYPES: + sensors.append( AirthingsSensorEntity(reader, key, name, unit, icon, device_class) ) + add_devices(sensors) class AirthingsWavePlusDataReader: def __init__(self, mac): self._mac = mac - self._state = { } + self._state = {} def get_data(self, key): if key in self._state: @@ -54,27 +59,32 @@ def mac(self): @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): - _LOGGER.debug("Airthings updating data") + _LOGGER.debug(f"Updating data from Airthings Wave Plus {self._mac}") + import pygatt from pygatt.backends import Characteristic adapter = pygatt.backends.GATTToolBackend() - char = 'b42e2a68-ade7-11e4-89d3-123b93f75cba' + #char = 'b42e2a68-ade7-11e4-89d3-123b93f75cba' + try: - # reset_on_start must be false - reset is hardcoded to do sudo, which does not exist in the hass.io Docker container. + # reset_on_start must be false - reset is hardcoded to execute sudo, which doesn't exist + # in the hass.io Docker container. adapter.start(reset_on_start=False) device = adapter.connect(self._mac) + # Unclear why this does not work. Seems broken in the command line tool too. Hopefully handle is stable... #value = device.char_read(char,timeout=10) value = device.char_read_handle('0x000d',timeout=10) (humidity, light, sh_rad, lo_rad, temp, pressure, co2, voc) = struct.unpack('