Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue 282 use pint to check and convert units (#283)
Prepare for future user functionality to auto-convert data to desired units when POSTing and GETting data, and hook up unit conversion to our dev endpoint for posting sensor data. * Use pint for unit_utils, using h to denote hour, adding the world's currencies, and simplifying units according to preference; also add tests Signed-off-by: F.N. Claessen <felix@seita.nl> * Add new dependencies to requirements Signed-off-by: F.N. Claessen <felix@seita.nl> * Fix docstring: cubic unit with unicode Signed-off-by: F.N. Claessen <felix@seita.nl> * Fix docstring examples Signed-off-by: F.N. Claessen <felix@seita.nl> * Convert units and data in SensorDataSchema Signed-off-by: F.N. Claessen <felix@seita.nl> * Fix case of simple multiplier Signed-off-by: F.N. Claessen <felix@seita.nl> * Test more unit conversions Signed-off-by: F.N. Claessen <felix@seita.nl> * Refactor unit utils Signed-off-by: F.N. Claessen <felix@seita.nl> * Fix converting offset units (such as degrees Celsius) Signed-off-by: F.N. Claessen <felix@seita.nl> * Extra testing of unit util functions, incl. conversion of offset units Signed-off-by: F.N. Claessen <felix@seita.nl> * Add missing docstring Signed-off-by: F.N. Claessen <felix@seita.nl> * Black Signed-off-by: F.N. Claessen <felix@seita.nl> * Add inline note Signed-off-by: F.N. Claessen <felix@seita.nl> * Clarify what test util function does Signed-off-by: F.N. Claessen <felix@seita.nl> * Add missing type annotation Signed-off-by: F.N. Claessen <felix@seita.nl>
- Loading branch information
Showing
8 changed files
with
301 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
from datetime import timedelta | ||
import pytest | ||
|
||
from flexmeasures.utils.unit_utils import ( | ||
determine_flow_unit, | ||
determine_stock_unit, | ||
determine_unit_conversion_multiplier, | ||
units_are_convertible, | ||
is_energy_unit, | ||
is_power_unit, | ||
u, | ||
) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"unit, time_unit, expected_unit", | ||
[ | ||
("m³", None, "m³/h"), | ||
("kWh", None, "kW"), | ||
("km", "h", "km/h"), | ||
("m", "s", "km/h"), | ||
], | ||
) | ||
def test_determine_flow_unit( | ||
unit, | ||
time_unit, | ||
expected_unit, | ||
): | ||
if time_unit is None: | ||
assert determine_flow_unit(unit) == expected_unit | ||
else: | ||
assert determine_flow_unit(unit, time_unit) == expected_unit | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"unit, time_unit, expected_unit", | ||
[ | ||
("m³/h", None, "m³"), | ||
("kW", None, "kWh"), | ||
("m/s", "s", "m"), | ||
("m/s", "h", "km"), | ||
], | ||
) | ||
def test_determine_stock_unit( | ||
unit, | ||
time_unit, | ||
expected_unit, | ||
): | ||
if time_unit is None: | ||
assert determine_stock_unit(unit) == expected_unit | ||
else: | ||
assert determine_stock_unit(unit, time_unit) == expected_unit | ||
|
||
|
||
def test_determine_unit_conversion_multiplier(): | ||
assert determine_unit_conversion_multiplier("kW", "W") == 1000 | ||
assert determine_unit_conversion_multiplier("J/s", "W") == 1 | ||
assert determine_unit_conversion_multiplier("Wh", "W", timedelta(minutes=10)) == 6 | ||
assert determine_unit_conversion_multiplier("kWh", "MJ") == 3.6 | ||
assert determine_unit_conversion_multiplier("°C", "K") == 274.15 | ||
|
||
|
||
def test_h_denotes_hour_and_not_planck_constant(): | ||
assert u.Quantity("h").dimensionality == u.Quantity("hour").dimensionality | ||
assert ( | ||
u.Quantity("hbar").dimensionality | ||
== u.Quantity("planck_constant").dimensionality | ||
) | ||
|
||
|
||
def test_units_are_convertible(): | ||
assert units_are_convertible("kW", "W") # units just have different prefixes | ||
assert units_are_convertible( | ||
"J/s", "W" | ||
) # units can be converted using some multiplier | ||
assert units_are_convertible( | ||
"Wh", "W" | ||
) # units that represent a stock delta can, knowing the duration, be converted to a flow | ||
assert units_are_convertible("toe", "W") # tonne of oil equivalent | ||
assert units_are_convertible("°C", "K") # offset unit to absolute unit | ||
assert not units_are_convertible("°C", "W") | ||
assert not units_are_convertible("EUR/MWh", "W") | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"unit, power_unit", | ||
[ | ||
("EUR/MWh", False), | ||
("KRW/kWh", False), | ||
("kWh", False), | ||
("kW", True), | ||
("watt", True), | ||
("°C", False), | ||
], | ||
) | ||
def test_is_power_unit(unit: str, power_unit: bool): | ||
assert is_power_unit(unit) is power_unit | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"unit, energy_unit", | ||
[ | ||
("EUR/MWh", False), | ||
("KRW/kWh", False), | ||
("kWh", True), | ||
("kW", False), | ||
("watthour", True), | ||
("°C", False), | ||
], | ||
) | ||
def test_is_energy_unit(unit: str, energy_unit: bool): | ||
assert is_energy_unit(unit) is energy_unit |
Oops, something went wrong.