Skip to content

Allow for SI units in forcasts#217

Merged
MatthewFlamm merged 18 commits intoMatthewFlamm:masterfrom
makushimu:feat/si_units
Aug 11, 2024
Merged

Allow for SI units in forcasts#217
MatthewFlamm merged 18 commits intoMatthewFlamm:masterfrom
makushimu:feat/si_units

Conversation

@makushimu
Copy link
Copy Markdown
Contributor

This allows to request the forecast data to be natively returned with SI units instead of US customary units.
While the lib currently converts the returned value to SI, it can't really convert the textual observations due to its free form text nature. My ultimate goal is to expose this to home assistant.

There is no change to the default values, so there should be no change to existing code.

Still missing some new tests to cover this feature, but I wanted to at least have this out there for initial review.

@codecov
Copy link
Copy Markdown

codecov bot commented Jul 29, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 94.09%. Comparing base (11aec2d) to head (620e513).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #217      +/-   ##
==========================================
+ Coverage   93.79%   94.09%   +0.30%     
==========================================
  Files           9        9              
  Lines         645      661      +16     
==========================================
+ Hits          605      622      +17     
+ Misses         40       39       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@MatthewFlamm
Copy link
Copy Markdown
Owner

Thanks for this PR! I am +1 for getting this in.

NWS is flaky with respect to honoring the requested units. This library provides some double checks and conversions in the SimpleNWS class in case the NWS returns the wrong unit in some cases.

This code below smells incorrect, although maybe not wrong. And, it isn't commented very well on what the purpose is. There is some conversion between temperature units here. It looks like the conversion can go both ways, so I'm not sure that anything needs to be changed. This maybe more of a note to remember for reviewers including me to look into how this PR interacts with that code bit.

for key in ("probabilityOfPrecipitation", "dewpoint", "relativeHumidity"):
extracted = SimpleNWS.extract_value(forecast_entry, key)
if isinstance(extracted, tuple):
value, value_unit = extracted
if value_unit.endswith("degC") and temp_unit == "F":
value = round(float(value) * 1.8 + 32, 0)
elif value_unit.endswith("degF") and temp_unit == "C":
value = round((float(value) - 32) / 1.8, 0)
forecast_entry[key] = int(value)
else:
forecast_entry[key] = extracted

Copy link
Copy Markdown
Owner

@MatthewFlamm MatthewFlamm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments on my first read through.

@makushimu
Copy link
Copy Markdown
Contributor Author

Cool!
I still want to write some tests around this, and at the same time, I can look into those conversions as well.
That being said, the conversion only seems to be triggering if there is a mismatch between what's being returned for those 3 field ("degC","degF" for the "probabilityOfPrecipitation", "dewpoint" and "relativeHumidity" fields) vs the "temperatureUnit" that was returned. So, if I understand this correctly, this code will just convert those 3 fields to whatever the temperatureUnit was returned.

Copy link
Copy Markdown
Contributor Author

@makushimu makushimu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all the prompt reviews!

@makushimu
Copy link
Copy Markdown
Contributor Author

Ah yeah, by using a StrEnum, this limits to python 3.11 and greater. I can probably emulate the StrEnum behaviour with a regular enum that will make it work for older versions.

@lymanepp
Copy link
Copy Markdown
Collaborator

Ah yeah, by using a StrEnum, this limits to python 3.11 and greater. I can probably emulate the StrEnum behaviour with a regular enum that will make it work for older versions.

There's a backport in place already. Look at const.py for usage.

@makushimu
Copy link
Copy Markdown
Contributor Author

Should be better now. I'm not sure about the test changes that I did, but that felt like the cleanest way to handle the parameters. I'm open to updating it to something better, of course!

from .backports.enum import StrEnum


class NwsForecastUnits(StrEnum):
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move this to const.py where other values are stored? Or will we prefer to make them separate in the future?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, not sure this needs the Nws prefix as that isn't done elsewhere.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with moving to const.py.

We have a bit of mixed bag on naming currently. Most constants do not have a Nws prefix, although the error does. In my experience most python packages do not prefix the package, or related, name on variables inside their namespace. I would vote for no prefix to be most consistent with the rest of the package.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My idea behind the separate file was because this class would be "public" vs the more "private" values that are stored in the const.py, but this makes sense too.

Copy link
Copy Markdown
Owner

@MatthewFlamm MatthewFlamm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked at the testing changes, yet but this is looking really close.

- Remove Nws prefix for NwsForecastUnits enum
- Move ForecastUnits to const.py file
- Make all raw_data functions that depend on ForecastUnits have a
  default value
Copy link
Copy Markdown
Owner

@MatthewFlamm MatthewFlamm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small nit, but otherwise LGTM

Co-authored-by: MatthewFlamm <39341281+MatthewFlamm@users.noreply.github.com>
Copy link
Copy Markdown
Owner

@MatthewFlamm MatthewFlamm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! LGTM

@MatthewFlamm
Copy link
Copy Markdown
Owner

@lymanepp you have requested changes earlier. We can wait to merge in case you have other comments.

@MatthewFlamm MatthewFlamm merged commit f03d161 into MatthewFlamm:master Aug 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants