Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get forecasts for an asset-id instead of passing location #16

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6f5a55f
add asset-id to get forecasts, used GenericAsset(type) instead of Ass…
Ahmad-Wahid Jul 22, 2023
acf1e03
refactoring
Ahmad-Wahid Jul 24, 2023
9080a0a
refactoring
Ahmad-Wahid Jul 25, 2023
f9448ce
remove extra brackets
Ahmad-Wahid Jul 25, 2023
abea5df
add both assets name in the exception message
Ahmad-Wahid Jul 25, 2023
ddfc405
add asset-id to get forecasts, used GenericAsset(type) instead of Ass…
Ahmad-Wahid Jul 22, 2023
adb193b
refactoring
Ahmad-Wahid Jul 24, 2023
caae0c1
refactoring
Ahmad-Wahid Jul 25, 2023
06d26c1
remove extra brackets
Ahmad-Wahid Jul 25, 2023
767f4c1
add both assets name in the exception message
Ahmad-Wahid Jul 25, 2023
59ef4e0
clear exception message
Ahmad-Wahid Jul 26, 2023
1fc3691
Merge remote-tracking branch 'origin/2-allow-to-pass-asset-id-andor-n…
Ahmad-Wahid Jul 26, 2023
dbc475b
Merge remote-tracking branch 'origin/main' into 2-allow-to-pass-asset…
Ahmad-Wahid Jul 26, 2023
8465c17
removed unused package
Ahmad-Wahid Jul 26, 2023
3022ffd
add asset-id cli param
Ahmad-Wahid Jul 26, 2023
96a7c53
add asset-id to register a weather sensor
Ahmad-Wahid Jul 27, 2023
6a93236
fix sensor schema validation and raise Warnings
Ahmad-Wahid Jul 27, 2023
7c4a077
refactoring
Ahmad-Wahid Jul 27, 2023
1333fc1
refactor schema and update generic asset and type
Ahmad-Wahid Jul 28, 2023
22e52b7
stop code when no close station is found
Ahmad-Wahid Jul 28, 2023
eddc198
update warning message and refactoring
Ahmad-Wahid Aug 1, 2023
b33dd7a
Merge main + update test warning message
Mar 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 27 additions & 19 deletions flexmeasures_openweathermap/cli/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from .schemas.weather_sensor import WeatherSensorSchema
from ..utils.modeling import (
get_or_create_weather_station,
get_asset_id_weather_station,
get_weather_station_by_asset_id,
)
from ..utils.locating import get_locations, get_location_by_asset_id
from ..utils.filing import make_file_path
Expand All @@ -22,7 +22,6 @@
)
from ..sensor_specs import mapping


"""
TODO: allow to also pass an asset ID or name for the weather station (instead of location) to both commands?
See https://github.com/SeitaBV/flexmeasures-openweathermap/issues/2
Expand Down Expand Up @@ -76,7 +75,7 @@ def add_weather_sensor(**args):
)
raise click.Abort
if args["asset_id"] is not None:
weather_station = get_asset_id_weather_station(args["asset_id"])
weather_station = get_weather_station_by_asset_id(args["asset_id"])
elif args["latitude"] is not None and args["longitude"] is not None:
weather_station = get_or_create_weather_station(
args["latitude"], args["longitude"]
Expand All @@ -86,22 +85,31 @@ def add_weather_sensor(**args):
"Arguments are missing to register a weather sensor. Provide either '--asset-id' or ('--latitude' and '--longitude')."
)

fm_sensor_specs = get_supported_sensor_spec(args["name"])
fm_sensor_specs["generic_asset"] = weather_station
fm_sensor_specs["timezone"] = args["timezone"]
fm_sensor_specs["name"] = fm_sensor_specs.pop("fm_sensor_name")
fm_sensor_specs.pop("owm_sensor_name")
sensor = Sensor(**fm_sensor_specs)
sensor.attributes = fm_sensor_specs["attributes"]

db.session.add(sensor)
db.session.commit()
click.echo(
f"[FLEXMEASURES-OWM] Successfully created weather sensor with ID {sensor.id}, at weather station with ID {weather_station.id}"
)
click.echo(
f"[FLEXMEASURES-OWM] You can access this sensor at its entity address {sensor.entity_address}"
)
sensor = Sensor.query.filter(
Sensor.name == args["name"].lower(),
Sensor.generic_asset == weather_station,
).one_or_none()
if sensor:
click.echo(
f"[FLEXMEASURES-OWM] A '{args['name']}' weather sensor already exists at this weather station (the station's ID is {weather_station.id})."
)
nhoening marked this conversation as resolved.
Show resolved Hide resolved
else:
fm_sensor_specs = get_supported_sensor_spec(args["name"])
fm_sensor_specs["generic_asset"] = weather_station
fm_sensor_specs["timezone"] = args["timezone"]
fm_sensor_specs["name"] = fm_sensor_specs.pop("fm_sensor_name")
fm_sensor_specs.pop("owm_sensor_name")
sensor = Sensor(**fm_sensor_specs)
sensor.attributes = fm_sensor_specs["attributes"]

db.session.add(sensor)
db.session.commit()
click.echo(
f"[FLEXMEASURES-OWM] Successfully created weather sensor with ID {sensor.id}, at weather station with ID {weather_station.id}"
)
click.echo(
f"[FLEXMEASURES-OWM] You can access this sensor at its entity address {sensor.entity_address}"
)


@flexmeasures_openweathermap_bp.cli.command("get-weather-forecasts")
Expand Down
31 changes: 2 additions & 29 deletions flexmeasures_openweathermap/cli/schemas/weather_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@
)

import pytz
from flexmeasures import Sensor

from ...utils.modeling import (
get_or_create_weather_station,
get_asset_id_weather_station,
)
from ...utils.owm import get_supported_sensor_spec, get_supported_sensors_str


Expand Down Expand Up @@ -42,31 +37,9 @@ def validate_name_is_supported(self, name: str):
)

@validates_schema(skip_on_field_errors=False)
def validate_name_is_unique_in_weather_station(self, data, **kwargs):
if (
"name" not in data
or "latitude" not in data
or "longitude" not in data
or "asset_id" not in data
):
def validate_name_is_given(self, data, **kwargs):
nhoening marked this conversation as resolved.
Show resolved Hide resolved
if "name" not in data:
return # That's a different validation problem
if data["latitude"] is not None and data["longitude"] is not None:
weather_station = get_or_create_weather_station(
data["latitude"], data["longitude"]
)
elif data["asset_id"] is not None:
weather_station = get_asset_id_weather_station(data["asset_id"])
else:
return

sensor = Sensor.query.filter(
Sensor.name == data["name"].lower(),
Sensor.generic_asset == weather_station,
).one_or_none()
if sensor:
raise ValidationError(
f"A '{data['name']}' weather sensor already exists at this weather station (the station's ID is {weather_station.id})."
)

@validates("timezone")
def validate_timezone(self, timezone: str):
Expand Down
7 changes: 4 additions & 3 deletions flexmeasures_openweathermap/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
from flask_sqlalchemy import SQLAlchemy
from flexmeasures.app import create as create_flexmeasures_app
from flexmeasures.conftest import db, fresh_db # noqa: F401
from flexmeasures import Asset, AssetType, Sensor
from flexmeasures.data.models.generic_assets import GenericAsset, GenericAssetType
from flexmeasures.data.models.time_series import Sensor

from flexmeasures_openweathermap import WEATHER_STATION_TYPE_NAME

Expand Down Expand Up @@ -42,10 +43,10 @@ def add_weather_sensors_fresh_db(fresh_db) -> Dict[str, Sensor]: # noqa: F811

def create_weather_sensors(db: SQLAlchemy): # noqa: F811
"""Add a weather station asset with two weather sensors."""
weather_station_type = AssetType(name=WEATHER_STATION_TYPE_NAME)
weather_station_type = GenericAssetType(name=WEATHER_STATION_TYPE_NAME)
db.session.add(weather_station_type)

weather_station = Asset(
weather_station = GenericAsset(
name="Test weather station",
generic_asset_type=weather_station_type,
latitude=33.4843866,
Expand Down
3 changes: 2 additions & 1 deletion flexmeasures_openweathermap/utils/locating.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import Tuple, List, Optional

import click
from flask import current_app

from flexmeasures.utils.grid_cells import LatLngGrid, get_cell_nums
from flexmeasures import Sensor
Expand Down Expand Up @@ -103,7 +104,7 @@ def find_weather_sensor_by_location(
f"[FLEXMEASURES-OWM] No sufficiently close weather sensor found (within {max_degree_difference_for_nearest_weather_sensor} {flexmeasures_inflection.pluralize('degree', max_degree_difference_for_nearest_weather_sensor)} distance) for measuring {sensor_name}! We're looking for: {location}, closest available: ({weather_station.location})"
nhoening marked this conversation as resolved.
Show resolved Hide resolved
)
else:
raise Warning(
current_app.logger.warning(
"[FLEXMEASURES-OWM] No weather sensor set up yet for measuring %s. Try the register-weather-sensor CLI task."
% sensor_name
)
Expand Down
2 changes: 1 addition & 1 deletion flexmeasures_openweathermap/utils/modeling.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def get_or_create_weather_station(latitude: float, longitude: float) -> GenericA
return weather_station


def get_asset_id_weather_station(asset_id: int) -> GenericAsset:
def get_weather_station_by_asset_id(asset_id: int) -> GenericAsset:
weather_station = GenericAsset.query.filter(
GenericAsset.generic_asset_type_id == asset_id
).one_or_none()
Expand Down