Skip to content

Commit

Permalink
feat: remove conversions to imperial (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
lhw authored Dec 27, 2024
1 parent 2b9f9bf commit 217d387
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 162 deletions.
35 changes: 0 additions & 35 deletions aiocloudweather/conversion.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
""" A list of all the unit conversions. Many are just approximations."""

from .const import (
LIGHT_LUX,
UnitOfIrradiance,
UnitOfPrecipitationDepth,
UnitOfPressure,
Expand Down Expand Up @@ -53,37 +52,3 @@ def lux_to_wm2(lux: float) -> float:
def mph_to_ms(speed: float) -> float:
"""Convert miles per hour (mph) to meters per second (m/s)."""
return speed * 0.44704


@unit(UnitOfPressure.INHG)
def hpa_to_inhg(pressure: float) -> float:
"""Convert hectopascals (hPa) to inches of mercury (inHg)."""
return pressure * 0.02953


@unit(UnitOfTemperature.FAHRENHEIT)
def celsius_to_fahrenheit(temp_c: float) -> float:
"""Convert Celsius to Fahrenheit."""
return temp_c * 9.0 / 5.0 + 32


@unit(UnitOfPrecipitationDepth.INCHES)
def mm_to_in(length: float) -> float:
"""Convert millimeters (mm) to inches."""
return length * 0.0393701


@unit(LIGHT_LUX)
def wm2_to_lux(lux: float) -> float:
"""Convert watts per square meter (W/m²) to lux.
For natural daylight, the luminous efficacy varies
but is typically in the range of 90 to 120 lm/W.
A commonly used average value is around 93 lm/W
"""
return lux * 93


@unit(UnitOfSpeed.MILES_PER_HOUR)
def ms_to_mph(speed: float) -> float:
"""Convert meters per second (m/s) to miles per hour (mph)."""
return speed * 2.23694
82 changes: 16 additions & 66 deletions aiocloudweather/station.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,11 @@
from typing import Final

from aiocloudweather.conversion import (
celsius_to_fahrenheit,
fahrenheit_to_celsius,
hpa_to_inhg,
in_to_mm,
inhg_to_hpa,
lux_to_wm2,
mm_to_in,
mph_to_ms,
ms_to_mph,
wm2_to_lux,
)
from .const import (
DEGREE,
Expand Down Expand Up @@ -187,7 +182,6 @@ class WeathercloudRawSensor:
default=None,
metadata={
"unit": UnitOfIrradiance.WATTS_PER_SQUARE_METER,
"keep": True,
"arg": "solarrad",
},
)
Expand All @@ -202,25 +196,15 @@ class WeathercloudRawSensor:
UnitOfSpeed.MILES_PER_HOUR: mph_to_ms,
}

METRIC_TO_IMPERIAL: Final = {
UnitOfPressure.HPA: hpa_to_inhg,
UnitOfTemperature.CELSIUS: celsius_to_fahrenheit,
UnitOfPrecipitationDepth.MILLIMETERS: mm_to_in,
UnitOfIrradiance.WATTS_PER_SQUARE_METER: wm2_to_lux,
UnitOfSpeed.METERS_PER_SECOND: ms_to_mph,
}


@dataclass
class Sensor:
"""Represents a weather sensor."""

name: str

metric: float
metric_unit: str
imperial: float
imperial_unit: str
value: float
unit: str


@dataclass
Expand Down Expand Up @@ -305,7 +289,6 @@ def from_wunderground(data: WundergroundRawSensor) -> "WeatherStation":

value = sensor_field.type(value) * sensor_field.metadata.get("factor", 1)
unit = sensor_field.metadata.get("unit")
keep_original = sensor_field.metadata.get("keep", False)
conversion_func = IMPERIAL_TO_METRIC.get(unit)

if conversion_func:
Expand All @@ -324,23 +307,14 @@ def from_wunderground(data: WundergroundRawSensor) -> "WeatherStation":
continue
sensor_data[sensor_field.name] = Sensor(
name=sensor_field.name,
metric=converted_value,
metric_unit=conversion_func.unit,
imperial=value,
imperial_unit=unit,
)
if not conversion_func or keep_original:
field_name = (
sensor_field.name
if not keep_original
else f"{sensor_field.name}raw"
value=converted_value,
unit=conversion_func.unit,
)
sensor_data[field_name] = Sensor(
name=field_name,
metric=value,
metric_unit=unit,
imperial=value,
imperial_unit=unit,
else:
sensor_data[sensor_field.name] = Sensor(
name=sensor_field.name,
value=value,
unit=unit,
)
return WeatherStation(
station_id=data.station_id,
Expand Down Expand Up @@ -374,38 +348,14 @@ def from_weathercloud(data: WeathercloudRawSensor) -> "WeatherStation":

value = sensor_field.type(value) # No idea why this is needed
unit = sensor_field.metadata.get("unit")
conversion_func = METRIC_TO_IMPERIAL.get(unit)

if conversion_func:
if unit != PERCENTAGE:
value: float = float(value) / 10 # All values are shifted by 10
try:
converted_value = conversion_func(value)
except TypeError as e:
_LOGGER.error(
"Failed to convert %s from %s to %s: %s -> %s",
sensor_field,
unit,
conversion_func.unit,
value,
e,
)
continue
converted_value = conversion_func(value)
sensor_data[sensor_field.name] = Sensor(
name=sensor_field.name,
metric=float(value),
metric_unit=unit,
imperial=converted_value,
imperial_unit=conversion_func.unit,
)
else:
sensor_data[sensor_field.name] = Sensor(
name=sensor_field.name,
metric=value,
metric_unit=unit,
imperial=value,
imperial_unit=unit,
)

sensor_data[sensor_field.name] = Sensor(
name=sensor_field.name,
value=value,
unit=unit,
)

return WeatherStation(
station_id=str(data.station_id),
Expand Down
35 changes: 0 additions & 35 deletions tests/test_conversion.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
from aiocloudweather.conversion import (
celsius_to_fahrenheit,
fahrenheit_to_celsius,
hpa_to_inhg,
in_to_mm,
inhg_to_hpa,
lux_to_wm2,
mm_to_in,
mph_to_ms,
ms_to_mph,
wm2_to_lux,
)


Expand Down Expand Up @@ -40,33 +35,3 @@ def test_mph_to_ms():
assert round(mph_to_ms(10), 4) == 4.4704
assert round(mph_to_ms(30), 4) == 13.4112
assert round(mph_to_ms(5), 4) == 2.2352


def test_hpa_to_inhg():
assert round(hpa_to_inhg(1013.25), 2) == 29.92
assert round(hpa_to_inhg(1000), 2) == 29.53
assert round(hpa_to_inhg(950), 2) == 28.05


def test_celsius_to_fahrenheit():
assert round(celsius_to_fahrenheit(0)) == 32
assert round(celsius_to_fahrenheit(100)) == 212
assert round(celsius_to_fahrenheit(10)) == 50


def test_mm_to_in():
assert round(mm_to_in(25.4), 2) == 1
assert round(mm_to_in(63.5), 2) == 2.5
assert round(mm_to_in(12.7), 2) == 0.5


def test_wm2_to_lux():
assert round(wm2_to_lux(1)) == 93
assert round(wm2_to_lux(5)) == 465
assert round(wm2_to_lux(10)) == 930


def test_ms_to_mph():
assert round(ms_to_mph(4.4704), 4) == 10
assert round(ms_to_mph(13.4112), 4) == 30
assert round(ms_to_mph(2.2352), 4) == 5
44 changes: 18 additions & 26 deletions tests/test_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,12 @@ def test_weather_station_from_wunderground():

assert weather_station.station_id == "12345"
assert weather_station.station_key == "12345"
assert round(weather_station.barometer.metric, 2) == 1013.21
assert weather_station.barometer.metric_unit == "hPa"
assert weather_station.barometer.imperial == 29.92
assert weather_station.barometer.imperial_unit == "inHg"
assert weather_station.temperature.metric == 22.5
assert weather_station.temperature.metric_unit == "°C"
assert weather_station.temperature.imperial == 72.5
assert weather_station.temperature.imperial_unit == "°F"
assert weather_station.humidity.metric == 44
assert weather_station.humidity.metric_unit == "%"
assert weather_station.humidity.imperial == 44
assert weather_station.humidity.imperial_unit == "%"
assert round(weather_station.barometer.value, 2) == 1013.21
assert weather_station.barometer.unit == "hPa"
assert weather_station.temperature.value == 22.5
assert weather_station.temperature.unit == "°C"
assert weather_station.humidity.value == 44
assert weather_station.humidity.unit == "%"


def test_weather_station_from_weathercloud():
Expand All @@ -47,8 +41,8 @@ def test_weather_station_from_weathercloud():
temperature=160,
humidity=80,
dewpoint=129,
rain=0,
dailyrain=0,
rain=109,
dailyrain=25,
winddirection=288,
windspeed=0,
windgustspeed=0,
Expand All @@ -59,15 +53,13 @@ def test_weather_station_from_weathercloud():

assert weather_station.station_id == "12345"
assert weather_station.station_key == "12345"
assert weather_station.barometer.metric == 1013
assert weather_station.barometer.metric_unit == "hPa"
assert round(weather_station.barometer.imperial, 2) == 29.91
assert weather_station.barometer.imperial_unit == "inHg"
assert weather_station.temperature.metric == 16
assert weather_station.temperature.metric_unit == "°C"
assert weather_station.temperature.imperial == 60.8
assert weather_station.temperature.imperial_unit == "°F"
assert weather_station.humidity.metric == 80
assert weather_station.humidity.metric_unit == "%"
assert weather_station.humidity.imperial == 80
assert weather_station.humidity.imperial_unit == "%"
assert weather_station.barometer.value == 1013
assert weather_station.barometer.unit == "hPa"
assert weather_station.temperature.value == 16
assert weather_station.temperature.unit == "°C"
assert weather_station.humidity.value == 80
assert weather_station.humidity.unit == "%"
assert weather_station.rain.value == 10.9
assert weather_station.rain.unit == "mm/h"
assert weather_station.dailyrain.value == 2.5
assert weather_station.dailyrain.unit == "mm"

0 comments on commit 217d387

Please sign in to comment.