Skip to content
Merged
Changes from all commits
Commits
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
159 changes: 159 additions & 0 deletions docs/forecasts.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,165 @@ curl -i -H "Content-Type: application/json" -X POST -d '{"pv_power_forecast":[0,

You need to be careful here to send the correct amount of data on this list, the correct length. For example, if the data time step is defined as 1 hour and you are performing a day-ahead optimization, then this list length should be 24 data points.

### Understanding forecast data formats: List vs Dictionary

EMHASS supports two formats for passing forecast data as runtime parameters: **list format** and **dictionary format
with timestamps**. Understanding when to use each format can significantly simplify your Home Assistant automations.

#### List Format (Traditional)

The list format passes forecast values as a simple array. This is the most compact format but requires careful
attention to timing and data length.

**Requirements:**
- The list must contain values for the **current time period first**, followed by future values
- The list length must match your prediction horizon based on `optimization_time_step`
- Values must be in the correct order (chronological)

**Example:**
```bash
curl -i -H "Content-Type: application/json" -X POST -d '{
"load_cost_forecast": [0.25, 0.24, 0.23, 0.26, 0.28, ...],
"prediction_horizon": 24,
"optimization_time_step": 60
}' http://localhost:5000/action/dayahead-optim
```
For a 24-hour forecast with 1-hour intervals, you need exactly 24 values starting from the current hour.

When to use list format:
- Your forecast data is already aligned with EMHASS intervals
- You want minimal JSON payload size
- You generate forecast values programmatically in the correct interval

Dictionary Format with Timestamps (Recommended for most users)

The dictionary format allows you to pass forecast values with explicit timestamps. EMHASS will automatically handle
resampling, alignment, and gap filling.

Advantages:
- Automatic resampling: If your data is hourly but EMHASS runs at 15-minute intervals, resampling happens
automatically
- Flexible timing: No need to calculate exact list length or worry about current time alignment
- Self-documenting: Timestamps make it clear which value applies when
- Automatic gap filling: Missing timestamps are filled using forward-fill and backward-fill
- Timezone aware: Timestamps are parsed and converted to your configured timezone

Format:
{
"load_cost_forecast": {
"2025-10-16 10:00:00+00:00": 0.25,
"2025-10-16 11:00:00+00:00": 0.28,
"2025-10-16 12:00:00+00:00": 0.23,
...
}
}

Example curl command:
curl -i -H "Content-Type: application/json" -X POST -d '{
"load_cost_forecast": {
"2025-10-16 10:00:00+00:00": 0.25,
"2025-10-16 11:00:00+00:00": 0.28,
"2025-10-16 12:00:00+00:00": 0.23
},
"prediction_horizon": 48,
"optimization_time_step": 15
}' http://localhost:5000/action/naive-mpc-optim

What happens internally:
1. Timestamps are parsed as ISO8601 format with timezone
2. Data is resampled to match your optimization_time_step (e.g., from 1h to 15min intervals)
3. Values are aligned with the forecast horizon using nearest-neighbor interpolation
4. Any missing values are filled using forward-fill then backward-fill
5. The result is converted to a list for the optimizer

When to use dictionary format:
- Your price data comes from an API (Nordpool, ENTSO-E, Amber, etc.) that provides hourly prices
- You want EMHASS to handle interval conversion automatically
- Your optimization_time_step differs from your data resolution
- You want more readable and maintainable Home Assistant templates

Practical Home Assistant Examples

Dictionary format with Nordpool (Simple - Recommended!):
```
shell_command:
emhass_dayahead_nordpool: >
curl -i -H "Content-Type: application/json" -X POST -d '{
"load_cost_forecast": {{ state_attr("sensor.nordpool_kwh_be_eur_3_10_025", "raw_today") | tojson }},
"prod_price_forecast": {{ state_attr("sensor.nordpool_kwh_be_eur_3_10_025", "raw_today") | tojson }}
}' http://localhost:5000/action/dayahead-optim
```
The Nordpool integration already provides data in dictionary format with timestamps, so you can pass it directly using
| tojson!

List format with Nordpool (Traditional - More Complex):
```
shell_command:
emhass_dayahead_nordpool_list: >
curl -i -H "Content-Type: application/json" -X POST -d '{
"load_cost_forecast": {{(
([states("sensor.nordpool_kwh_be_eur_3_10_025")|float(0)] +
state_attr("sensor.nordpool_kwh_be_eur_3_10_025", "raw_today") | map(attribute="value") | list +
state_attr("sensor.nordpool_kwh_be_eur_3_10_025", "raw_tomorrow") | map(attribute="value") | list)
[now().hour:][:24]
)}}
}' http://localhost:5000/action/dayahead-optim
```

Notice how the list format requires:
- Adding the current hour value first [states("sensor.nordpool...")]
- Extracting values from dictionaries map(attribute="value")
- Slicing from current hour [now().hour:]
- Limiting to the correct length [:24]

Dictionary format handles all of this automatically!

Important Notes

Timezone handling:
- Timestamps should include timezone information (e.g., +00:00 for UTC, +02:00 for CEST)
- EMHASS will convert timestamps to your configured timezone from secrets_emhass.yaml
- If timestamps don't include timezone, they're assumed to be in your local timezone

Data resolution:
- Dictionary format works best when your source data is at a coarser resolution than your optimization_time_step
- Example: Hourly price data automatically resampled to 15-minute intervals
- The resampling uses "nearest neighbor" method, so hourly prices are held constant for all 15-minute intervals within
that hour

Current values:
- When using list format, the first value in the list must be the current period
- Example: If it's 14:30 and your intervals are 30 minutes, the first value should be for 14:30-15:00
- Dictionary format automatically handles this by using timestamps

Mixing formats:
- You can use list format for some forecasts and dictionary format for others in the same API call
- Example: pv_power_forecast as list, load_cost_forecast as dictionary

curl -i -H "Content-Type: application/json" -X POST -d '{
"pv_power_forecast": [0, 0, 50, 150, 300, ...],
"load_cost_forecast": {
"2025-10-16 10:00:00+00:00": 0.25,
"2025-10-16 11:00:00+00:00": 0.28
}
}' http://localhost:5000/action/naive-mpc-optim

Summary: Which Format Should I Use?

| Scenario | Recommended Format | Reason |
|--------------------------------------------------|--------------------|----------------------------------|
| Using Nordpool/ENTSO-E/Amber price APIs | Dictionary | Data already includes timestamps |
| Data from Home Assistant sensors with attributes | Dictionary | Easier template syntax |
| Hourly data with 15-min optimization intervals | Dictionary | Automatic resampling |
| Self-generated forecast in Python/Node-RED | Either | Choose based on convenience |
| Minimal network payload needed | List | More compact JSON |
| Generated forecast already matches intervals | List | No conversion needed |

For most Home Assistant users: Use dictionary format with timestamps for simpler, more maintainable automations.


---

### Example using: Solcast forecast + Amber prices

If you're using Solcast then you can define the following sensors in your system:
Expand Down
Loading