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
21 changes: 17 additions & 4 deletions flexmeasures_openweathermap/cli/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from ..utils.modeling import (
get_or_create_weather_station,
)
from ..utils.locating import get_locations
from ..utils.locating import get_locations, get_location_by_asset_id
from ..utils.filing import make_file_path
from ..utils.owm import (
save_forecasts_in_db,
Expand Down Expand Up @@ -95,12 +95,18 @@ def add_weather_sensor(**args):
@click.option(
"--location",
type=str,
required=True,
required=False,
help='Measurement location(s). "latitude,longitude" or "top-left-latitude,top-left-longitude:'
'bottom-right-latitude,bottom-right-longitude." The first format defines one location to measure.'
" The second format defines a region of interest with several (>=4) locations"
' (see also the "method" and "num_cells" parameters for details on how to use this feature).',
)
@click.option(
"--asset-id",
type=int,
required=False,
help="ID of a weather station asset - forecasts will be gotten for its location. If present, --location will be ignored."
)
@click.option(
"--store-in-db/--store-as-json-files",
default=True,
Expand All @@ -125,7 +131,7 @@ def add_weather_sensor(**args):
help="Name of the region (will create sub-folder if you store json files).",
)
@task_with_status_report("get-openweathermap-forecasts")
def collect_weather_data(location, store_in_db, num_cells, method, region):
def collect_weather_data(location, asset_id, store_in_db, num_cells, method, region):
"""
Collect weather forecasts from the OpenWeatherMap API.
This will be done for one or more locations, for which we first identify relevant weather stations.
Expand All @@ -139,7 +145,14 @@ def collect_weather_data(location, store_in_db, num_cells, method, region):
raise Exception(
"[FLEXMEASURES-OWM] Setting OPENWEATHERMAP_API_KEY not available."
)
locations = get_locations(location, num_cells, method)
if asset_id is not None:
locations = [(get_location_by_asset_id(asset_id))]
Ahmad-Wahid marked this conversation as resolved.
Show resolved Hide resolved
elif location is not None:
locations = get_locations(location, num_cells, method)
else:
raise Warning(
"[FLEXMEASURES-OWM] Pass either location or asset-id to get weather forecasts."
)

# Save the results
if store_in_db:
Expand Down
21 changes: 19 additions & 2 deletions flexmeasures_openweathermap/utils/locating.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import click

from flexmeasures.utils.grid_cells import LatLngGrid, get_cell_nums
from flexmeasures import Asset, Sensor
from flexmeasures import Sensor
from flexmeasures.data.models.generic_assets import GenericAsset, GenericAssetType
from flexmeasures.utils import flexmeasures_inflection

from .. import WEATHER_STATION_TYPE_NAME
Expand Down Expand Up @@ -89,7 +90,7 @@ def find_weather_sensor_by_location_or_fail(
n=1,
)
if weather_sensor is not None:
weather_station: Asset = weather_sensor.generic_asset
weather_station: GenericAsset = weather_sensor.generic_asset
if abs(
location[0] - weather_station.location[0]
) > max_degree_difference_for_nearest_weather_sensor or abs(
Expand All @@ -105,3 +106,19 @@ def find_weather_sensor_by_location_or_fail(
% sensor_name
)
return weather_sensor


def get_location_by_asset_id(asset_id: int) -> Tuple[float, float]:
"""Get location for forecasting by passing an asset id"""
asset = GenericAsset.query.filter(
GenericAsset.generic_asset_type_id == asset_id
).one_or_none()
if asset.generic_asset_type.name != WEATHER_STATION_TYPE_NAME:
raise Exception(
"[FLEXMEASURES-OWM] Generic asset type name and weather station type name are not the same."
Ahmad-Wahid marked this conversation as resolved.
Show resolved Hide resolved
)
if asset is None:
raise Exception(
"[FLEXMEASURES-OWM] No asset found for the given asset id %s." % asset_id
)
Ahmad-Wahid marked this conversation as resolved.
Show resolved Hide resolved
return (asset.latitude, asset.longitude)
19 changes: 10 additions & 9 deletions flexmeasures_openweathermap/utils/modeling.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from packaging import version

from flask import current_app
from flexmeasures import Asset, AssetType, Source, __version__ as flexmeasures_version
from flexmeasures.data.models.generic_assets import GenericAsset, GenericAssetType
from flexmeasures import Source, __version__ as flexmeasures_version
from flexmeasures.data import db
from flexmeasures.data.services.data_sources import get_or_create_source

Expand Down Expand Up @@ -38,31 +39,31 @@ def get_or_create_owm_data_source_for_derived_data() -> Source:
)


def get_or_create_weather_station_type() -> AssetType:
def get_or_create_weather_station_type() -> GenericAssetType:
"""Make sure a weather station type exists"""
weather_station_type = AssetType.query.filter(
AssetType.name == WEATHER_STATION_TYPE_NAME,
weather_station_type = GenericAssetType.query.filter(
GenericAssetType.name == WEATHER_STATION_TYPE_NAME,
).one_or_none()
if weather_station_type is None:
weather_station_type = AssetType(
weather_station_type = GenericAssetType(
name=WEATHER_STATION_TYPE_NAME,
description="A weather station with various sensors.",
)
db.session.add(weather_station_type)
return weather_station_type


def get_or_create_weather_station(latitude: float, longitude: float) -> Asset:
def get_or_create_weather_station(latitude: float, longitude: float) -> GenericAsset:
"""Make sure a weather station exists at this location."""
station_name = current_app.config.get(
"WEATHER_STATION_NAME", DEFAULT_WEATHER_STATION_NAME
)
weather_station = Asset.query.filter(
Asset.latitude == latitude, Asset.longitude == longitude
weather_station = GenericAsset.query.filter(
GenericAsset.latitude == latitude, GenericAsset.longitude == longitude
).one_or_none()
if weather_station is None:
weather_station_type = get_or_create_weather_station_type()
weather_station = Asset(
weather_station = GenericAsset(
name=station_name,
generic_asset_type=weather_station_type,
latitude=latitude,
Expand Down