123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- import pytest
- from flexmeasures import Sensor
- from flexmeasures.data.schemas.sensors import (
- QuantityOrSensor,
- VariableQuantityField,
- )
- from flexmeasures.utils.unit_utils import ur
- from marshmallow import ValidationError
- @pytest.mark.parametrize(
- "src_quantity, dst_unit, fails, exp_dst_quantity",
- [
- # deserialize a sensor
- ({"sensor": 1}, "MWh", False, None),
- ({"sensor": 1}, "kWh", False, None),
- ({"sensor": 1}, "kW", False, None),
- ({"sensor": 1}, "EUR", True, None),
- ({"sensor": 1}, "/h", False, None), # convertable to MWh²/h
- ({"sensor": 2}, "EUR/kWh", False, None),
- ({"sensor": 2}, "EUR", True, None),
- # deserialize a quantity
- (1, "%", False, "100.0 %"),
- (5, "%", False, "500.0 %"),
- ("1MWh", "MWh", False, "1 MWh"),
- ("1 MWh", "kWh", False, "1000.0 kWh"),
- ("1 MWh", "kW", True, None),
- ("100 EUR/MWh", "EUR/kWh", False, "0.1 EUR/kWh"),
- ("100 EUR/MWh", "EUR", True, None),
- ("1 EUR/kWh", "/MWh", False, "1.0 kEUR/MWh"),
- ("50%", "/MWh", False, "500.0 kWh/MWh"),
- ("/", "/MWh", True, None),
- ("/", "MWh", True, None),
- ("10 batteries", "MWh", True, None),
- # deserialize a time series specification
- (
- [{"start": "2024-08-17T11:00+02", "duration": "PT1H", "value": "2 MWh"}],
- "kWh",
- False,
- "2000.0 kWh",
- ),
- (
- [
- {
- "start": "2024-08-17T11:00+02",
- "duration": "PT1H",
- "value": "829.4 Wh/kWh",
- }
- ],
- "/MWh",
- False,
- "829.4 kWh/MWh",
- ),
- (
- [
- {
- "start": "2024-08-17T11:00+02",
- "duration": "PT1H",
- "value": "914.7 EUR/kWh",
- }
- ],
- "/MWh",
- False,
- "914.7 kEUR/MWh",
- ),
- # todo: uncomment after to_preferred gets rid of mEUR
- # (
- # [{"start": "2024-08-17T11:00+02", "duration": "PT1H", "value": "120.8 EUR/MWh"}],
- # "/kWh",
- # False,
- # "0.1208 EUR/kWh",
- # ),
- ],
- )
- def test_quantity_or_sensor_deserialize(
- setup_dummy_sensors, src_quantity, dst_unit, fails, exp_dst_quantity
- ):
- schema = VariableQuantityField(to_unit=dst_unit, return_magnitude=False)
- try:
- dst_quantity = schema.deserialize(src_quantity)
- if isinstance(src_quantity, (ur.Quantity, int, float)):
- assert dst_quantity == ur.Quantity(exp_dst_quantity)
- assert str(dst_quantity) == exp_dst_quantity
- elif isinstance(src_quantity, list):
- assert dst_quantity[0]["value"] == ur.Quantity(exp_dst_quantity)
- assert str(dst_quantity[0]["value"]) == exp_dst_quantity
- assert not fails
- except ValidationError as e:
- assert fails, e
- @pytest.mark.parametrize(
- "src_quantity, expected_magnitude",
- [
- ("1 kW", 0.001),
- ("10 kW", 0.01),
- ("100 kW", 0.1),
- ("1 MW", 1),
- ("1.2 GW", 1200),
- ("2000 kVA", 2),
- ("3600/4.184 cal/h", 1e-6),
- ],
- )
- def test_quantity_or_sensor_conversion(
- setup_dummy_sensors, src_quantity, expected_magnitude
- ):
- schema = QuantityOrSensor(to_unit="MW")
- assert schema.deserialize(src_quantity).magnitude == expected_magnitude
- @pytest.mark.parametrize(
- "sensor_id, input_param, dst_unit, fails",
- [
- # deserialize a sensor
- (1, "sensor:1", "MWh", False),
- (1, "sensor:1", "kWh", False),
- (1, "sensor:1", "kW", False),
- (1, "sensor:1", "EUR", True),
- (2, "sensor:2", "EUR/kWh", False),
- (2, "sensor:2", "EUR", True),
- # deserialize a quantity
- (None, "1MWh", "MWh", False),
- (None, "1 MWh", "kWh", False),
- (None, "1 MWh", "kW", True),
- (None, "100 EUR/MWh", "EUR/kWh", False),
- (None, "100 EUR/MWh", "EUR", True),
- ],
- )
- def test_quantity_or_sensor_field(
- setup_dummy_sensors, sensor_id, input_param, dst_unit, fails, db
- ):
- field = QuantityOrSensor(to_unit=dst_unit)
- try:
- if sensor_id is None:
- val = field.convert(input_param, None, None)
- assert val.units == ur.Unit(dst_unit)
- else:
- val = field.convert(input_param, None, None)
- assert val == db.session.get(Sensor, sensor_id)
- assert not fails
- except Exception as e:
- assert fails, e
- @pytest.mark.parametrize(
- "input_param, dst_unit, fails",
- [
- # deserialize a quantity
- ([{"value": 1, "datetime": "2024-07-21T00:15+07"}], "MWh", False),
- ([{"value": "1", "datetime": "2024-07-21T00:15+07"}], "MWh", True),
- ([{"value": "1MWh", "datetime": "2024-07-21T00:15+07"}], "MWh", False),
- ([{"value": "1000 kWh", "datetime": "2024-07-21T00:15+07"}], "MWh", False),
- ([{"value": "1 MW", "datetime": "2024-07-21T00:15+07"}], "MWh", True),
- ],
- )
- def test_time_series_field(input_param, dst_unit, fails, db):
- field = VariableQuantityField(
- to_unit=dst_unit,
- default_src_unit="MWh",
- return_magnitude=False,
- )
- try:
- val = field.convert(input_param, None, None)
- assert val[0]["value"].units == ur.Unit(dst_unit)
- assert val[0]["value"].magnitude == 1
- assert not fails
- except Exception as e:
- assert fails, e
|