Forecastsolar Connection
This module provides a read-only REST API connection to the forecast.solar API.
You can obtain an estimate of solar production for a specific location, defined by latitude and longitude, and a specific plane orientation, defined by declination and azimuth, based on the installed module power.
Supported endpoints include: “Estimate”, “Historic”, and “Clearsky”:
Estimate Solar Production The estimate endpoint provides the forecast for today and the upcoming days, depending on the account model.
Historic Solar Production The historic endpoint calculates the average solar production for a given day based on historical weather data, excluding current weather conditions.
Clear Sky Solar Production The clearsky endpoint calculates the theoretically possible solar production assuming no cloud cover.
For more information, visit the forecast.solar API documentation.
ForecastsolarConnection
- class eta_nexus.connections.ForecastsolarConnection(url: str = 'https://api.forecast.solar', *, url_params: dict[str, Any] | None = None, query_params: dict[str, Any] | None = None, nodes: Nodes[ForecastsolarNode] | None = None, retry_total: int = 3, retry_backoff_factor: float = 1.0)[source]
ForecastsolarConnection is a class to download and upload multiple features from and to the ForecastSolar database as timeseries.
- Parameters:
url – URL of the server with scheme (https://).
usr – Not needed for Forecast.Solar.
pwd – Not needed for Forecast.Solar.
nodes – Nodes to select in connection.
retry_total – Total number of retries for failed HTTP requests (default: 3).
retry_backoff_factor – Backoff factor for retries (default: 1s-> e.g. 1s, 2s, 4s for 3 retries).
- logger: Logger = <Logger eta_nexus.connections.forecastsolar_connection (WARNING)>
- read_node(node: ForecastsolarNode, from_time: datetime, to_time: datetime, interval: timedelta, **kwargs: Any) pd.DataFrame[source]
Download data from the Forecast.Solar Database.
Note: The Forecast.Solar API returns full-day data regardless of time parameters. Time filtering and resampling are handled in read_series after data retrieval.
- Parameters:
node – Node to read values from.
from_time – Start time (used for filtering in read_series, not in API call).
to_time – End time (used for filtering in read_series, not in API call).
interval – Interval for resampling (handled in read_series via df_interpolate).
- Returns:
pandas.DataFrame containing the data read from the connection.
- read(nodes: ForecastsolarNode | Nodes[ForecastsolarNode] | None = None) pd.DataFrame[source]
Return solar forecast for the current time.
- Parameters:
nodes – Single node or list/set of nodes to read values from.
- Returns:
Pandas DataFrame containing the data read from the connection.
- read_series(from_time: datetime, to_time: datetime, nodes: ForecastsolarNode | Nodes[ForecastsolarNode] | None = None, interval: TimeStep = 1, **kwargs: Any) pd.DataFrame[source]
Return a time series of forecast data from the Forecast.Solar Database.
- Parameters:
nodes – Single node or list/set of nodes to read values from.
from_time – Starting time to begin reading (included in output).
to_time – Time to stop reading at (not included in output).
interval – Interval between time steps. It is interpreted as seconds if given as integer.
kwargs – Other parameters (ignored by this connection).
- Returns:
Pandas DataFrame containing the data read from the connection.
- timestr_from_datetime(dt: datetime) str[source]
Create an Forecast.Solar compatible time string.
- Parameters:
dt – Datetime object to convert to string.
- Returns:
Forecast.Solar compatible time string.
- classmethod route_valid(nodes: Nodes, **kwargs: Any) bool[source]
Check if node routes make up a valid route, by using the Forecast.Solar API’s check endpoint.
- Parameters:
nodes – List of nodes to check.
- Returns:
Boolean if the nodes are on the same route.
- static calculate_watt_hours_period(watt_df: pandas.DataFrame) pandas.DataFrame[source]
Calculates watt hours for each period based on the average watts between consecutive rows.
- Parameters:
df – DataFrame with indices representing time intervals and columns representing node’s watt estimates
- Returns:
DataFrame with the watt-hour-period estimates for each interval
- static cumulative_watt_hours_per_day(watt_hours_df: pandas.DataFrame, from_unit: str = 'watthours/period') pandas.DataFrame[source]
Calculates the cumulative watt-hours throughout each day for each panel.
- Parameters:
watt_hours_df – df with indices representing time intervals and columns containing watt-hour estimates.
from_unit – Unit of the input DataFrame. Default is “watthours/period”.
- Returns:
DataFrame with cumulative watt-hours per day for each panel, rounded to three decimal places.
- static summarize_watt_hours_per_day(watt_hours_df: pandas.DataFrame, from_unit: str = 'watthours/period') pandas.DataFrame[source]
Sums the watt-hours over each day for each panel.
- Parameters:
watt_hours_df – df with indices representing time intervals and columns containing watt-hour estimates.
from_unit – Unit of the input DataFrame. Default is “watthours/period”.
- Returns:
DataFrame with total watt-hours per day for each panel, rounded to three decimal places.
- url_parsed: ParseResult
URL of the server to connect to
- exc: BaseException | None
ForecastsolarNode
- class eta_nexus.nodes.ForecastsolarNode(name: str, url: str, protocol: str, *args: Any, **kwargs: Any)[source]
Node for using the Forecast.Solar API.
Mandatory parameters are: * The location of the forecast solar plane(s): latitude, longitude, * Plane parameters: declination, azimuth and kwp.
Additionally api_key must be set for endpoints other than ‘estimate’, multiple planes or if requests capacity is exceeded.
For multiple planes, the parameters shall be passed as lists of the same length (e.g. [0, 30], [180, 180], [5, 5]).
By default, data is queried as ‘watts’. Other options are ‘watthours’, ‘watthours/period’ and ‘watthours/day’. Either set the data parameter or call the appropriate method afterwards of :class:’eta_nexus.connections.forecast_solar.ForecastsolarConnection’.
- endpoint: str
Endpoint in (estimate, history, clearsky), defaults to estimate; string
- data: str
What data to query, i.e. only ‘watts’, ‘watthours’, ‘watthours/period’ or ‘watthours/day’; string
- latitude: int
Latitude of plane location, -90 (south) … 90 (north); handled with a precision of 0.0001 or abt. 10 m
- longitude: int
Longitude of plane location, -180 (west) … 180 (east); handled with a precision of 0.0001 or abt. 10 m
- declination: int | list[int]
Plane declination, 0 (horizontal) … 90 (vertical) - always in relation to earth’s surface; integer
- azimuth: int | list[int]
Plane azimuth, -180 … 180 (-180 = north, -90 = east, 0 = south, 90 = west, 180 = north); integer
- no_sun: int | None
Format of timestamps in the response, see API doc for values; string Forecast for full day or only sunrise to sunset, 0|1 (API defaults to 0); int
- horizon: int | list[int] | None
Horizon information; string, (comma-separated list of numerics) See API doc
- name: str
Name for the node.
- url: str
URL of the connection.
- url_parsed: ParseResult
Parse result object of the URL (in case more post-processing is required).
- protocol: str
Protocol of the connection.
- dtype: Callable | None
Data type of the node (for value conversion). Note that strings will be interpreted as utf-8 encoded. If you do not want this behaviour, use ‘bytes’.
Example Usage
Simple node without API key:
from eta_nexus.connections import ForecastsolarConnection
from eta_nexus.nodes import ForecastsolarNode
# ------------------------------
# Simple node without API key:
# ------------------------------
node_simple = ForecastsolarNode(
name="Forecastsolar Node",
url="https://api.forecast.solar",
protocol="forecast_solar",
latitude=49.86381,
longitude=8.68105,
declination=14,
azimuth=90,
kwp=23.31,
)
# Create an instance of the ForecastsolarConnection class
conn_simple = ForecastsolarConnection()
# Use the read method of the ForecastsolarConnection instance to get an estimation
# The read method takes a node as an argument, here represented by node_simple
estimation = conn_simple.read(node_simple)
Node with api key and multiple planes:
# ------------------------------
# Node with api key and multiple planes:
# ------------------------------
node_eta = ForecastsolarNode(
name="Forecastsolar Node",
url="https://api.forecast.solar",
protocol="forecast_solar",
api_key="A1B2C3D4E5F6G7H8", # Your API key
latitude=49.86381,
longitude=8.68105,
declination=[14, 10, 10],
azimuth=[90, -90, 90],
kwp=[23.31, 23.31, 23.31],
)
# Create a connection instance from the node_eta using the from_node method
conn_eta = ForecastsolarConnection.from_node(node_eta)
if isinstance(conn_eta, ForecastsolarConnection):
# Get a series of estimations for a specified time interval
estimation = conn_eta.read_series(
from_time=datetime(2024, 5, 7), to_time=datetime(2024, 5, 8), interval=timedelta(minutes=15)
)
else:
raise TypeError("The connection must be a ForecastsolarConnection, to be able to call read_series.")