EMHASS: An Energy Management for Home Assistant

yes, it’s in the attributes, something like this:

\"pv_power_forecast\": {{(state_attr('sensor.solcast_pv_forecast_forecast_today', 'detailedHourly') | selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',1000)|map('int')|list  + state_attr('sensor.solcast_pv_forecast_forecast_tomorrow', 'detailedHourly') | map(attribute='pv_estimate')|map('multiply',1000)|map('int')|list)|tojson}}

Note this is the hourly values, not sure which you use. DetailedForecast is half hour (as opposed to DetailedHourly, which is hourly :slight_smile:

Nordpool hourly:

\"load_cost_forecast\":{{((state_attr('sensor.nordpool_kwh_nl_eur_3_10_0', 'raw_today') | map(attribute='value') | list  + state_attr('sensor.nordpool_kwh_nl_eur_3_10_0', 'raw_tomorrow') | map(attribute='value') | list))[now().hour:][:24] }},
      \"prod_price_forecast\":{{((state_attr('sensor.nordpool_kwh_nl_eur_3_10_0', 'raw_today') | map(attribute='value') | list  + state_attr('sensor.nordpool_kwh_nl_eur_3_10_0', 'raw_tomorrow') | map(attribute='value') | list))[now().hour:][:24]}}}'

Well they are the sensors I use. They can be manupulated to give me an average wattage output from PV per 30 minute time step which suits my tariff forecasts from Amber and prediction horizon which varies throught the day.

There will be examples out there that suite the Nordpool tariff data you are using. It may not be 30 minute, I don’t know. But what ever it is this particular data should be the forecast average wattage for that time step.

Like I said, you can leave it to EMHASS to extract this information and format it automatically by selecting one of the solar forecast providers in the config as long as you can describe you solar panels accuratly in the config.

I only go to the trouble of formatting pv_power_forecast in the API POST for historical reasons.

The pv_power_forecast data dictionary are in watts (W).

  • EMHASS consistently works internally with power data (instantaneous rates) in watts or average watts per time step, not energy in kilowatt-hours.
  • When you feed it Solcast forecast data (which yes, is in kWh per time step), EMHASS converts that to W by dividing by the forecast interval and multiplying by 1000.

So this code:

{#- Forecast of consumption price (demand tariff) -#}
  "pv_power_forecast": {{
    ([states('sensor.sonnenbatterie_84324_production_w')|int(0)] +
    state_attr('sensor.solcast_pv_forecast_forecast_today', 'detailedForecast')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',1000)|map('int')|list +
    state_attr('sensor.solcast_pv_forecast_forecast_tomorrow', 'detailedForecast')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',1000)|map('int')|list
    )| tojson
  }},

should deliver something like this:

"pv_power_forecast": [946, 1319, 1802, 2354, 2841, 3201, 3489, 3705, 3853, 3950, 3945, 3907, 3750, 3544, 3269, 2931, 2442, 1896, 1379, 825, 198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 159, 643, 1166, 1698, 2213, 2786, 3188, 3478, 3700, 3843, 3913, 3927, 3869, 3736, 3521, 3241, 2894, 2343, 1820, 1312, 730, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

and that data in W (or average W over the 30 min time step), in JSON foremat, is suitable to include in an API call to EMHASS MPC or dayahead models along with all the other data.

So my entire template produces this:

{"prod_price_forecast": [-0.0026, 0.0219, 0.0128, 0.0046, -0.0022, -0.0201, -0.0259, -0.0322, -0.0365, -0.0386, -0.0393, -0.0385, -0.0354, -0.03, -0.0207, 0.003, 0.017, 0.0711, 0.0984, 0.1399, 0.1797, 0.1977, 0.2029, 0.2019, 0.1982, 0.1937, 0.1891, 0.1445, 0.138, 0.1324, 0.129, 0.1249, 0.123, 0.1242, 0.1201, 0.1087, 0.1021, 0.1001, 0.0975, 0.0959, 0.0973],
 "load_cost_forecast":[0.06, 0.0871, 0.077, 0.0679, 0.0605, 0.0544, 0.048, 0.0411, 0.0363, 0.034, 0.0332, 0.0342, 0.0375, 0.0435, 0.0537, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.2219, 0.2147, 0.2085, 0.2048, 0.2004, 0.1982, 0.1995, 0.195, 0.1825, 0.1752, 0.173, 0.1701, 0.1684, 0.17],"pv_power_forecast": [1334, 1802, 2354, 2841, 3201, 3489, 3705, 3853, 3950, 3945, 3907, 3750, 3544, 3269, 2931, 2442, 1896, 1379, 825, 198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 159, 643, 1166, 1698, 2213, 2786, 3188, 3478, 3700, 3843, 3913, 3927, 3869, 3736, 3521, 3241, 2894, 2343, 1820, 1312, 730, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 "load_power_forecast": [596, 552, 538, 550, 593, 2186, 708, 567, 662, 633, 590, 647, 576, 845, 1618, 1465, 498, 462, 436, 457, 584, 877, 1161, 1052, 1136, 921, 1034, 781, 626, 504, 420, 417, 390, 370, 370, 379, 359, 396, 425, 381, 388, 361, 313, 314, 310, 323, 844, 996, 682],
 "prediction_horizon": 40,
 "num_def_loads": 2,
 "def_total_hours": [1,0],
 "P_deferrable_nom": [1300, 920],
 "treat_def_as_semi_cont": [1, 0],
 "set_def_constant": [0, 0],
 "soc_init": 0.01,
 "soc_final": 0.08,
 "alpha": 1,
 "beta": 0,
 "battery_charge_power_max": 3300,
 "battery_discharge_power_max": 1200
}

In my system this data is recalculated every 30 seconds and POSTed to EMHASS via a node-red HTTP request node followed by a ‘publish-data’ POST.

Thank you, but I don’t know what else I could do but confirming the arrays I pass to EMHASS have the right size, according to the 15 minutes resolution.

Does anybody use the thermal model with an underfloor heating?

Just upgraded to 0.13.4 - saw some odd looking predictions.
As I have a hybrid inverter, I need to update the new “Max hybrid inverter AC input and output power” settings from 1000 to match my inverters max settings.
Thanks David and team for the update and this new feature!!

Hello,

Newbie here and sorry if I put this question in the wrong thread or so (feel free to move it).

I feel that I am running in circles trying to find out where/how to properly configure Emhass.
While it seems rather straight forward something eludes me (and just maybe I am missing something very obvious).

Running: Home Assistant Green (updated)
Have installed Emhass as an Add-on via the add-on store (and adding the proper git repository)

But after that I have some issues;
a) fail to locate the config.json-file, have been digging around in the file system (both with file editor and ssh/terminal) but still haven’t been able to locate it
b) trying to use the GUI-config (reacable via the gear cog in the graphical interface); here I seem to miss information(?), e.g. for deferrable loads I can only fill in a numerical value and cannot put in more info (which would be needed in order to configure how I want these loads to be handled I assume). Further nothing seems to happen if I click the yaml, default or save buttons at the bottom.

Have tried to uninstall and reinstall Emhass several times but still I cannot seem to be able to configure anything.

I think I am missing something here and would appriciate if someone can point me in the right direction…

After install go to “Settings > Add-ons > EMHASS” and then click on “Open Web UI”:

Then click on the “gear” icon:

Then you will reach the configuration page and fill in all the needed parameters. No need to go search for any config.json or whatever file using a terminal.

A save button is at the bottom to save your configuration.

There is everything that you need on that page.
That will configure the energy optimizations. After that and after launching an optimization, data will be published to HA. You then need to handle that information yourself using dedicated automations to control your real loads/switches.

The “List and box view toggle” and the “YAML” button work fine for me.

1 Like

HI!
I am also a newb, just a little ahead of you on this mission. Cant guide you all the way since I am not there, Still, the first steps you are stumbling with, see if you can get some answers from @rcruikshank extensive explanations to me about this questions, just a little above;

You will learn that EMHASS works as a calculator “on top of” home assistant.
That you need to specify the sensors in the GUI for:

“sensor_power_photovoltaics” - Identify this in your PV setup

“sensor_power_photovoltaics_forecast”- this can either be created by EMHASS itself by specifications futher down in the GUI config about the PV specifications, the inverter, the forcast provider aso. OR you can “point” this information to EMHASS over API using restcommand OR shellcommand.

“sensor_power_load_no_var_loads” - this is a sensor you have to template/create yourself, and then specify in the GUI.

look at @rcruikshank documentation here
for readable documentation about setting this up using node-red.

Unfortunately I am still struggling myself, but this is a start to get a grip of how EMHASS seem to work.

Yes, David has given you some advice above. He developed EMHASS so he’s the fount of all knowledge.

EMHASS configuration via that gear icon is used to describe your environment. Some of it is difficult to understand until you get used to the way it all works. Fill it in as best you can. Some of it you may not need. My config is here but its more related to Node-Red, Amber Electric and sonnen batteries. But it might help.

I use EMHASS MPC method. There are other ways to use it but I’ll stick to that method here.

EMHASS runs in its own Docker container and only interacts with Home Assistant by publishing the results of its calculations into a number of sensors in HA that you can use to manage your battery and manage your deferrable loads.

You have to call on EMHASS to do these calculations via a RESTful API call if you are familiar with that? There are two RESTful POSTs that you have to call. The first is to send relevant data to EMHASS and the second is to ask EMHASS to publish the results back into HA sensors. You call them one after the other in the MPC method.

The data you include in the first call can be supplied in a number of ways but the way I do it and the way most people here do it is to use a Jinja2 template to compile the data in a JSON format to be included in the POST.

Some of this data may actually overwrite some of the configuration you may have entered in the EMHASS setup.

For instant there is a section in the setup where you can record the tariffs. This is fine if you have static tariffs. Your typical shoulder, peak and off peak tariffs.

However, if you have tariffs that change all the time and forecast tariff data provided from the energy market then you can’t really use this static config. You have to format the forecast data as you get it and pass it to EMHASS to do its calculation.

This is quite complicated and if you look at my doco mentioned above, you’ll see an example of how to do that in Node-Red for an energy market that changes the tariffs every 5 minutes.

Some of this forecast data can be left to the setup configuration to deal with. For example, solar production forecast can be done simply by selecting one of the options under weather forecast method.

I don’t do that. For historical reason I download PV forecast from solcast using a HACS integration and then list the forecast via my Jinja2 template along with the other data.

In the MPC method the system also needs at least the last two days of household consumption data. EMHASS gets this from the recorder database. All you have to do is list the sensor in your system that has this data and EMHASS handle it. But I used to have a lot fo trouble with unstable recorder data, so I had to create a node-red flow that captures this data and stores it in a string variable in node-red to put into the the JSON data.

You mentioned that you can only enter a number into the deferrable loads config. That’s because EMHASS only needs to know a couple of things about deferrable loads. Firstly how many you have (pool pump, hot water, EV charging etc) and whether they are a static load (e.g. a pool pump) or a variable load (e.g. charging an EV) and how long you want to run these loads. You can also manage things like operating hours.

But again this configuration vis the gear may very well be overwritten of never used if you pass this info every time you POST to EMHASS.

That’s what I do. I call this RESTful API POST every 30 seconds and pass all this data and do things like put a slide control on my dashboard so I can dynamically change the maximum power for charging my EV. EMHASS will vary the charge depending of all the other factors but won’t go over the maximum power I pass to it.

Don’t be discouraged by my unwieldy configuration document mentioned above. Its 50 odd pages and a bit woffley.

You can see the Jinja2 code I use and the JSON output from it. My config document explains more.

Still not getting there :grimacing: And from 1/10 we will change to 15min tariffs, so I winder if i will get this going, until have to redo again :rofl:

Have defined the PV-panels and inverter, using open Meteo for weather forecast (for simplicity) and now focusing on getting the Nordpooldata pushed to EMHASS and start with dayahead optimization. Logger set to debug.

Using @cavemonkeys example in a .yaml file included in config.yaml:

rest_command:
  
  trigger_nordpool_forecast:
    url: http://localhost:5000/action/dayahead-optim
    method: POST
    headers:
      content_type: "application/json"

    payload: >-

      {

      "load_cost_forecast":{{((state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_today') | map(attribute='value') | list  + state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_tomorrow') | map(attribute='value') | list))[now().hour:][:24] }},

      "prod_price_forecast":{{((state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_today') | map(attribute='value') | list  + state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_tomorrow') | map(attribute='value') | list))[now().hour:][:24]}},

      }


Testing the code in the template editor I get two arrays:

"load_cost_forecast":[54.681, 45.965, 44.769, 44.068, 45.855, 43.449, 41.895, 37.962, 15.139, 9.377, 12.21, 10.533, 4.647, 5.088, 5.088, 9.46, 26.564, 41.496, 113.888, 109.996, 81.081, 70.315, 66.094, 64.361],

"prod_price_forecast":[54.681, 45.965, 44.769, 44.068, 45.855, 43.449, 41.895, 37.962, 15.139, 9.377, 12.21, 10.533, 4.647, 5.088, 5.088, 9.46, 26.564, 41.496, 113.888, 109.996, 81.081, 70.315, 66.094, 64.361],

Triggering the rest_command from automation.yaml:

automation:
    
  - alias:  trigger nordpool and push to EMHASS
    trigger:
      platform: time
      at: '23:00:00'
    action:
    - service: rest_command.trigger_nordpool_forecast

Still I cannot get the EMHASS to do any optimization! Manually pushing the optimization task in the GUI, looking at debug logs results in:

[2025-09-07 00:20:14 +0200] [24] [ERROR] Exception on /action/dayahead-optim [POST]
Traceback (most recent call last):
  File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 1511, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 919, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/src/emhass/web_server.py", line 393, in action_call
    input_data_dict = set_input_data_dict(
                      ^^^^^^^^^^^^^^^^^^^^
  File "/app/src/emhass/command_line.py", line 306, in set_input_data_dict
    P_load_forecast = fcst.get_load_forecast(
                      ^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/src/emhass/forecast.py", line 1401, in get_load_forecast
    with open(data_path, "rb") as fid:
         ^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/data/long_train_data.pkl'
FileNotFoundError: [Errno 2] No such file or directory: '/data/long_train_data.pkl'

Any Ideas where to start looking for whats wrong?

So this output is not correct JSON format.

A trick is to use a JSON format checker. Take your output and past it into one of many JSON format validator web sites and it will tell you what is wrong.

Better yet, take your code, your output and the error logs and explain to chatgpt that you need help to debug this code to produce valid input to EMHASS API for dayahead.

Here’s an example

Or see this:

Please review the below code, output and errors from EMHASS and rewrite corrected code that produced valid JSON output for EMHASS dayahead method.

YAML Code:

type or paste code here

rest_command:
  
  trigger_nordpool_forecast:
    url: http://localhost:5000/action/dayahead-optim
    method: POST
    headers:
      content_type: "application/json"

    payload: >-

      {

      "load_cost_forecast":{{((state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_today') | map(attribute='value') | list  + state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_tomorrow') | map(attribute='value') | list))[now().hour:][:24] }},

      "prod_price_forecast":{{((state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_today') | map(attribute='value') | list  + state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_tomorrow') | map(attribute='value') | list))[now().hour:][:24]}},

      }

Output:

"load_cost_forecast":[54.681, 45.965, 44.769, 44.068, 45.855, 43.449, 41.895, 37.962, 15.139, 9.377, 12.21, 10.533, 4.647, 5.088, 5.088, 9.46, 26.564, 41.496, 113.888, 109.996, 81.081, 70.315, 66.094, 64.361],

"prod_price_forecast":[54.681, 45.965, 44.769, 44.068, 45.855, 43.449, 41.895, 37.962, 15.139, 9.377, 12.21, 10.533, 4.647, 5.088, 5.088, 9.46, 26.564, 41.496, 113.888, 109.996, 81.081, 70.315, 66.094, 64.361],

Logs:

[2025-09-07 00:20:14 +0200] [24] [ERROR] Exception on /action/dayahead-optim [POST]
Traceback (most recent call last):
  File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 1511, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 919, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/src/emhass/web_server.py", line 393, in action_call
    input_data_dict = set_input_data_dict(
                      ^^^^^^^^^^^^^^^^^^^^
  File "/app/src/emhass/command_line.py", line 306, in set_input_data_dict
    P_load_forecast = fcst.get_load_forecast(
                      ^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/src/emhass/forecast.py", line 1401, in get_load_forecast
    with open(data_path, "rb") as fid:
         ^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/data/long_train_data.pkl'
FileNotFoundError: [Errno 2] No such file or directory: '/data/long_train_data.pkl'

Automation:

automation:
    
  - alias:  trigger nordpool and push to EMHASS
    trigger:
      platform: time
      at: '23:00:00'
    action:
    - service: rest_command.trigger_nordpool_forecast
ChatGPT said:

Thanks for sharing all the detail — I can see a couple of things happening here:

Your JSON is invalid because the arrays are emitted as raw Python lists without being converted into JSON with Jinja’s tojson filter.
→ This causes EMHASS to choke when parsing the payload.

The FileNotFoundError (/data/long_train_data.pkl) is a separate EMHASS issue: when you call dayahead-optim, EMHASS expects either:

A trained load forecast model (long_train_data.pkl), or

Explicitly provided load_cost_forecast and prod_price_forecast arrays in valid JSON.

Since you’re providing the arrays yourself, the error suggests EMHASS isn’t recognising them due to the JSON formatting problem.

Here’s a corrected Home Assistant YAML that should generate valid JSON:

rest_command:
  trigger_nordpool_forecast:
    url: "http://localhost:5000/action/dayahead-optim"
    method: POST
    headers:
      Content-Type: "application/json"
    payload: >-
      {
        "load_cost_forecast": {{ (
          (state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_today') | map(attribute='value') | list
          + state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_tomorrow') | map(attribute='value') | list
        )[now().hour:][:24] | tojson }},
        
        "prod_price_forecast": {{ (
          (state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_today') | map(attribute='value') | list
          + state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_tomorrow') | map(attribute='value') | list
        )[now().hour:][:24] | tojson }}
      }

Key Fixes:

:white_check_mark: Used tojson to ensure proper JSON arrays ([…]) rather than Python-like lists.
:white_check_mark: Corrected header name: Content-Type instead of content_type.
:white_check_mark: Removed trailing comma after the last field (illegal in JSON).

Expected Payload Example

What gets POSTed to EMHASS will now look like this:

{
  "load_cost_forecast": [54.681, 45.965, 44.769, 44.068, 45.855, 43.449, 41.895, 37.962, 15.139, 9.377, 12.21, 10.533, 4.647, 5.088, 5.088, 9.46, 26.564, 41.496, 113.888, 109.996, 81.081, 70.315, 66.094, 64.361],
  "prod_price_forecast": [54.681, 45.965, 44.769, 44.068, 45.855, 43.449, 41.895, 37.962, 15.139, 9.377, 12.21, 10.533, 4.647, 5.088, 5.088, 9.46, 26.564, 41.496, 113.888, 109.996, 81.081, 70.315, 66.094, 64.361]
}

:point_right: Question for you: do you want only prices passed as both load_cost_forecast and prod_price_forecast (as you’ve written), or should one of them instead be your solar forecast (from Solcast, etc.)?

If both are meant to be the same, the above is fine. If not, I can adjust it so EMHASS gets proper price vs production forecasts.

You said:
EMHASS has been internally configured to get PV forecast data.
ChatGPT said:

Perfect — thanks, that simplifies things.

Since EMHASS already pulls the PV forecast internally, you only need to push the Nordpool price forecasts as load_cost_forecast and prod_price_forecast. That matches what you had in your YAML, so the only real problem was the JSON formatting and the header casing.

Here’s the final corrected code you can drop straight into Home Assistant:

rest_command:
  trigger_nordpool_forecast:
    url: "http://localhost:5000/action/dayahead-optim"
    method: POST
    headers:
      Content-Type: "application/json"
    payload: >-
      {
        "load_cost_forecast": {{ (
          (state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_today') | map(attribute='value') | list
          + state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_tomorrow') | map(attribute='value') | list
        )[now().hour:][:24] | tojson }},
        
        "prod_price_forecast": {{ (
          (state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_today') | map(attribute='value') | list
          + state_attr('sensor.nordpool_kwh_se3_sek_3_10_025', 'raw_tomorrow') | map(attribute='value') | list
        )[now().hour:][:24] | tojson }}
      }
automation:
  - alias: Trigger Nordpool and push to EMHASS
    trigger:
      platform: time
      at: "23:00:00"
    action:
      - service: rest_command.trigger_nordpool_forecast

Why this fixes it

tojson → ensures the list renders as valid JSON instead of Python syntax.

Content-Type → correct capitalisation so Flask interprets it properly.

Removed trailing commas → JSON is strict, so this avoids parse errors.

Your arrays (24h window starting from current hour) now align with EMHASS’s dayahead-optim expectations.

:zap: With this in place, EMHASS won’t try to look for long_train_data.pkl anymore, because it sees the load_cost_forecast and prod_price_forecast you’re sending.

Do you want me to also add a debug log step in the automation that writes out the actual JSON payload to your Home Assistant log, so you can confirm what’s being sent before EMHASS sees it?

1 Like

I sould add that the reason there are two POSTs is becuase you can call the first POST with forecast data for the day which then calculates the forecast state of your battery and deferrable loads for the day and then call the publish POST every 5 minutes thereafter to continually update the sensors in HA for your automations to react to and change the states of battery and loads.

So dayahead method you’d call once in the morning and the publish post your would call every 5 minutes throughout the day to update the HA sensors from the EMHASS table of forecast states it calculated at the beginning of the day.

MPC is different as it recalculates that table constantly and then publishes so that the forecast changes are more reactive to conditions. I call this every 30 seconds. but you can run at whatever frequency you like.

1 Like

i merging my setup from 30 min intervals to 15 min, but it keeps failing.

I think the log is not really related, but:

  • in the rest command: do all forecasts have to be the exact same length?
  • prediction horizon: is this hours or your set interval
  • is there a maximum length for the data you can send? I am now sending +/- 3 days, so arrays of each 336 data points

[2025-09-08 11:53:09 +0200] [27] [ERROR] Exception on /action/naive-mpc-optim [POST]
Traceback (most recent call last):
File “/app/.venv/lib/python3.12/site-packages/flask/app.py”, line 1511, in wsgi_app
response = self.full_dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/app/.venv/lib/python3.12/site-packages/flask/app.py”, line 919, in full_dispatch_request
rv = self.handle_user_exception(e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/app/.venv/lib/python3.12/site-packages/flask/app.py”, line 917, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File “/app/.venv/lib/python3.12/site-packages/flask/app.py”, line 902, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/app/src/emhass/web_server.py”, line 393, in action_call
input_data_dict = set_input_data_dict(
^^^^^^^^^^^^^^^^^^^^
File “/app/src/emhass/command_line.py”, line 381, in set_input_data_dict
df_weather = fcst.get_weather_forecast(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/app/src/emhass/forecast.py”, line 583, in get_weather_forecast
“ts”: list(data_raw[“result”][“watts”].keys()),
~~~~~~~~~~~~~~~~~~^^^^^^^^^
TypeError: string indices must be integers, not ‘str’

First of all make sure you set 15 minutes in EMHASS internal configuration. I should have identified ta bug that prevents to correctly use the runtime parameter: Error with optimization_time_step = 15 and open-meteo method · Issue #563 · davidusb-geek/emhass · GitHub

Then you need consistency among the prediction horizon, resolution, arrays.

(your reply is much appreciated, sorry for taking so long to get back to you [life is a competitive beast… :wink: ] )

I fully understand what you mean by the cog gear and I do get the idea that I should use the GUI to input any settings needed but this is where I think I miss something crucial.

Referring to the included picture I can write a value in ‘deferrable loads’ and I can click save, but if I go to some other page and come back nothing is saved.
I probably would expect that I could click on ‘deferrable loads’ and get more options available (like setting how many hours per day the load should be available and so on) but nothing happens.
If I click on ‘yaml’ or ‘defaults’ nothing happens either.

I am normally using a chromebook running chrome to access Home Assistant (running on a Home Assistant Green) for setting things up but have also tried running firefox, and trying to access the settings using my mobile (both app and browser) so something seems to elude me here…

Note; not saying there is anything wrong with Emhass, on the contrary from what I can see it would help me much. I would guess it is either something really obvious that I miss here or I have some incompatibility in my HA setup…

What I am trying to accomplish as a first use case is something rather simple; have an electrical water boiler that I can control using a shelly and would like to run it the cheapest hours (based on prices from NordPool).

Thanks,

The error was on my side, so all good now!

and BTW this forks provides 15M data for nordpool

available in HACS

Ok I understand.
That is some wierd behavior you are having there.
But yes definetly putting an integer number on that box should deploy a series of options that you can fill in to define each deferrable load.
This is what I have for 1 defeerable load:

I’m not able to reproduce your issue, so this could be tricky to solve.
Maybe it can be fixed with some cache clearing and a HA restart?

For my both this and the YAML button works well.

Tried to run the browser in incognito mode (which should be similar to clear the cache (unless you mean clean a cache in Home Assistant somehow?)), and also rebooted the Home Assistant Green in Safe Mode and even while I still could access the GUI the behavior was the same :frowning:

Is there any logs from HA that could possibly give some clues?

And while I understand that making any settings should be done through the GUI is there any way to access a settings file since the GUI settings does not work for me?

I am running Home Assistant on a Home Assistant Green system it is the HAOS version - shouldn’t make any difference I believe?

This is odd since I haven’t really tinkered with HA much I haven’t set up so many things that could interfere with EMHASS I guess…

Well, if anyone has any idea what to try I am all ears :slight_smile:

Yes, go to the add-on configuration pane and select the folder path as the “/share” folder:

Then you should access the share partition using the terminal add-on and “cd share”:

In there you can try and edit the “config.json” using “nano config.json” and then save and restart the EMHASS add-on.