EMHASS: An Energy Management for Home Assistant

I use negative values in load_no_var history, without an issue.

I think the sensitivity is if there is a gap in the data over the minimum 2 days, EMHASS cannot do the calculation from internal data.

My workaround is to provide an explicit load_power_forecast in my MPC payload, so EMHASS doesn’t need to be calculated. The power forecast can be anything, but I use my HVAC power consumption (as a function of temperature) as that is one of my big loads.

        "load_power_forecast": {{
          ([states('sensor.power_load_no_var_loads')|int] +
          states('sensor.hvac_power_forecast') | from_json | map('multiply', 1000) | list 
          )| tojson 
        }}, 
"load_power_forecast": [4217, 6000.0, 6000.0, 6000.0, 6000.0, 6000.0, 8000.0, 8000.0, 8000.0, 8000.0, 6000.0, 6000.0, 4000.0, 4000.0, 4000.0, 4000.0, 2000.0, 2000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 2000.0, 2000.0, 4000.0, 4000.0, 6000.0],
1 Like

Thanks Mark, did you automate this? Eg if shell command with the sensor generates an error use other shell command with this fixed load? If i a not mistaken the shell commands nowadays provide feedback.

Or do i misunderstand and is your sensor always fed like this? How do you manage the calculation? Unless mistaken emhass requires (in my case) 24 hourly averages right? My sensor provides 30sec values

This is a limitation on the HA core API used by EMHASS to retrieve data.
Here is the official API documentation: https://developers.home-assistant.io/docs/api/rest
We are using the /api/history/period/<timestamp> GET endpoint.

The EMHASS code is actually ready to receive data with “holes” (NaN’s) and properly fill them using linear interpolation with simple Pandas methods.
However the data never reach EMHASS, so nothing to do here.
If anyone has a better solution to this I’m willing to hear about it to see if we can improve this inconvenient behavior.

2 Likes

I’m interested in people’s strategies for influencing when the battery charges and discharges.

In my case I don’t really want the battery to discharge below about 15¢/ kWh but I am happy for the battery to charge fully almost every day at the cheapest times.

I have been playing around with the battery_weight values and I find with a discharge_weight of 0.15 and a charge_weight of 0, the battery doesn’t discharge unnecessarily. As you can see below it charges enough for the discharges above the desired threshold set by discharge_weight.

However, I can’t get it to bias towards additional charging, once tried setting the charge_weight to a negative value and setting soc_final to 1.0.

Any other ideas?

1 Like

Good Idea.
I was just thinking that maybe changing the load forecast to realtime load for next 30mins + static load for the next 24hrs. I.e. usage of non-deferrable loads is reasonably constant day-to-day. I guess apart from the HVAC use you have identified.

Another question please, here in Australia, most DNSPs restrict solar feed-in to 5KW.

Is there an easy way to influence EMHASS so that any P_PV value over 5000 is treated as 0c/pKWh? and should be self consumed if possible?

E.g. here is a good example; my P_deferrable0 (EV, light blue) is ramping down this afternoon due to unit_prod_price is higher now than what it will be tomorrow. This is exactly what EMHASS should do. tick!

However EMHASS doesn’t know that anything above 5KW is curtailed and wasted by the inverter. I could solve this by increasing the charge rate of the EV charger (not easy) or by modifying the deferrable0 automation task… but is there a better way?

There was some discussion about setting a max discharge to the grid value, but I don’t think it has been implemented yet.

This is a work in progress at this PR: https://github.com/davidusb-geek/emhass/pull/168
It seems finished so probably integrating this in the next release.

1 Like

Perhaps you could cap your (solcast?) forecast to 5000? Then EMHASS will calculate with that and will ‘use’ more of the grid, but essentially using the 5000+ portion?

If you cap the PV forecast to 5000 W, then EMHASS will only optimize the 5000 W of generation, say 1000W for your load and 4000W for grid export.

In the situation you are generating say 8000W and your load is say only 1000W, with a max_,export constraint EMHASS can allocate up to 5000W for grid export and then allocate the remaining 2000W to a load or even your battery.

Setting soc_final=1 seems better, but we’re still see what happens at midday when tomorrow’s prices forecasts come in.

Perfect. I will keep an eye on the PR.

new EMHASS install here. It installed, then I left it a bit, it has had several updates along the way, but I’ve never been able to get it “working”. Just been digging a bit deeper and I see this in the logs:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/usr/local/lib/python3.11/dist-packages/emhass/web_server.py", line 13, in <module>
    import pandas as pd
  File "/usr/local/lib/python3.11/dist-packages/pandas/__init__.py", line 16, in <module>
    raise ImportError(
ImportError: Unable to import required dependencies:
numpy: Error importing numpy: you should not try to import numpy from
        its source directory; please exit the numpy source tree, and relaunch
        your python interpreter from there.

I’m (currently) running addon 0.6.5 on HAOS 11.4, Core 2024.1.5. The web server won’t start because of the above (that error sequence loops so I don’t know where it starts/stops, but contains all the info). I just get 502 bad gateway when I try to go to the menu item on the left nav bar. I reckon it’s something simple I’m missing, but I can’t for the life of me figure out what it might be. Debug level messages didn’t get me any more info above the default.

Are you on a RPi? Which version?
Currently Armhf architectures are not supported.

Can emhass deal with unknown running times and how should I do that?
The problem is my washing machine uses “fuzzy logic”.
When I start the normal program it can run from 3hours up until 4,5 hours depending on the load in the machine, how dirty the clothes are…
I use a tapo smart plug to start and stop the machine.
Sadly the machine has no interface I can feed into HA.

1 Like

Hello,

I am new to Emhass. Thanks for this amazing project! The learning curve is a bit steep, but getting there.

I am trying to automate my shell command and pass my own data into the algorithm, starting with Nordpool cost data. I am running following shell command:

curl -i -H \"Content-Type: application/json\" -X POST -d '{\"load_cost_forecast\":{{((state_attr('sensor.nordpool', 'raw_today') | map(attribute='value') | list + state_attr('sensor.nordpool', 'raw_tomorrow') | map(attribute='value') | list))[now().hour:][:24] }},\"prod_price_forecast\":{{((state_attr('sensor.nordpool_kwh_be_eur_3_10_021', 'raw_today') | map(attribute='value') | list + state_attr('sensor.nordpool_kwh_be_eur_3_10_021', 'raw_tomorrow') | map(attribute='value') | list))[now().hour:][:24]}}}' http://localhost:5000/action/dayahead-optim

But getting error: 400 bad request while running it manually via the Homeassistant SSH add-on. Don’t see any entries into the Emhass logs as well.

A regular shell command without any own data works fine… Similar issue when I am trying to pass Solcast data.

Any pointers where I should be looking?

Thanks!

Or run dayahead for two days as that doesn’t rely on the history data.

This formatting is very tricky indeed.
Try putting all this block into the template editor on the developer tools:

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

If that look good then there is maybe need to add a tojson at the end of each list, like this:

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

I hope it helps…

What does your jinja template return in the developer tools renderer? Does the output look correct?

Take your template and past it into the renderer and closely review the output or take the output and test it in a JSON validator like https://jsonlint.com/ to make sure it’s valid JSON format.

{"load_cost_forecast":{{((state_attr(‘sensor.nordpool’, ‘raw_today’) | map(attribute=‘value’) | list + state_attr(‘sensor.nordpool’, ‘raw_tomorrow’) | map(attribute=‘value’) | list))[now().hour:][:24] }},"prod_price_forecast":{{((state_attr(‘sensor.nordpool_kwh_be_eur_3_10_021’, ‘raw_today’) | map(attribute=‘value’) | list + state_attr(‘sensor.nordpool_kwh_be_eur_3_10_021’, ‘raw_tomorrow’) | map(attribute=‘value’) | list))[now().hour:][:24]}}}

1 Like

Nice feature that json testing.
I’m almost sure that this is the solution, adding the tojson function:

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