EMHASS: An Energy Management for Home Assistant

Thank you!
That helped me a lot!

What I don’t understand so far is the meaning of:
“Sensor to replace NAN values with 0s”
“Sensor to replace NAN values with linear interpolation”

First I forgot to update the first one (it used the default and my optimizations failed.
I then put in both, my “PV”- and “no_var_loads”- senser, and it worked.

could somebody explain, what this is for?

Well, I might understand in general the meaning, but not for this specific case and why this is “new” and mandatory for the addon.

One more thing:
When I open the log in the Addon, I get the error:
Failed to get 5b918bf2_emhass logs, e.callApiRaw is not a function.
I can download it, but it is not shown in the browser.

The logging is due to a change in HA. I believe upgrading HA Core to 2024.11.x will solve it.

I currently access EMHASS logs via Settings > System > Logs > EMHASS (from the dropdown)

Somehow I probably made a terrible mistake by installing an update without reading what the changes are beforehand.
My log is full of error messages.
Can anyone advise me on the best course of action?

Updating rest commands without restarting is possible. In “Developer tools”-> “YAML” → and under “YAML configuration reloading” click on “RESTFUL COMMAND”

here’s a recent link to how to upgrade - EMHASS: An Energy Management for Home Assistant - #2840 by 110hs
Take note of step 6, this is where you can view your previous settings.

PV solar predictions from multiple invertors/strings using forecast.solar.

I have a system with 3 different strings of solar panels each with their own azimuth, inclination and inverter. In home assistant I have 3 forecast.solar services that are used in the energy dashboard to show the dotted line predictions. Now for emhass I want to pass (the sum of) these 3 predictions to the daily and mpc optimizer.

Seems like when using the forecast.solar method for weather_forecast_method in emhass I can only pass one inverter size.
Sadly, the predictions that are shown in the energy dashboard are not in the Home Assistant sensor attributes.
So I guess the only way to get 48 half hour blocks of predicted solar for the 3 systems to send to emhass I would have to make 3 rest sensors, call the https://api.forecast.solar/estimate API directly, and add the results trough some templating magic?

Please tell me there is an easier way? Searching the forum I found someone using nodered but that is something I want to avoid.

Yes you will need to do some templating magic like you said.

If you have a paid solar.forecast account and number of API calls is not an issue, then a second option is to configure your 3 roofs in the EMHASS configurator and then pick the solar.forecast as the method for PV forecast. This should work fine.

When data is not available, the sensor values will be replaced with zero.
I set this to my PV sensor.

When data is not available the missing values are computed via linear interpolation. I set this to my load forecast sensor.

I don’t expect these scenarios to happen often but using these sensors makes sense to me.

You probably are not running the latest version of HA. Install the updates. This was fixed.

thank you!

now I understand better. The only thing is, it is mandatory now, and if you don’t edit the default, it will fail.

for the logs: yes, I did the update now and it works.
but: after a few seconds in the log, I see a new error:

Failed to get 5b918bf2_emhass logs, Error in input stream

I guess it tries to load further data and fails for some reason. maybe a bug?

Since updating to the latest version of EMHASS (I come from v0.8.6, so I skipped quite some versions), I see following odd behavior:
Every time the MPC optimization is run and results are published, my deferrable load 1 power gets pushed forward into the future, with the result that my “Deferrable Load 1” sensor value always remains at 0W.

In my case, deferrable load 1 is my electric vehicle charger, configured as a non-semi-continuous load in EMHASS. In the screenshots below it is labeled as “Laadpaal”.

Optimization run 1:
image

Optimization run 2:
image

Optimization run 3:
image

As you can see, the car will never start charging.
Is there a certain config causing this behaviour?

1 Like

I have a question for everyone in this thread.
I am planning to purchase a home battery.
Now I would like to know which brands are easy to integrate with home assistant.
I live in Belgium and we have 3 phases.
I would also like an ac-coupled system.

What do the other parameters look like? Deferrable end timestamp and Deferrable start timestamp; Cool apexcharts by the way, how did you get the forecasted values in there?

Sonnen works well with a full featured RESTful API for controlling the battery.

Hello,

can I ask you if the shelly is used just as “clean contact” or you are using 230V to supply the SG signal? My Ariston NUOS has got the SG pins but the manual says “attention: 230V signal” which it seems strange…

Thanks
Davide

Yes the SG ready signal is 230v switched via the Shelly.

ok, so if I choose weather_forecast_method solar.forcast in config and set a list of 3 values for surface_tilt and surface_azimuth it should work? he option to set inverter size seems to be missing in the new settings screen (tthere used used to be optional_solar_forecast_kwp in the previous settings screen) . I guess I can pass them all as runtime parameters.
emhass will make the API call’s with the correct lat/long coordinates set in home assistant?
If I pass them as runtime parameters in the mpc optimizer will the solar.forcast api be called every time it runs for all 3 systems or is there some kind of buffering?

This is the bit of code currently implemented to retrieve solar.forecast data:

url = "https://api.forecast.solar/estimate/"+str(round(self.lat, 2))+"/"+str(round(self.lon, 2))+\
                    "/"+str(self.plant_conf['surface_tilt'][i])+"/"+str(self.plant_conf['surface_azimuth'][i]-180)+\
                    "/"+str(self.retrieve_hass_conf["solar_forecast_kwp"])

So yes the list of values for tilt and azimuth should work.
Then, yes optional_solar_forecast_kwp can be set at runtime.
As you can see in the code snippet the lat/lon are currently defined as secrets in the add-on configuration pane (use the optional check to unlock these). But in the near future these and the local curreny will be retrieved directly from HA.
There is no buffer, the API is called with this URL inside a for loop, so in your case 3 API calls for each MPC run.

2 Likes

Hi Sam,

Some more info on my config:
I provide following parameters at runtime:

{
"load_cost_forecast": [0.247, 0.247, 0.23, 0.23, 0.236, 0.236, 0.25, 0.25, 0.264, 0.264, 0.22, 0.22, 0.213, 0.213, 0.206, 0.206, 0.201, 0.201, 0.207, 0.207, 0.206, 0.206, 0.214, 0.214, 0.221, 0.221, 0.207, 0.207, 0.2, 0.2, 0.19, 0.19, 0.191, 0.191, 0.19, 0.19, 0.196, 0.196, 0.212, 0.212, 0.206, 0.206, 0.218, 0.218, 0.214, 0.214, 0.2, 0.2, 0.188, 0.188],
"prod_price_forecast":[0.13, 0.13, 0.113, 0.113, 0.119, 0.119, 0.133, 0.133, 0.147, 0.147, 0.103, 0.103, 0.097, 0.097, 0.089, 0.089, 0.084, 0.084, 0.09, 0.09, 0.09, 0.09, 0.097, 0.097, 0.104, 0.104, 0.091, 0.091, 0.084, 0.084, 0.074, 0.074, 0.075, 0.075, 0.073, 0.073, 0.079, 0.079, 0.096, 0.096, 0.089, 0.089, 0.101, 0.101, 0.097, 0.097, 0.083, 0.083, 0.071, 0.071],
"pv_power_forecast":[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, 0, 0, 0, 0, 2, 26, 62, 101, 154, 197, 222, 244, 249, 235, 217, 187, 165, 133, 91, 55, 24, 2, 0],
"def_total_hours": [20, 0],
"def_start_timestep": [0,0],
"def_end_timestep": [0,-25],
"prediction_horizon": 48,
"soc_init": 0.08
}

This is generated dynamically using templating in Node-Red.
This worked before, but since my last update of EMHASS, the abovementioned issue began.

Here’s my EMHASS config file:

{
  "battery_charge_efficiency": 0.95,
  "battery_charge_power_max": 3000,
  "battery_discharge_efficiency": 0.95,
  "battery_discharge_power_max": 3000,
  "battery_dynamic_max": 0.9,
  "battery_dynamic_min": -0.9,
  "battery_maximum_state_of_charge": 0.9,
  "battery_minimum_state_of_charge": 0.02,
  "battery_nominal_energy_capacity": 8000,
  "battery_target_state_of_charge": 0.6,
  "compute_curtailment": false,
  "continual_publish": false,
  "costfun": "profit",
  "delta_forecast_daily": 1,
  "end_timesteps_of_each_deferrable_load": [
    0,
    9
  ],
  "historic_days_to_retrieve": 2,
  "inverter_is_hybrid": false,
  "load_cost_forecast_method": "hp_hc_periods",
  "load_forecast_method": "naive",
  "load_negative": false,
  "load_offpeak_hours_cost": 0.1419,
  "load_peak_hour_periods": {
    "period_hp_1": [
      {
        "start": "02:54"
      },
      {
        "end": "15:24"
      }
    ],
    "period_hp_2": [
      {
        "start": "17:24"
      },
      {
        "end": "20:24"
      }
    ]
  },
  "load_peak_hours_cost": 0.1907,
  "logging_level": "DEBUG",
  "lp_solver": "COIN_CMD",
  "lp_solver_path": "empty",
  "maximum_power_from_grid": 8000,
  "maximum_power_to_grid": 9000,
  "method_ts_round": "first",
  "modules_per_string": [
    16
  ],
  "nominal_power_of_deferrable_loads": [
    2400,
    7360
  ],
  "number_of_deferrable_loads": 2,
  "operating_hours_of_each_deferrable_load": [
    18,
    1
  ],
  "optimization_time_step": 30,
  "photovoltaic_production_sell_price": 0.1419,
  "production_price_forecast_method": "constant",
  "pv_inverter_model": [
    "Fronius_International_GmbH__Fronius_Primo_5_0_1_208_240__240V_"
  ],
  "pv_module_model": [
    "CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M"
  ],
  "sensor_linear_interp": [
    "sensor.pv1_inverter_watts",
    "sensor.power_load_no_var_loads"
  ],
  "sensor_power_load_no_var_loads": "sensor.power_load_no_var_loads",
  "sensor_power_photovoltaics": "sensor.pv1_inverter_watts",
  "sensor_replace_zero": [
    "sensor.pv1_inverter_watts"
  ],
  "set_battery_dynamic": false,
  "set_deferrable_load_single_constant": [
    false,
    false
  ],
  "set_deferrable_startup_penalty": [
    0,
    0
  ],
  "set_nocharge_from_grid": false,
  "set_nodischarge_to_grid": false,
  "set_total_pv_sell": false,
  "set_use_battery": true,
  "set_zero_min": true,
  "start_timesteps_of_each_deferrable_load": [
    0,
    3
  ],
  "strings_per_inverter": [
    1
  ],
  "surface_azimuth": [
    205
  ],
  "surface_tilt": [
    30
  ],
  "treat_deferrable_load_as_semi_cont": [
    true,
    false
  ],
  "weather_forecast_method": "scrapper",
  "weight_battery_charge": 0.01,
  "weight_battery_discharge": 0.01
}

If you’d like the same chart is I have, here’s the code :slightly_smiling_face:
image

YAML code:

type: custom:apexcharts-card
span:
  start: minute
header:
  show: true
  title: Optimizer
  show_states: true
  colorize_states: true
now:
  show: true
yaxis:
  - id: power
    decimals: 0
    max: 8000
  - id: price
    decimals: 3
    opposite: true
series:
  - entity: sensor.p_pv_forecast
    yaxis_id: power
    curve: stepline
    show:
      in_header: before_now
      legend_value: false
    stroke_width: 1
    data_generator: |
      return entity.attributes.forecasts.map((entry) => {
        return [new Date(entry.date), entry.p_pv_forecast];
      });
  - entity: sensor.p_load_forecast
    yaxis_id: power
    curve: stepline
    show:
      in_header: before_now
      legend_value: false
    stroke_width: 1
    data_generator: |
      return entity.attributes.forecasts.map((entry) => {
        return [new Date(entry.date), entry.p_load_forecast];
      });
  - entity: sensor.p_deferrable0
    name: Warmtepomp
    yaxis_id: power
    type: area
    stroke_width: 2
    show:
      in_header: before_now
      legend_value: false
    data_generator: |
      return entity.attributes.deferrables_schedule.map((entry) => {
        return [new Date(entry.date), entry.p_deferrable0];
      });
  - entity: sensor.p_deferrable1
    name: Laadpaal
    yaxis_id: power
    type: area
    stroke_width: 2
    show:
      in_header: before_now
      legend_value: false
    data_generator: |
      return entity.attributes.deferrables_schedule.map((entry) => {
        return [new Date(entry.date), entry.p_deferrable1];
      });
  - entity: sensor.current_electricity_price_offtake
    name: Afnametarief
    curve: stepline
    stroke_width: 1
    data_generator: |
      return entity.attributes.prices.map((entry) => {
        return [new Date(entry.time), entry.price];
      });
    show:
      legend_value: false
      in_header: before_now
    yaxis_id: price
    float_precision: 3

Ok but still I would need just a dry contact to close the SG pins…otherwise I’m quite puzzled I should put 230V on the SG pins

That’s how the circuit board had been designed.


1000006727

1 Like