Rename settings variables (remove prefixes)

This commit is contained in:
Dominique Lasserre
2025-01-18 14:26:34 +01:00
parent 1e1bac9fdb
commit 3257dac92b
58 changed files with 867 additions and 918 deletions

View File

@@ -9,12 +9,12 @@ from akkudoktoreos.prediction.elecpriceimport import ElecPriceImportCommonSettin
class ElecPriceCommonSettings(SettingsBaseModel):
"""Electricity Price Prediction Configuration."""
elecprice_provider: Optional[str] = Field(
provider: Optional[str] = Field(
default=None,
description="Electricity price provider id of provider to be used.",
examples=["ElecPriceAkkudoktor"],
)
elecprice_charges_kwh: Optional[float] = Field(
charges_kwh: Optional[float] = Field(
default=None, ge=0, description="Electricity price charges (€/kWh).", examples=[0.21]
)

View File

@@ -49,15 +49,15 @@ class ElecPriceProvider(PredictionProvider):
electricity price_provider (str): Prediction provider for electricity price.
Attributes:
prediction_hours (int, optional): The number of hours into the future for which predictions are generated.
prediction_historic_hours (int, optional): The number of past hours for which historical data is retained.
hours (int, optional): The number of hours into the future for which predictions are generated.
historic_hours (int, optional): The number of past hours for which historical data is retained.
latitude (float, optional): The latitude in degrees, must be within -90 to 90.
longitude (float, optional): The longitude in degrees, must be within -180 to 180.
start_datetime (datetime, optional): The starting datetime for predictions, defaults to the current datetime if unspecified.
end_datetime (datetime, computed): The datetime representing the end of the prediction range,
calculated based on `start_datetime` and `prediction_hours`.
calculated based on `start_datetime` and `hours`.
keep_datetime (datetime, computed): The earliest datetime for retaining historical data, calculated
based on `start_datetime` and `prediction_historic_hours`.
based on `start_datetime` and `historic_hours`.
"""
# overload
@@ -71,4 +71,4 @@ class ElecPriceProvider(PredictionProvider):
return "ElecPriceProvider"
def enabled(self) -> bool:
return self.provider_id() == self.config.elecprice.elecprice_provider
return self.provider_id() == self.config.elecprice.provider

View File

@@ -54,11 +54,11 @@ class ElecPriceAkkudoktor(ElecPriceProvider):
of hours into the future and retains historical data.
Attributes:
prediction_hours (int, optional): Number of hours in the future for the forecast.
prediction_historic_hours (int, optional): Number of past hours for retaining data.
hours (int, optional): Number of hours in the future for the forecast.
historic_hours (int, optional): Number of past hours for retaining data.
start_datetime (datetime, optional): Start datetime for forecasts, defaults to the current datetime.
end_datetime (datetime, computed): The forecast's end datetime, computed based on `start_datetime` and `prediction_hours`.
keep_datetime (datetime, computed): The datetime to retain historical data, computed from `start_datetime` and `prediction_historic_hours`.
end_datetime (datetime, computed): The forecast's end datetime, computed based on `start_datetime` and `hours`.
keep_datetime (datetime, computed): The datetime to retain historical data, computed from `start_datetime` and `historic_hours`.
Methods:
provider_id(): Returns a unique identifier for the provider.
@@ -125,18 +125,16 @@ class ElecPriceAkkudoktor(ElecPriceProvider):
capped_data = data.clip(min=lower_bound, max=upper_bound)
return capped_data
def _predict_ets(
self, history: np.ndarray, seasonal_periods: int, prediction_hours: int
) -> np.ndarray:
def _predict_ets(self, history: np.ndarray, seasonal_periods: int, hours: int) -> np.ndarray:
clean_history = self._cap_outliers(history)
model = ExponentialSmoothing(
clean_history, seasonal="add", seasonal_periods=seasonal_periods
).fit()
return model.forecast(prediction_hours)
return model.forecast(hours)
def _predict_median(self, history: np.ndarray, prediction_hours: int) -> np.ndarray:
def _predict_median(self, history: np.ndarray, hours: int) -> np.ndarray:
clean_history = self._cap_outliers(history)
return np.full(prediction_hours, np.median(clean_history))
return np.full(hours, np.median(clean_history))
def _update_data(
self, force_update: Optional[bool] = False
@@ -155,8 +153,8 @@ class ElecPriceAkkudoktor(ElecPriceProvider):
# Assumption that all lists are the same length and are ordered chronologically
# in ascending order and have the same timestamps.
# Get elecprice_charges_kwh in wh
charges_wh = (self.config.elecprice.elecprice_charges_kwh or 0) / 1000
# Get charges_kwh in wh
charges_wh = (self.config.elecprice.charges_kwh or 0) / 1000
highest_orig_datetime = None # newest datetime from the api after that we want to update.
series_data = pd.Series(dtype=float) # Initialize an empty series
@@ -183,27 +181,23 @@ class ElecPriceAkkudoktor(ElecPriceProvider):
assert highest_orig_datetime # mypy fix
# some of our data is already in the future, so we need to predict less. If we got less data we increase the prediction hours
needed_prediction_hours = int(
self.config.prediction.prediction_hours
needed_hours = int(
self.config.prediction.hours
- ((highest_orig_datetime - self.start_datetime).total_seconds() // 3600)
)
if needed_prediction_hours <= 0:
if needed_hours <= 0:
logger.warning(
f"No prediction needed. needed_prediction_hours={needed_prediction_hours}, prediction_hours={self.config.prediction.prediction_hours},highest_orig_datetime {highest_orig_datetime}, start_datetime {self.start_datetime}"
) # this might keep data longer than self.start_datetime + self.config.prediction.prediction_hours in the records
f"No prediction needed. needed_hours={needed_hours}, hours={self.config.prediction.hours},highest_orig_datetime {highest_orig_datetime}, start_datetime {self.start_datetime}"
) # this might keep data longer than self.start_datetime + self.config.prediction.hours in the records
return
if amount_datasets > 800: # we do the full ets with seasons of 1 week
prediction = self._predict_ets(
history, seasonal_periods=168, prediction_hours=needed_prediction_hours
)
prediction = self._predict_ets(history, seasonal_periods=168, hours=needed_hours)
elif amount_datasets > 168: # not enough data to do seasons of 1 week, but enough for 1 day
prediction = self._predict_ets(
history, seasonal_periods=24, prediction_hours=needed_prediction_hours
)
prediction = self._predict_ets(history, seasonal_periods=24, hours=needed_hours)
elif amount_datasets > 0: # not enough data for ets, do median
prediction = self._predict_median(history, prediction_hours=needed_prediction_hours)
prediction = self._predict_median(history, hours=needed_hours)
else:
logger.error("No data available for prediction")
raise ValueError("No data available")

View File

@@ -22,24 +22,22 @@ logger = get_logger(__name__)
class ElecPriceImportCommonSettings(SettingsBaseModel):
"""Common settings for elecprice data import from file or JSON String."""
elecpriceimport_file_path: Optional[Union[str, Path]] = Field(
import_file_path: Optional[Union[str, Path]] = Field(
default=None,
description="Path to the file to import elecprice data from.",
examples=[None, "/path/to/prices.json"],
)
elecpriceimport_json: Optional[str] = Field(
import_json: Optional[str] = Field(
default=None,
description="JSON string, dictionary of electricity price forecast value lists.",
examples=['{"elecprice_marketprice_wh": [0.0003384, 0.0003318, 0.0003284]}'],
)
# Validators
@field_validator("elecpriceimport_file_path", mode="after")
@field_validator("import_file_path", mode="after")
@classmethod
def validate_elecpriceimport_file_path(
cls, value: Optional[Union[str, Path]]
) -> Optional[Path]:
def validate_import_file_path(cls, value: Optional[Union[str, Path]]) -> Optional[Path]:
if value is None:
return None
if isinstance(value, str):
@@ -65,12 +63,12 @@ class ElecPriceImport(ElecPriceProvider, PredictionImportProvider):
return "ElecPriceImport"
def _update_data(self, force_update: Optional[bool] = False) -> None:
if self.config.elecprice.provider_settings.elecpriceimport_file_path is not None:
if self.config.elecprice.provider_settings.import_file_path is not None:
self.import_from_file(
self.config.elecprice.provider_settings.elecpriceimport_file_path,
self.config.elecprice.provider_settings.import_file_path,
key_prefix="elecprice",
)
if self.config.elecprice.provider_settings.elecpriceimport_json is not None:
if self.config.elecprice.provider_settings.import_json is not None:
self.import_from_json(
self.config.elecprice.provider_settings.elecpriceimport_json, key_prefix="elecprice"
self.config.elecprice.provider_settings.import_json, key_prefix="elecprice"
)

View File

@@ -15,7 +15,7 @@ logger = get_logger(__name__)
class LoadCommonSettings(SettingsBaseModel):
"""Load Prediction Configuration."""
load_provider: Optional[str] = Field(
provider: Optional[str] = Field(
default=None,
description="Load provider id of provider to be used.",
examples=["LoadAkkudoktor"],

View File

@@ -33,18 +33,18 @@ class LoadProvider(PredictionProvider):
LoadProvider is a thread-safe singleton, ensuring only one instance of this class is created.
Configuration variables:
load_provider (str): Prediction provider for load.
provider (str): Prediction provider for load.
Attributes:
prediction_hours (int, optional): The number of hours into the future for which predictions are generated.
prediction_historic_hours (int, optional): The number of past hours for which historical data is retained.
hours (int, optional): The number of hours into the future for which predictions are generated.
historic_hours (int, optional): The number of past hours for which historical data is retained.
latitude (float, optional): The latitude in degrees, must be within -90 to 90.
longitude (float, optional): The longitude in degrees, must be within -180 to 180.
start_datetime (datetime, optional): The starting datetime for predictions, defaults to the current datetime if unspecified.
end_datetime (datetime, computed): The datetime representing the end of the prediction range,
calculated based on `start_datetime` and `prediction_hours`.
calculated based on `start_datetime` and `hours`.
keep_datetime (datetime, computed): The earliest datetime for retaining historical data, calculated
based on `start_datetime` and `prediction_historic_hours`.
based on `start_datetime` and `historic_hours`.
"""
# overload
@@ -58,4 +58,4 @@ class LoadProvider(PredictionProvider):
return "LoadProvider"
def enabled(self) -> bool:
return self.provider_id() == self.config.load.load_provider
return self.provider_id() == self.config.load.provider

View File

@@ -111,7 +111,7 @@ class LoadAkkudoktor(LoadProvider):
# We provide prediction starting at start of day, to be compatible to old system.
# End date for prediction is prediction hours from now.
date = self.start_datetime.start_of("day")
end_date = self.start_datetime.add(hours=self.config.prediction.prediction_hours)
end_date = self.start_datetime.add(hours=self.config.prediction.hours)
while compare_datetimes(date, end_date).lt:
# Extract mean (index 0) and standard deviation (index 1) for the given day and hour
# Day indexing starts at 0, -1 because of that

View File

@@ -22,19 +22,19 @@ logger = get_logger(__name__)
class LoadImportCommonSettings(SettingsBaseModel):
"""Common settings for load data import from file or JSON string."""
load_import_file_path: Optional[Union[str, Path]] = Field(
import_file_path: Optional[Union[str, Path]] = Field(
default=None,
description="Path to the file to import load data from.",
examples=[None, "/path/to/yearly_load.json"],
)
load_import_json: Optional[str] = Field(
import_json: Optional[str] = Field(
default=None,
description="JSON string, dictionary of load forecast value lists.",
examples=['{"load0_mean": [676.71, 876.19, 527.13]}'],
)
# Validators
@field_validator("load_import_file_path", mode="after")
@field_validator("import_file_path", mode="after")
@classmethod
def validate_loadimport_file_path(cls, value: Optional[Union[str, Path]]) -> Optional[Path]:
if value is None:
@@ -62,11 +62,7 @@ class LoadImport(LoadProvider, PredictionImportProvider):
return "LoadImport"
def _update_data(self, force_update: Optional[bool] = False) -> None:
if self.config.load.provider_settings.load_import_file_path is not None:
self.import_from_file(
self.config.provider_settings.load_import_file_path, key_prefix="load"
)
if self.config.load.provider_settings.load_import_json is not None:
self.import_from_json(
self.config.load.provider_settings.load_import_json, key_prefix="load"
)
if self.config.load.provider_settings.import_file_path is not None:
self.import_from_file(self.config.provider_settings.import_file_path, key_prefix="load")
if self.config.load.provider_settings.import_json is not None:
self.import_from_json(self.config.load.provider_settings.import_json, key_prefix="load")

View File

@@ -53,9 +53,9 @@ class PredictionCommonSettings(SettingsBaseModel):
determines the time zone based on latitude and longitude.
Attributes:
prediction_hours (Optional[int]): Number of hours into the future for predictions.
hours (Optional[int]): Number of hours into the future for predictions.
Must be non-negative.
prediction_historic_hours (Optional[int]): Number of hours into the past for historical data.
historic_hours (Optional[int]): Number of hours into the past for historical data.
Must be non-negative.
latitude (Optional[float]): Latitude in degrees, must be between -90 and 90.
longitude (Optional[float]): Longitude in degrees, must be between -180 and 180.
@@ -65,16 +65,16 @@ class PredictionCommonSettings(SettingsBaseModel):
and longitude.
Validators:
validate_prediction_hours (int): Ensures `prediction_hours` is a non-negative integer.
validate_prediction_historic_hours (int): Ensures `prediction_historic_hours` is a non-negative integer.
validate_hours (int): Ensures `hours` is a non-negative integer.
validate_historic_hours (int): Ensures `historic_hours` is a non-negative integer.
validate_latitude (float): Ensures `latitude` is within the range -90 to 90.
validate_longitude (float): Ensures `longitude` is within the range -180 to 180.
"""
prediction_hours: Optional[int] = Field(
hours: Optional[int] = Field(
default=48, ge=0, description="Number of hours into the future for predictions"
)
prediction_historic_hours: Optional[int] = Field(
historic_hours: Optional[int] = Field(
default=48,
ge=0,
description="Number of hours into the past for historical predictions data",

View File

@@ -114,16 +114,16 @@ class PredictionStartEndKeepMixin(PredictionBase):
@computed_field # type: ignore[prop-decorator]
@property
def end_datetime(self) -> Optional[DateTime]:
"""Compute the end datetime based on the `start_datetime` and `prediction_hours`.
"""Compute the end datetime based on the `start_datetime` and `hours`.
Ajusts the calculated end time if DST transitions occur within the prediction window.
Returns:
Optional[DateTime]: The calculated end datetime, or `None` if inputs are missing.
"""
if self.start_datetime and self.config.prediction.prediction_hours:
if self.start_datetime and self.config.prediction.hours:
end_datetime = self.start_datetime + to_duration(
f"{self.config.prediction.prediction_hours} hours"
f"{self.config.prediction.hours} hours"
)
dst_change = end_datetime.offset_hours - self.start_datetime.offset_hours
logger.debug(f"Pre: {self.start_datetime}..{end_datetime}: DST change: {dst_change}")
@@ -147,10 +147,10 @@ class PredictionStartEndKeepMixin(PredictionBase):
return None
historic_hours = self.historic_hours_min()
if (
self.config.prediction.prediction_historic_hours
and self.config.prediction.prediction_historic_hours > historic_hours
self.config.prediction.historic_hours
and self.config.prediction.historic_hours > historic_hours
):
historic_hours = int(self.config.prediction.prediction_historic_hours)
historic_hours = int(self.config.prediction.historic_hours)
return self.start_datetime - to_duration(f"{historic_hours} hours")
@computed_field # type: ignore[prop-decorator]

View File

@@ -19,7 +19,7 @@ class PVForecastCommonSettings(SettingsBaseModel):
# Inverter Parameters
# https://pvlib-python.readthedocs.io/en/stable/_modules/pvlib/inverter.html
pvforecast_provider: Optional[str] = Field(
provider: Optional[str] = Field(
default=None,
description="PVForecast provider id of provider to be used.",
examples=["PVForecastAkkudoktor"],

View File

@@ -28,18 +28,18 @@ class PVForecastProvider(PredictionProvider):
PVForecastProvider is a thread-safe singleton, ensuring only one instance of this class is created.
Configuration variables:
pvforecast_provider (str): Prediction provider for pvforecast.
provider (str): Prediction provider for pvforecast.
Attributes:
prediction_hours (int, optional): The number of hours into the future for which predictions are generated.
prediction_historic_hours (int, optional): The number of past hours for which historical data is retained.
hours (int, optional): The number of hours into the future for which predictions are generated.
historic_hours (int, optional): The number of past hours for which historical data is retained.
latitude (float, optional): The latitude in degrees, must be within -90 to 90.
longitude (float, optional): The longitude in degrees, must be within -180 to 180.
start_datetime (datetime, optional): The starting datetime for predictions (inlcusive), defaults to the current datetime if unspecified.
end_datetime (datetime, computed): The datetime representing the end of the prediction range (exclusive),
calculated based on `start_datetime` and `prediction_hours`.
calculated based on `start_datetime` and `hours`.
keep_datetime (datetime, computed): The earliest datetime for retaining historical data (inclusive), calculated
based on `start_datetime` and `prediction_historic_hours`.
based on `start_datetime` and `historic_hours`.
"""
# overload
@@ -54,6 +54,6 @@ class PVForecastProvider(PredictionProvider):
def enabled(self) -> bool:
logger.debug(
f"PVForecastProvider ID {self.provider_id()} vs. config {self.config.pvforecast.pvforecast_provider}"
f"PVForecastProvider ID {self.provider_id()} vs. config {self.config.pvforecast.provider}"
)
return self.provider_id() == self.config.pvforecast.pvforecast_provider
return self.provider_id() == self.config.pvforecast.provider

View File

@@ -14,21 +14,25 @@ Classes:
Example:
# Set up the configuration with necessary fields for URL generation
settings_data = {
"prediction_hours": 48,
"prediction_historic_hours": 24,
"latitude": 52.52,
"longitude": 13.405,
"pvforecast_provider": "Akkudoktor",
"pvforecast0_peakpower": 5.0,
"pvforecast0_surface_azimuth": -10,
"pvforecast0_surface_tilt": 7,
"pvforecast0_userhorizon": [20, 27, 22, 20],
"pvforecast0_inverter_paco": 10000,
"pvforecast1_peakpower": 4.8,
"pvforecast1_surface_azimuth": -90,
"pvforecast1_surface_tilt": 7,
"pvforecast1_userhorizon": [30, 30, 30, 50],
"pvforecast1_inverter_paco": 10000,
"prediction": {
"hours": 48,
"historic_hours": 24,
"latitude": 52.52,
"longitude": 13.405,
},
"pvforecast": {
"provider": "PVForecastAkkudoktor",
"pvforecast0_peakpower": 5.0,
"pvforecast0_surface_azimuth": -10,
"pvforecast0_surface_tilt": 7,
"pvforecast0_userhorizon": [20, 27, 22, 20],
"pvforecast0_inverter_paco": 10000,
"pvforecast1_peakpower": 4.8,
"pvforecast1_surface_azimuth": -90,
"pvforecast1_surface_tilt": 7,
"pvforecast1_userhorizon": [30, 30, 30, 50],
"pvforecast1_inverter_paco": 10000,
}
}
# Create the config instance from the provided data
@@ -47,12 +51,12 @@ Example:
print(forecast.report_ac_power_and_measurement())
Attributes:
prediction_hours (int): Number of hours into the future to forecast. Default is 48.
prediction_historic_hours (int): Number of past hours to retain for analysis. Default is 24.
hours (int): Number of hours into the future to forecast. Default is 48.
historic_hours (int): Number of past hours to retain for analysis. Default is 24.
latitude (float): Latitude for the forecast location.
longitude (float): Longitude for the forecast location.
start_datetime (datetime): Start time for the forecast, defaulting to current datetime.
end_datetime (datetime): Computed end datetime based on `start_datetime` and `prediction_hours`.
end_datetime (datetime): Computed end datetime based on `start_datetime` and `hours`.
keep_datetime (datetime): Computed threshold datetime for retaining historical data.
Methods:
@@ -159,13 +163,13 @@ class PVForecastAkkudoktor(PVForecastProvider):
of hours into the future and retains historical data.
Attributes:
prediction_hours (int, optional): Number of hours in the future for the forecast.
prediction_historic_hours (int, optional): Number of past hours for retaining data.
hours (int, optional): Number of hours in the future for the forecast.
historic_hours (int, optional): Number of past hours for retaining data.
latitude (float, optional): The latitude in degrees, validated to be between -90 and 90.
longitude (float, optional): The longitude in degrees, validated to be between -180 and 180.
start_datetime (datetime, optional): Start datetime for forecasts, defaults to the current datetime.
end_datetime (datetime, computed): The forecast's end datetime, computed based on `start_datetime` and `prediction_hours`.
keep_datetime (datetime, computed): The datetime to retain historical data, computed from `start_datetime` and `prediction_historic_hours`.
end_datetime (datetime, computed): The forecast's end datetime, computed based on `start_datetime` and `hours`.
keep_datetime (datetime, computed): The datetime to retain historical data, computed from `start_datetime` and `historic_hours`.
Methods:
provider_id(): Returns a unique identifier for the provider.
@@ -286,10 +290,10 @@ class PVForecastAkkudoktor(PVForecastProvider):
# Assumption that all lists are the same length and are ordered chronologically
# in ascending order and have the same timestamps.
if len(akkudoktor_data.values[0]) < self.config.prediction.prediction_hours:
if len(akkudoktor_data.values[0]) < self.config.prediction.hours:
# Expect one value set per prediction hour
error_msg = (
f"The forecast must cover at least {self.config.prediction.prediction_hours} hours, "
f"The forecast must cover at least {self.config.prediction.hours} hours, "
f"but only {len(akkudoktor_data.values[0])} data sets are given in forecast data."
)
logger.error(f"Akkudoktor schema change: {error_msg}")
@@ -318,9 +322,9 @@ class PVForecastAkkudoktor(PVForecastProvider):
self.update_value(dt, data)
if len(self) < self.config.prediction.prediction_hours:
if len(self) < self.config.prediction.hours:
raise ValueError(
f"The forecast must cover at least {self.config.prediction.prediction_hours} hours, "
f"The forecast must cover at least {self.config.prediction.hours} hours, "
f"but only {len(self)} hours starting from {self.start_datetime} "
f"were predicted."
)
@@ -370,13 +374,13 @@ if __name__ == "__main__":
# Set up the configuration with necessary fields for URL generation
settings_data = {
"prediction": {
"prediction_hours": 48,
"prediction_historic_hours": 24,
"hours": 48,
"historic_hours": 24,
"latitude": 52.52,
"longitude": 13.405,
},
"pvforecast": {
"pvforecast_provider": "PVForecastAkkudoktor",
"provider": "PVForecastAkkudoktor",
"pvforecast0_peakpower": 5.0,
"pvforecast0_surface_azimuth": -10,
"pvforecast0_surface_tilt": 7,

View File

@@ -11,7 +11,7 @@ from akkudoktoreos.prediction.weatherimport import WeatherImportCommonSettings
class WeatherCommonSettings(SettingsBaseModel):
"""Weather Forecast Configuration."""
weather_provider: Optional[str] = Field(
provider: Optional[str] = Field(
default=None,
description="Weather provider id of provider to be used.",
examples=["WeatherImport"],

View File

@@ -101,18 +101,18 @@ class WeatherProvider(PredictionProvider):
WeatherProvider is a thread-safe singleton, ensuring only one instance of this class is created.
Configuration variables:
weather_provider (str): Prediction provider for weather.
provider (str): Prediction provider for weather.
Attributes:
prediction_hours (int, optional): The number of hours into the future for which predictions are generated.
prediction_historic_hours (int, optional): The number of past hours for which historical data is retained.
hours (int, optional): The number of hours into the future for which predictions are generated.
historic_hours (int, optional): The number of past hours for which historical data is retained.
latitude (float, optional): The latitude in degrees, must be within -90 to 90.
longitude (float, optional): The longitude in degrees, must be within -180 to 180.
start_datetime (datetime, optional): The starting datetime for predictions, defaults to the current datetime if unspecified.
end_datetime (datetime, computed): The datetime representing the end of the prediction range,
calculated based on `start_datetime` and `prediction_hours`.
calculated based on `start_datetime` and `hours`.
keep_datetime (datetime, computed): The earliest datetime for retaining historical data, calculated
based on `start_datetime` and `prediction_historic_hours`.
based on `start_datetime` and `historic_hours`.
"""
# overload
@@ -126,7 +126,7 @@ class WeatherProvider(PredictionProvider):
return "WeatherProvider"
def enabled(self) -> bool:
return self.provider_id() == self.config.weather.weather_provider
return self.provider_id() == self.config.weather.provider
@classmethod
def estimate_irradiance_from_cloud_cover(

View File

@@ -62,13 +62,13 @@ class WeatherBrightSky(WeatherProvider):
of hours into the future and retains historical data.
Attributes:
prediction_hours (int, optional): Number of hours in the future for the forecast.
prediction_historic_hours (int, optional): Number of past hours for retaining data.
hours (int, optional): Number of hours in the future for the forecast.
historic_hours (int, optional): Number of past hours for retaining data.
latitude (float, optional): The latitude in degrees, validated to be between -90 and 90.
longitude (float, optional): The longitude in degrees, validated to be between -180 and 180.
start_datetime (datetime, optional): Start datetime for forecasts, defaults to the current datetime.
end_datetime (datetime, computed): The forecast's end datetime, computed based on `start_datetime` and `prediction_hours`.
keep_datetime (datetime, computed): The datetime to retain historical data, computed from `start_datetime` and `prediction_historic_hours`.
end_datetime (datetime, computed): The forecast's end datetime, computed based on `start_datetime` and `hours`.
keep_datetime (datetime, computed): The datetime to retain historical data, computed from `start_datetime` and `historic_hours`.
Methods:
provider_id(): Returns a unique identifier for the provider.

View File

@@ -68,15 +68,15 @@ class WeatherClearOutside(WeatherProvider):
WeatherClearOutside is a thread-safe singleton, ensuring only one instance of this class is created.
Attributes:
prediction_hours (int, optional): The number of hours into the future for which predictions are generated.
prediction_historic_hours (int, optional): The number of past hours for which historical data is retained.
hours (int, optional): The number of hours into the future for which predictions are generated.
historic_hours (int, optional): The number of past hours for which historical data is retained.
latitude (float, optional): The latitude in degrees, must be within -90 to 90.
longitude (float, optional): The longitude in degrees, must be within -180 to 180.
start_datetime (datetime, optional): The starting datetime for predictions, defaults to the current datetime if unspecified.
end_datetime (datetime, computed): The datetime representing the end of the prediction range,
calculated based on `start_datetime` and `prediction_hours`.
calculated based on `start_datetime` and `hours`.
keep_datetime (datetime, computed): The earliest datetime for retaining historical data, calculated
based on `start_datetime` and `prediction_historic_hours`.
based on `start_datetime` and `historic_hours`.
"""
@classmethod

View File

@@ -22,22 +22,22 @@ logger = get_logger(__name__)
class WeatherImportCommonSettings(SettingsBaseModel):
"""Common settings for weather data import from file or JSON string."""
weatherimport_file_path: Optional[Union[str, Path]] = Field(
import_file_path: Optional[Union[str, Path]] = Field(
default=None,
description="Path to the file to import weather data from.",
examples=[None, "/path/to/weather_data.json"],
)
weatherimport_json: Optional[str] = Field(
import_json: Optional[str] = Field(
default=None,
description="JSON string, dictionary of weather forecast value lists.",
examples=['{"weather_temp_air": [18.3, 17.8, 16.9]}'],
)
# Validators
@field_validator("weatherimport_file_path", mode="after")
@field_validator("import_file_path", mode="after")
@classmethod
def validate_weatherimport_file_path(cls, value: Optional[Union[str, Path]]) -> Optional[Path]:
def validate_import_file_path(cls, value: Optional[Union[str, Path]]) -> Optional[Path]:
if value is None:
return None
if isinstance(value, str):
@@ -63,11 +63,11 @@ class WeatherImport(WeatherProvider, PredictionImportProvider):
return "WeatherImport"
def _update_data(self, force_update: Optional[bool] = False) -> None:
if self.config.weather.provider_settings.weatherimport_file_path is not None:
if self.config.weather.provider_settings.import_file_path is not None:
self.import_from_file(
self.config.weather.provider_settings.weatherimport_file_path, key_prefix="weather"
self.config.weather.provider_settings.import_file_path, key_prefix="weather"
)
if self.config.weather.provider_settings.weatherimport_json is not None:
if self.config.weather.provider_settings.import_json is not None:
self.import_from_json(
self.config.weather.provider_settings.weatherimport_json, key_prefix="weather"
self.config.weather.provider_settings.import_json, key_prefix="weather"
)