From d80a6e253d757e62a94d53f9c5b93ed5f0c2c638 Mon Sep 17 00:00:00 2001 From: Lennart Weller Date: Sun, 23 Jun 2024 23:12:33 +0200 Subject: [PATCH] fix: Irradiance and Illumination. A real issue (#10) * fix: Irradiance and Illumination. A real issue * formatting --- .vscode/settings.json | 7 +++++++ aiocloudweather/conversion.py | 16 ++++++++++++---- aiocloudweather/station.py | 29 ++++++++++++++++++++++++----- tests/test_conversion.py | 18 +++++++++--------- 4 files changed, 52 insertions(+), 18 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b9df53f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "python.testing.pytestEnabled": true, + "python.testing.pytestArgs": [ + "tests" + ], + "python.testing.unittestEnabled": false +} \ No newline at end of file diff --git a/aiocloudweather/conversion.py b/aiocloudweather/conversion.py index ab5d93e..be789f4 100644 --- a/aiocloudweather/conversion.py +++ b/aiocloudweather/conversion.py @@ -41,8 +41,12 @@ def in_to_mm(length: float) -> float: @unit(UnitOfIrradiance.WATTS_PER_SQUARE_METER) def lux_to_wm2(lux: float) -> float: - """Convert lux to watts per square meter (W/m²).""" - return lux * 0.0079 + """Convert lux to watts per square meter (W/m²). + 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.METERS_PER_SECOND) @@ -71,8 +75,12 @@ def mm_to_in(length: float) -> float: @unit(LIGHT_LUX) def wm2_to_lux(lux: float) -> float: - """Convert watts per square meter (W/m²) to lux.""" - return lux * 127 + """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) diff --git a/aiocloudweather/station.py b/aiocloudweather/station.py index 7b7d369..635939b 100644 --- a/aiocloudweather/station.py +++ b/aiocloudweather/station.py @@ -90,7 +90,13 @@ class WundergroundRawSensor: ) uv: int = field(default=None, metadata={"unit": UV_INDEX, "arg": "UV"}) solarradiation: float = field( - default=None, metadata={"unit": LIGHT_LUX, "arg": "solarRadiation"} + default=None, + metadata={ + "unit": LIGHT_LUX, + "keep": True, + "factor": 1000, + "arg": "solarRadiation", + }, ) @@ -146,7 +152,11 @@ class WeathercloudRawSensor: uv: int = field(default=None, metadata={"unit": UV_INDEX, "arg": "uvi"}) solarradiation: int = field( default=None, - metadata={"unit": UnitOfIrradiance.WATTS_PER_SQUARE_METER, "arg": "solarrad"}, + metadata={ + "unit": UnitOfIrradiance.WATTS_PER_SQUARE_METER, + "keep": True, + "arg": "solarrad", + }, ) @@ -211,6 +221,9 @@ class WeatherStation: ) uv: Sensor = field(default=None, metadata={"name": "UV Index"}) solarradiation: Sensor = field(default=None, metadata={"name": "Solar Radiation"}) + solarradiationraw: Sensor = field( + default=None, metadata={"name": "Solar Radiation Raw"} + ) heatindex: Sensor = field(default=None, metadata={"name": "Heat Index"}) @staticmethod @@ -236,8 +249,9 @@ def from_wunderground(data: WundergroundRawSensor) -> "WeatherStation": if value is None: continue - value = sensor_field.type(value) # No idea why this is needed + 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: @@ -261,8 +275,13 @@ def from_wunderground(data: WundergroundRawSensor) -> "WeatherStation": imperial=value, imperial_unit=unit, ) - else: - sensor_data[sensor_field.name] = Sensor( + if not conversion_func or keep_original: + field_name = ( + sensor_field.name + if not keep_original + else f"{sensor_field.name}raw" + ) + sensor_data[field_name] = Sensor( name=sensor_field.name, metric=value, metric_unit=unit, diff --git a/tests/test_conversion.py b/tests/test_conversion.py index 460bf27..c3f109f 100644 --- a/tests/test_conversion.py +++ b/tests/test_conversion.py @@ -13,9 +13,9 @@ def test_fahrenheit_to_celsius(): - assert round(fahrenheit_to_celsius(32)) == 0 - assert round(fahrenheit_to_celsius(212)) == 100 - assert round(fahrenheit_to_celsius(50)) == 10 + assert round(fahrenheit_to_celsius(32), 2) == 0 + assert round(fahrenheit_to_celsius(212), 2) == 100 + assert round(fahrenheit_to_celsius(50), 2) == 10 def test_inhg_to_hpa(): @@ -31,9 +31,9 @@ def test_in_to_mm(): def test_lux_to_wm2(): - assert round(lux_to_wm2(100), 2) == 0.79 - assert round(lux_to_wm2(500), 2) == 3.95 - assert round(lux_to_wm2(1000), 2) == 7.9 + assert round(lux_to_wm2(100), 2) == 1.08 + assert round(lux_to_wm2(500), 2) == 5.38 + assert round(lux_to_wm2(1000), 2) == 10.75 def test_mph_to_ms(): @@ -61,9 +61,9 @@ def test_mm_to_in(): def test_wm2_to_lux(): - assert round(wm2_to_lux(1)) == 127 - assert round(wm2_to_lux(5)) == 635 - assert round(wm2_to_lux(10)) == 1270 + 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():