Outdoor Environment - Pollen and UV-Index and more Included!

:herb: Outdoor Environment — 80+ environmental sensors from Open-Meteo,

no API key, no account, no excuses

I built this integration because I wanted Home Assistant to know what was
happening outside my house — not just temperature and rain, but the full
picture: air quality, UV index, pollen levels, solar radiation, soil moisture.
The kind of data that actually changes what automations make sense to run.

Open-Meteo is free, accurate, and doesn't require registration.
It felt like an obvious fit.


The idea is simple: you configure your location once, and the integration
creates sensors. Each sensor maps to a specific environmental metric.
HA records them over time, so you get history, charts, and trends —
all with the tools you already have.

When pollen is high, close the windows automatically. When UV is extreme,
send a notification. When soil moisture drops below a threshold, trigger
the irrigation. The integration just exposes the data — what you do with
it is entirely up to your setup.

What it tracks:

  • :thermometer: Weather — temperature, humidity, wind speed & direction,
    precipitation, cloud cover, visibility, pressure
  • :dashing_away: Air quality — PM2.5, PM10, CO, NO₂, SO₂, ozone,
    European AQI, US AQI
  • :sun: Solar & UV — UV index, UV index clear sky,
    shortwave & direct radiation, sunshine duration
  • :cherry_blossom: Pollen — grass, tree, weed (where available by region)
  • :seedling: Agro metrics — soil temperature (multiple depths),
    soil moisture, evapotranspiration, leaf wetness
  • :ocean: Marine (coastal locations) — wave height, wave direction,
    wave period

80+ sensors total — you pick which ones to enable.
No need to create 80 entities if you only care about 10.


No API key. No account. No third-party service in the middle.
Just HA pulling data from Open-Meteo the same way your browser would.

Polling is configurable and conservative by default —
environmental data doesn't change by the second, so there's no reason
to hammer the endpoint.


Installation: HACS (pending official listing —
you can add the repo manually in the meantime) or copy the folder directly.

GitHub:


Still early — regional availability for pollen data varies depending on
location, and marine sensors only make sense for coastal setups.
Happy to hear what's missing or broken in your specific case.
Feedback and PRs welcome :folded_hands:

1 Like

I wanted to try it but I can't set it up correctl.

The log says:

Logger: homeassistant.config_entries
Quelle: config_entries.py:769
Erstmals aufgetreten: 10:19:18 (2 Vorkommnisse)
Zuletzt protokolliert: 10:19:25

Error setting up entry Outdoor Environment for outdoor_environment
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1280, in _load_platform
    cache[full_name] = self._import_platform(platform_name)
                       ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1312, in _import_platform
    return importlib.import_module(f"{self.pkg_path}.{platform_name}")
           ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/util/loop.py", line 201, in protected_loop_func
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.14/importlib/__init__.py", line 88, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1398, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1371, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1342, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 938, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 759, in exec_module
  File "<frozen importlib._bootstrap>", line 491, in _call_with_frames_removed
  File "/config/custom_components/outdoor_environment/sensor.py", line 136, in <module>
    device_class=SensorDeviceClass.CARBON_MONOXIDE,
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: type object 'SensorDeviceClass' has no attribute 'CARBON_MONOXIDE'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 769, in __async_setup_with_context
    result = await component.async_setup_entry(hass, self)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/outdoor_environment/__init__.py", line 74, in async_setup_entry
    await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 2683, in async_forward_entry_setups
    await integration.async_get_platforms(platforms)
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1193, in async_get_platforms
    import_future.result()
    ~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1181, in async_get_platforms
    platforms.update(self._load_platforms(platform_names))
                     ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1106, in _load_platforms
    platform_name: self._load_platform(platform_name)
                   ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1300, in _load_platform
    raise ImportError(
        f"Exception importing {self.pkg_path}.{platform_name}"
    ) from err
ImportError: Exception importing custom_components.outdoor_environment.sensor

Same here, not working:

Logger: homeassistant.config_entries
Quelle: config_entries.py:787
Erstmals aufgetreten: 10:53:48 (1 Vorkommnis)
Zuletzt protokolliert: 10:53:48

Error setting up entry Outdoor Environment for outdoor_environment
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1281, in _load_platform
    cache[full_name] = self._import_platform(platform_name)
                       ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1313, in _import_platform
    return importlib.import_module(f"{self.pkg_path}.{platform_name}")
           ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/util/loop.py", line 201, in protected_loop_func
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.14/importlib/__init__.py", line 88, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1398, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1371, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1342, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 938, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 759, in exec_module
  File "<frozen importlib._bootstrap>", line 491, in _call_with_frames_removed
  File "/config/custom_components/outdoor_environment/sensor.py", line 136, in <module>
    device_class=SensorDeviceClass.CARBON_MONOXIDE,
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: type object 'SensorDeviceClass' has no attribute 'CARBON_MONOXIDE'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 787, in __async_setup_with_context
    result = await component.async_setup_entry(hass, self)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/outdoor_environment/__init__.py", line 74, in async_setup_entry
    await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 2727, in async_forward_entry_setups
    await integration.async_get_platforms(platforms)
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1194, in async_get_platforms
    import_future.result()
    ~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1182, in async_get_platforms
    platforms.update(self._load_platforms(platform_names))
                     ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1107, in _load_platforms
    platform_name: self._load_platform(platform_name)
                   ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1301, in _load_platform
    raise ImportError(
        f"Exception importing {self.pkg_path}.{platform_name}"
    ) from err
ImportError: Exception importing custom_components.outdoor_environment.sensor
Logger: homeassistant.loader
Quelle: loader.py:1281
Erstmals aufgetreten: 10:53:48 (2 Vorkommnisse)
Zuletzt protokolliert: 10:53:48

Unexpected exception importing platform custom_components.outdoor_environment.sensor
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1281, in _load_platform
    cache[full_name] = self._import_platform(platform_name)
                       ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1313, in _import_platform
    return importlib.import_module(f"{self.pkg_path}.{platform_name}")
           ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/util/loop.py", line 201, in protected_loop_func
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.14/importlib/__init__.py", line 88, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1398, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1371, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1342, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 938, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 759, in exec_module
  File "<frozen importlib._bootstrap>", line 491, in _call_with_frames_removed
  File "/config/custom_components/outdoor_environment/sensor.py", line 136, in <module>
    device_class=SensorDeviceClass.CARBON_MONOXIDE,
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: type object 'SensorDeviceClass' has no attribute 'CARBON_MONOXIDE'
Logger: homeassistant.util.loop
Quelle: util/loop.py:137
Erstmals aufgetreten: 10:53:48 (1 Vorkommnis)
Zuletzt protokolliert: 10:53:48

Detected blocking call to import_module with args ('custom_components.outdoor_environment.sensor',) inside the event loop by custom integration 'outdoor_environment' at custom_components/outdoor_environment/__init__.py, line 74: await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) (offender: /usr/src/homeassistant/homeassistant/loader.py, line 1313: return importlib.import_module(f"{self.pkg_path}.{platform_name}")), please create a bug report at https://github.com/nuggetz/ha-outdoor-environment/issues For developers, please see https://developers.home-assistant.io/docs/asyncio_blocking_operations/#import_module Traceback (most recent call last): File "<frozen runpy>", line 198, in _run_module_as_main File "<frozen runpy>", line 88, in _run_code File "/usr/src/homeassistant/homeassistant/__main__.py", line 229, in <module> sys.exit(main()) File "/usr/src/homeassistant/homeassistant/__main__.py", line 215, in main exit_code = runner.run(runtime_conf) File "/usr/src/homeassistant/homeassistant/runner.py", line 289, in run return loop.run_until_complete(setup_and_run_hass(runtime_config)) File "/usr/local/lib/python3.14/asyncio/base_events.py", line 706, in run_until_complete self.run_forever() File "/usr/local/lib/python3.14/asyncio/base_events.py", line 677, in run_forever self._run_once() File "/usr/local/lib/python3.14/asyncio/base_events.py", line 2046, in _run_once handle._run() File "/usr/local/lib/python3.14/asyncio/events.py", line 94, in _run self._context.run(self._callback, *self._args) File "/usr/src/homeassistant/homeassistant/config_entries.py", line 955, in async_setup_locked await self.async_setup(hass, integration=integration) File "/usr/src/homeassistant/homeassistant/config_entries.py", line 694, in async_setup await self.__async_setup_with_context(hass, integration) File "/usr/src/homeassistant/homeassistant/config_entries.py", line 787, in __async_setup_with_context result = await component.async_setup_entry(hass, self) File "/config/custom_components/outdoor_environment/__init__.py", line 74, in async_setup_entry await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

Hi, thanks for the report — this is a known issue that's already fixed.

The v0.1.0 release was built against an older HA API. In current Home Assistant versions (Python 3.14), SensorDeviceClass.CARBON_MONOXIDE has been renamed to SensorDeviceClass.CO, which caused the import error.

Fix: update to v0.1.1, just released. If you installed via HACS, simply update from the HACS panel. If you installed manually, replace the custom_components/outdoor_environment/ folder with the new version and restart HA.

Sorry for the inconvenience and thanks again for reporting!