core
core copied to clipboard
Add WeatherFlow integration
Proposed change
@natekspencer created a HACS Integration for the WeatherFlow tempest weather station. I've decided to migrate his code over into an official integration (with his permission).
This implements a single platform PLATFORM.SENSOR
which will display just about the entire swatch of available data. It uses a backing library to gather this data via UDP from the base station. Weather flow puts out UDP documentation so this would be a semi-official integration I guess as the API is published.
Reference Material
- https://weatherflow.github.io/Tempest/api/udp.html
- https://github.com/briis/pyweatherflowudp

Type of change
- [ ] Dependency upgrade
- [ ] Bugfix (non-breaking change which fixes an issue)
- [x] New integration (thank you!)
- [ ] New feature (which adds functionality to an existing integration)
- [ ] Deprecation (breaking change to happen in the future)
- [ ] Breaking change (fix/feature causing existing functionality to break)
- [ ] Code quality improvements to existing code or addition of tests
Additional information
- This PR fixes or closes issue: fixes #
- This PR is related to issue:
- Link to documentation pull request: https://github.com/home-assistant/home-assistant.io/pull/23478
Checklist
- [x] The code change is tested and works locally.
- [x] Local tests pass. Your PR cannot be merged unless tests pass
- [x] There is no commented out code in this PR.
- [x] I have followed the development checklist
- [x] The code has been formatted using Black (
black --fast homeassistant tests
) - [x] Tests have been added to verify that the new code works.
If user exposed functionality or configuration variables are added/changed:
- [x] Documentation added/updated for www.home-assistant.io
If the code communicates with devices, web services, or third-party tools:
- [x] The manifest file has all fields filled out correctly.
Updated and included derived files by running:python3 -m script.hassfest
. - [x] New or updated dependencies have been added to
requirements_all.txt
.
Updated by runningpython3 -m script.gen_requirements_all
. - [ ] For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.
- [x] Untested files have been added to
.coveragerc
.
The integration reached or maintains the following Integration Quality Scale:
- [x] No score or internal
- [ ] π₯ Silver
- [ ] π₯ Gold
- [ ] π Platinum
To help with the load of incoming pull requests:
- [x] I have reviewed two other open pull requests in this repository.
And the wait continues... but that's ok :) ....
@jeeftor Please don't ping for reviews. That is not acceptable or wished for. And to make it actually not work, I generally skip PRs that actually ping/ask.
Apologies
@natekspencer - did you make updates recently I need to pull in?
You might want to disable wind speed and wind direction by default as they are updated 20 times per minute. The wind average and wind direction average are updated once per minute like the other sensors.
Edit: corrected typo
You might want to disable wind speed and wind direction by default as they are updated 20 times per second. The wind average and wind direction average are updated once per minute like the other sensors.
It's actually around 20 times per minute (every 3 seconds). While still frequent, I would argue that it's one of the more relevant sensors.
It's actually around 20 times per minute (every 3 seconds). While still frequent, I would argue that it's one of the more relevant sensors.
Oops, typo. Corrected. Thanks for catching. But it's still a valid question as those two sensors accounted for around half of all data in my HA database.
It's actually around 20 times per minute (every 3 seconds). While still frequent, I would argue that it's one of the more relevant sensors.
Oops, typo. Corrected. Thanks for catching. But it's still a valid question as those two sensors accounted for around half of all data in my HA database.
Yeah, agreed. Wind direction for me is less relevant. But wind speed is crucial. Sometimes a minute delay is too long and can cause serious damage. I get frequent wind which can spike very quickly. Being able to react to the first such spike is important as a full minute of sustained high winds can be disastrous. I guess the question is, should it be disabled by default with a note saying to enable it if you need it. Or should it be enabled by default with a note saying it may cause a large HA database and disable if unneeded?
But wind speed is crucial. Sometimes a minute delay is too long and can cause serious damage. I get frequent wind which can spike very quickly. Being able to react to the first such spike is important as a full minute of sustained high winds can be disastrous.
It would be nice to be able to use the data for automations without being stored. Or maybe have a different retention period.
It would be nice to be able to use the data for automations without being stored. Or maybe have a different retention period.
True. The immediate value is wonderful for automations. After that, I only really care about the statistics of it and don't need the rest of the granularity.
Well this has been open for some time now ... I'm hoping somebody will take a look at it finally....
Well this has been open for some time now ... I'm hoping somebody will take a look at it finally....
Working well for several months now, if that positive data point helps.
@HyperActiveJ - Are you running the HACS version ... This would be an official version... and it would eventually move out of HACS - making it more widely available to the "slightly less nerdy" folks who just install vanilla HA
@HyperActiveJ - Are you running the HACS version ... This would be an official version... and it would eventually move out of HACS - making it more widely available to the "slightly less nerdy" folks who just install vanilla HA
Understood, I've just been pulling source from your repo.
I commend your patience getting this integrated into HA. But it's sad that the dev team continues to ignore this contribution. π
I wonder if we should just include a couple of sensors (like temperature and humidity) initially to reduce the code needed to review.
I wonder if we should just include a couple of sensors (like temperature and humidity) initially to reduce the code needed to review.
The HA component is less than 600 lines of code, so I don't see that as much of an impediment. Maybe WeatherFlow could donate a Tempest device to one of the devs. π
I wonder if we should just include a couple of sensors (like temperature and humidity) initially to reduce the code needed to review.
The HA component is less than 600 lines of code, so I don't see that as much of an impediment. Maybe WeatherFlow could donate a Tempest device to one of the devs. π
Just hypothesizing options, haha
I wonder if we should just include a couple of sensors (like temperature and humidity) initially to reduce the code needed to review.
The HA component is less than 600 lines of code, so I don't see that as much of an impediment. Maybe WeatherFlow could donate a Tempest device to one of the devs. π
Just hypothesizing options, haha
I'm all for it if it would help.
The attached patch contains required changes for recently deprecated things. weatherflow.patch
I wonder if we should just include a couple of sensors (like temperature and humidity) initially to reduce the code needed to review.
The HA component is less than 600 lines of code, so I don't see that as much of an impediment. Maybe WeatherFlow could donate a Tempest device to one of the devs. π
Just hypothesizing options, haha
I'm all for it if it would help.
At least the documentation component got reviewed.... so maybe there's hope! :)
I just discovered WeatherFlow and donβt have HACS currently so Iβm in that niche that would like to see this merged. Maybe the CI check failures are holding this back? Sorting the manifest keys for hassfest and addressing the TODO for pylint seems fairly straightforward. The mypy and ruff errors are less clear (to me). I do not have a device to test with or Iβd try to help with the changes myself.
It would be nice to be able to use the data for automations without being stored. Or maybe have a different retention period.
I found that it's possible to prevent recording selected values. This leaves them available to use for automations.
# https://www.home-assistant.io/integrations/recorder/
recorder:
exclude:
entity_globs:
- sensor.outdoor_wind_speed
- sensor.outdoor_wind_direction
I've marked this PR, as some jobs in our CI are failing. Please check the output of those jobs to see what went wrong and adjust the PR accordingly.
Please un-draft it once the CI passes and it is ready for review again by clicking the "Ready for review" button.
Thanks! π
../Frenck
I've marked this PR, as some jobs in our CI are failing. Please check the output of those jobs to see what went wrong and adjust the PR accordingly.
Here are fixes for most (all?) of the CI failures. Not that these are due to recent changes in the HA builds as the CIs were previously passing.
diff --git a/homeassistant/components/weatherflow/manifest.json b/homeassistant/components/weatherflow/manifest.json
index 1274c1ff22..42ab4dc6e7 100644
--- a/homeassistant/components/weatherflow/manifest.json
+++ b/homeassistant/components/weatherflow/manifest.json
@@ -1,15 +1,15 @@
{
"domain": "weatherflow",
"name": "WeatherFlow",
+ "codeowners": ["@natekspencer", "@jeeftor"],
"config_flow": true,
+ "dependencies": [],
"documentation": "https://www.home-assistant.io/integrations/weatherflow",
- "requirements": ["pyweatherflowudp==1.4.1"],
- "ssdp": [],
- "zeroconf": [],
"homekit": {},
- "dependencies": [],
- "codeowners": ["@natekspencer", "@jeeftor"],
- "iot_class": "local_push",
"integration_type": "hub",
- "loggers": ["pyweatherflowudp"]
+ "iot_class": "local_push",
+ "loggers": ["pyweatherflowudp"],
+ "requirements": ["pyweatherflowudp==1.4.1"],
+ "ssdp": [],
+ "zeroconf": []
}
diff --git a/homeassistant/components/weatherflow/sensor.py b/homeassistant/components/weatherflow/sensor.py
index 2c7dfeb45f..3801888635 100644
--- a/homeassistant/components/weatherflow/sensor.py
+++ b/homeassistant/components/weatherflow/sensor.py
@@ -37,9 +37,10 @@ from homeassistant.const import (
UnitOfTemperature,
UnitOfVolumetricFlux,
)
+from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
-from homeassistant.helpers.entity import DeviceInfo, EntityCategory
+from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.util.unit_system import METRIC_SYSTEM
@@ -49,9 +50,6 @@ from .const import DOMAIN, LOGGER
CONCENTRATION_KILOGRAMS_PER_CUBIC_METER = "kg/mΒ³"
CONCENTRATION_POUNDS_PER_CUBIC_FOOT = "lbs/ftΒ³"
-# TODO: Replace with UnitOfSpeed.KILOMETERS_PER_HOUR (km/h)?
-QUANTITY_KILOMETERS_PER_HOUR = "kph"
-
IMPERIAL_UNIT_MAP = {
CONCENTRATION_KILOGRAMS_PER_CUBIC_METER: CONCENTRATION_POUNDS_PER_CUBIC_FOOT,
UnitOfLength.KILOMETERS: UnitOfLength.MILES,
@@ -96,7 +94,7 @@ class WeatherFlowWindSensorEntityDescription(WeatherFlowSensorEntityDescription)
self.state_class = SensorStateClass.MEASUREMENT
self.conversion_fn = lambda attr: attr.to(UnitOfSpeed.MILES_PER_HOUR)
self.decimals = 2
- self.value_fn = lambda attr: attr.to(QUANTITY_KILOMETERS_PER_HOUR)
+ self.value_fn = lambda attr: attr.to(UnitOfSpeed.KILOMETERS_PER_HOUR)
SENSORS: tuple[WeatherFlowSensorEntityDescription, ...] = (
diff --git a/tests/components/weatherflow/conftest.py b/tests/components/weatherflow/conftest.py
index e1c7e3dbcc..3ed71b225e 100644
--- a/tests/components/weatherflow/conftest.py
+++ b/tests/components/weatherflow/conftest.py
@@ -25,19 +25,19 @@ def mock_setup_entry() -> Generator[AsyncMock, None, None]:
yield mock_setup
[email protected]()
[email protected]
def mock_config_entry() -> MockConfigEntry:
"""Return a mock config entry."""
return MockConfigEntry(domain=DOMAIN, data={CONF_HOST: "1.2.3.4"})
[email protected]()
[email protected]
def mock_config_entry2() -> MockConfigEntry:
"""Return a mock config entry."""
return MockConfigEntry(domain=DOMAIN, data={CONF_HOST: DEFAULT_HOST})
[email protected]()
[email protected]
def mock_has_devices() -> Generator[AsyncMock, None, None]:
"""Return a mock has_devices function."""
with patch(
@@ -47,7 +47,7 @@ def mock_has_devices() -> Generator[AsyncMock, None, None]:
yield mock_has_devices
[email protected]()
[email protected]
def mock_has_no_devices() -> Generator[AsyncMock, None, None]:
"""Return a mock has_devices function returning False."""
with patch(
@@ -57,7 +57,7 @@ def mock_has_no_devices() -> Generator[AsyncMock, None, None]:
yield mock_has_devices
[email protected]()
[email protected]
def mock_has_devices_error_listener() -> Generator[AsyncMock, None, None]:
"""Return a mock has_devices returning an error."""
with patch(
@@ -67,7 +67,7 @@ def mock_has_devices_error_listener() -> Generator[AsyncMock, None, None]:
yield mock_has_devices
[email protected]()
[email protected]
def mock_has_devices_error_address_in_use() -> Generator[AsyncMock, None, None]:
"""Return a mock has_devices returning an error."""
with patch(
@@ -77,7 +77,7 @@ def mock_has_devices_error_address_in_use() -> Generator[AsyncMock, None, None]:
yield mock_has_devices
[email protected]()
[email protected]
def mock_stop() -> Generator[AsyncMock, None, None]:
"""Return a fixture to handle the stop of udp."""
@@ -92,7 +92,7 @@ def mock_stop() -> Generator[AsyncMock, None, None]:
yield mock_function
[email protected]()
[email protected]
def mock_start() -> Generator[AsyncMock, None, None]:
"""Return fixture for starting upd."""
DEVICE_JSON = """
@@ -122,7 +122,7 @@ def mock_start() -> Generator[AsyncMock, None, None]:
"""Mock listening function."""
self._devices["HB-00000001"] = device
self._udp_task = asyncio.create_task(device_discovery_task(self))
- self._udp_task.add_done_callback(lambda _: print("Done Callback"))
+ self._udp_task.add_done_callback(lambda _: print("Done Callback")) # noqa: T201
with patch(
"pyweatherflowudp.client.WeatherFlowListener.start_listening",
@@ -132,7 +132,7 @@ def mock_start() -> Generator[AsyncMock, None, None]:
yield mock_function
[email protected]()
[email protected]
def mock_start_timeout() -> Generator[AsyncMock, None, None]:
"""Return fixture for starting upd."""
diff --git a/tests/components/weatherflow/test_config_flow.py b/tests/components/weatherflow/test_config_flow.py
index 0433c285f4..254e971346 100644
--- a/tests/components/weatherflow/test_config_flow.py
+++ b/tests/components/weatherflow/test_config_flow.py
@@ -129,7 +129,7 @@ async def test_devices_with_mocks_timeout(
await asyncio.sleep(1)
# Start the time forarder task
- asyncio.create_task(time_jump(hass))
+ _ = asyncio.create_task(time_jump(hass))
result = await hass.config_entries.flow.async_init(
DOMAIN,
If I cant get to this today -> I'll be able to get to it in a weeks time...
It would be nice to be able to use the data for automations without being stored. Or maybe have a different retention period.
I found that it's possible to prevent recording selected values. This leaves them available to use for automations.
# https://www.home-assistant.io/integrations/recorder/ recorder: exclude: entity_globs: - sensor.outdoor_wind_speed - sensor.outdoor_wind_direction
Is this something that should go in the docs ... or - just let somebody figure it out later :)
Just the docs...
On Fri, Mar 17, 2023, 3:21 PM Jeef @.***> wrote:
It would be nice to be able to use the data for automations without being stored. Or maybe have a different retention period.
I found that it's possible to prevent recording selected values. This leaves them available to use for automations.
https://www.home-assistant.io/integrations/recorder/
recorder: exclude: entity_globs: - sensor.outdoor_wind_speed - sensor.outdoor_wind_direction
Is this something that should go in the docs ... or - just let somebody figure it out later :)
β Reply to this email directly, view it on GitHub https://github.com/home-assistant/core/pull/75530#issuecomment-1474301021, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABAAJR5AKKIE4EK5LRPO7ZLW4S2SJANCNFSM54FCHV6Q . You are receiving this because you are subscribed to this thread.Message ID: @.***>
Looks like I got the final test passing... so Hopefully we're in good shape now.
oh wow :) this looks very promising. do we have an idea in which release this could make it?