EMHASS: An Energy Management for Home Assistant

Am I right in assuming that soc_init should be a decimal, not a percentage?

Currently I have the following in post_mpc_optim_solcast:

"soc_init":{{(states(''sensor.sonnenbatterie_84324_state_charge_user'')|float(0))/100
    }},"soc_final":1.0,

Where sensor.sonnenbatterie_84324_state_charge_user is alway a number between 0 and 100 being the percentage of battery remaining. I suspect this should be 0 to 1 being a decimal representation of the percentage charge remaining?

Thanks Mark
Can you share the automation script?
I think you have to force data update before checking if car is home and plugged in and then calculate AMPS required?

* entity: button.tesla_force_data_update, call service: button.press 
* entity: device_tracker.tesla_location_tracker, state: is home
* entity: binary_sensor.tesla_charger, state: is on
* entity: number.tesla_charging_amps,  call service: 
{
  "number": {
    "tesla_charging_amps": {"$expr": {"$divide": ["$sensor.p_deferrable3", "$sensor.sonnenbatterie_84324_meter_production_4_1_v_l1_n"]}}
  }
} 
or in other words set the tesla charging amps to deferrable3 Watts / current voltage?
* entity: switch.tesla_charger, call service: turn_on 
* entity: switch.tesla_charger, call service: turn_off whendeferrable3 goes to zero.
possibly with some hysteresis delays around on and off. 

or something like that?

Thanks
Rob

What does this expand to in developer tools:template?

It should be between 0-1 with the /100 statement.

Here it is;

alias: p_deferrable5 automation (EV2)
description: EV2 charging
trigger:
  - platform: state
    entity_id:
      - sensor.p_deferrable5
condition:
  - condition: zone
    entity_id: device_tracker.location_tracker
    zone: zone.home
  - condition: state
    entity_id: binary_sensor.charger
    state: "on"
action:
  - service: number.set_value
    data:
      value: >-
        {{min(state_attr('number.charging_amps','max'),states('sensor.p_deferrable5')|int(0)
        / (state_attr('sensor.charger_power','charger_phases')*3/2)|int(1)     /
        max(220,state_attr('sensor.charger_power','charger_volts')|int(230)))|round(0)}}
    target:
      entity_id: number.charging_amps
mode: single

Yep. Current value of sensor.sonnenbatterie_84324_state_charge_user is 88.

- platform: template
    sensors:
      sonnenbatterie_84324_state_charge_user_decimal:
        value_template: >-
          
          0.88
1 Like

ok something went wrong. I think maybe the cause was the car charger settings. I haven’t set up the automation yet. But I set have up the following.

In post_mpc_optim_solcast (p_deferrable3 is the car):

  • “def_total_hours”:[2,2,2,2]}

In EMHASS config:

  • nominal_power_of_deferrable_loads: 3300
  • operating_hours_of_each_deferrable_load: 2
  • peak_hours_periods_start_hours “03:00”
  • peak_hours_periods_end_hours: “20:00”
  • treat_deferrable_load_as_semi_cont: false

And the system charged the battery all night before a sunny day? I’ll have to charge the car all morning to stop feed-in during negative FiT rates.


Although deferrable3 was at 0 and still is:

Now why would it do that?

Seems to be back to normal for tomorrow:

Sounds unexpected.

Can you show all your EMHASS sensors on one history card so we can see what was going on last night.


Thanks

I switched to self consumption at 07:40 and charged the car until the battery reached 30% at 10:00.

Looks like grid power forecast has gone high. I was trying to set up car charging last night. Changed def_total_hours from 0 to 2 for deferred3 (car) and other settings in EMHASS config relating to deferrable3.

Maybe add the prices as well, if it was very cheap overnight maybe it thought it was better to charge battery overnight.

Interesting. Looks like amber general price was either lost or stuck overnight at 13c. Not that low but low enough. It was 3c in the afternoon but was probably trying to charge at that time as well. Just goes to show you need a Price * Watt/time graph as well. Might set up a sensor for that.

Still something wrong. High price (43c/kWh) but .p_batt_forecast still trying to charge the battery at full rate when the battery is 100% charged?

1 Like

Formatting is going wrong, I suspect it is your data.

Can you go back to display the table from :5000?

I’m only running the following shell commands:

  1. post_amber_forecast at 5:30am
  2. post_mpc_optim_solcast - every 60 second
  3. publish_data - every 60 second
shell_command:
  dayahead_optim: 'curl -i -H "Content-Type: application/json" -X POST -d ''{}'' http://localhost:5000/action/dayahead-optim'
  publish_data: 'curl -i -H "Content-Type: application/json" -X POST -d ''{}'' http://localhost:5000/action/publish-data'
  post_amber_forecast:
    'curl -i -H ''Content-Type: application/json'' -X POST -d ''{"prod_price_forecast":{{(
    state_attr(''sensor.cecil_st_feed_in_forecast'', ''forecasts'')|map(attribute=''per_kwh'')|list)
    }},"load_cost_forecast":{{(
    state_attr(''sensor.cecil_st_general_forecast'', ''forecasts'') |map(attribute=''per_kwh'')|list)
    }},"prediction_horizon":33}'' http://localhost:5000/action/dayahead-optim'
  post_emhass_forecast:
    'curl -i -H ''Content-Type: application/json'' -X POST -d ''{"prod_price_forecast":{{(
    state_attr(''sensor.cecil_st_feed_in_forecast'', ''forecasts'')|map(attribute=''per_kwh'')|list)
    }},{{states(''sensor.solcast_24hrs_forecast'')}},"load_cost_forecast":{{(
    state_attr(''sensor.cecil_st_general_forecast'', ''forecasts'') |map(attribute=''per_kwh'')|list)
    }}}'' http://localhost:5000/action/dayahead-optim'
  post_mpc_optim_solcast:
    'curl -i -H "Content-Type: application/json" -X POST -d ''{"load_cost_forecast":{{(
    ([states(''sensor.cecil_st_general_price'')|float(0)] +
    state_attr(''sensor.cecil_st_general_forecast'', ''forecasts'') |map(attribute=''per_kwh'')|list)[:48])
    }}, "prod_price_forecast":{{(
    ([states(''sensor.cecil_st_feed_in_price'')|float(0)] +
    state_attr(''sensor.cecil_st_feed_in_forecast'', ''forecasts'')|map(attribute=''per_kwh'')|list)[:48])
    }}, "pv_power_forecast":{{states(''sensor.solcast_24hrs_forecast'')
    }}, "prediction_horizon":48,"soc_init":{{(states(''sensor.sonnenbatterie_84324_state_charge_user_decimal'')|float(0))/100
    }},"soc_final":1.0,"def_total_hours":[2,2,2,2]}'' http://localhost:5000/action/naive-mpc-optim'
# def_total_hours [Deferrable_0=PoolPump] [Deferrable_1=DW] [Deferrable_2=WM&D] [Deferrable_3=tesla] 

Only deferrable0 (pool pump) is actually being automated. The other 3 are possibly not suitable (dishwasher, Washing machine and dryer and car charger) as they are used randomly. May remove them as deferrables.

PV forecast

sensor:
  - platform: rest
    name: "Solcast Forecast Data"
    json_attributes:
      - forecasts
    resource: https://api.solcast.com.au/rooftop_sites/XXXX-XXXX-XXXX-XXXX/forecasts?format=json&api_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX&hours=24
    method: GET
    value_template: "{{ (value_json.forecasts[0].pv_estimate)|round(2) }}"
    unit_of_measurement: "kW"
    device_class: power
    scan_interval: 00:30
    force_update: true

Getting some errors in logs:

2023-07-10 17:35:03,254 - web_server - INFO - Performing naive MPC optimization
2023-07-10 17:35:03,268 - web_server - INFO - Perform an iteration of a naive MPC controller
2023-07-10 17:35:03,381 - web_server - INFO - Status: Infeasible
2023-07-10 17:35:03,382 - web_server - INFO - Total value of the Cost function = -3.63
2023-07-10 17:35:03,796 - web_server - INFO - Setting up needed data
2023-07-10 17:35:03,799 - web_server - INFO -  >> Publishing data...
2023-07-10 17:35:03,799 - web_server - INFO - Publishing data to HASS instance
2023-07-10 17:35:03,816 - web_server - INFO - Successfully posted to sensor.p_pv_forecast = -0.75
2023-07-10 17:35:03,828 - web_server - INFO - Successfully posted to sensor.p_load_forecast = 994.22
2023-07-10 17:35:03,839 - web_server - INFO - Successfully posted to sensor.p_deferrable0 = 0.0
2023-07-10 17:35:03,850 - web_server - INFO - Successfully posted to sensor.p_deferrable1 = 0.0
2023-07-10 17:35:03,861 - web_server - INFO - Successfully posted to sensor.p_deferrable2 = 0.0
2023-07-10 17:35:03,877 - web_server - INFO - Successfully posted to sensor.p_deferrable3 = 0.0
2023-07-10 17:35:03,890 - web_server - INFO - Successfully posted to sensor.p_batt_forecast = -1945.26
2023-07-10 17:35:03,899 - web_server - INFO - Successfully posted to sensor.soc_batt_forecast = 10.0
2023-07-10 17:35:03,909 - web_server - INFO - Successfully posted to sensor.p_grid_forecast = 2940.24
2023-07-10 17:35:03,918 - web_server - INFO - Successfully posted to sensor.total_cost_fun_value = -3.63
2023-07-10 17:35:03,931 - web_server - INFO - Successfully posted to sensor.unit_load_cost = 0.52
2023-07-10 17:35:03,942 - web_server - INFO - Successfully posted to sensor.unit_prod_price = 0.42
2023-07-10 17:36:00,051 - web_server - INFO - Setting up needed data
2023-07-10 17:36:00,053 - web_server - ERROR - ERROR: The passed data is either not a list or the length is not correct, length should be 48
2023-07-10 17:36:00,053 - web_server - ERROR - Passed type is <class 'list'> and length is 48
2023-07-10 17:36:00,056 - web_server - INFO - Retrieve hass get data method initiated...
2023-07-10 17:36:00,691 - web_server - INFO - Retrieving weather forecast data using method = scrapper
2023-07-10 17:36:02,463 - web_server - INFO - Retrieving data from hass for load forecast using method = naive
2023-07-10 17:36:02,464 - web_server - INFO - Retrieve hass get data method initiated...
2023-07-10 17:36:03,907 - web_server - INFO -  >> Performing naive MPC optimization...
2023-07-10 17:36:03,908 - web_server - INFO - Performing naive MPC optimization
2023-07-10 17:36:03,917 - web_server - INFO - Perform an iteration of a naive MPC controller
2023-07-10 17:36:04,016 - web_server - INFO - Status: Infeasible
2023-07-10 17:36:04,017 - web_server - INFO - Total value of the Cost function = -3.61
2023-07-10 17:36:04,356 - web_server - INFO - Setting up needed data
2023-07-10 17:36:04,359 - web_server - INFO -  >> Publishing data...
2023-07-10 17:36:04,359 - web_server - INFO - Publishing data to HASS instance
2023-07-10 17:36:04,374 - web_server - INFO - Successfully posted to sensor.p_pv_forecast = -0.75
2023-07-10 17:36:04,387 - web_server - INFO - Successfully posted to sensor.p_load_forecast = 996.8
2023-07-10 17:36:04,398 - web_server - INFO - Successfully posted to sensor.p_deferrable0 = 0.0
2023-07-10 17:36:04,410 - web_server - INFO - Successfully posted to sensor.p_deferrable1 = 0.0
2023-07-10 17:36:04,421 - web_server - INFO - Successfully posted to sensor.p_deferrable2 = 0.0
2023-07-10 17:36:04,433 - web_server - INFO - Successfully posted to sensor.p_deferrable3 = 0.0
2023-07-10 17:36:04,445 - web_server - INFO - Successfully posted to sensor.p_batt_forecast = -1947.37
2023-07-10 17:36:04,458 - web_server - INFO - Successfully posted to sensor.soc_batt_forecast = 10.0
2023-07-10 17:36:04,473 - web_server - INFO - Successfully posted to sensor.p_grid_forecast = 2944.92
2023-07-10 17:36:04,486 - web_server - INFO - Successfully posted to sensor.total_cost_fun_value = -3.61
2023-07-10 17:36:04,502 - web_server - INFO - Successfully posted to sensor.unit_load_cost = 0.52
2023-07-10 17:36:04,517 - web_server - INFO - Successfully posted to sensor.unit_prod_price = 0.42
2023-07-10 17:37:00,032 - web_server - INFO - Setting up needed data
2023-07-10 17:37:00,033 - web_server - ERROR - ERROR: The passed data is either not a list or the length is not correct, length should be 48
2023-07-10 17:37:00,033 - web_server - ERROR - Passed type is <class 'list'> and length is 48
2023-07-10 17:37:00,035 - web_server - INFO - Retrieve hass get data method initiated...
2023-07-10 17:37:00,591 - web_server - INFO - Retrieving weather forecast data using method = scrapper
2023-07-10 17:37:02,428 - web_server - INFO - Retrieving data from hass for load forecast using method = naive
2023-07-10 17:37:02,428 - web_server - INFO - Retrieve hass get data method initiated...
2023-07-10 17:37:03,474 - web_server - INFO -  >> Performing naive MPC optimization...
2023-07-10 17:37:03,474 - web_server - INFO - Performing naive MPC optimization
2023-07-10 17:37:03,486 - web_server - INFO - Perform an iteration of a naive MPC controller
2023-07-10 17:37:03,638 - web_server - INFO - Status: Infeasible
2023-07-10 17:37:03,639 - web_server - INFO - Total value of the Cost function = -3.6
2023-07-10 17:37:04,056 - web_server - INFO - Setting up needed data
2023-07-10 17:37:04,058 - web_server - INFO -  >> Publishing data...
2023-07-10 17:37:04,058 - web_server - INFO - Publishing data to HASS instance
2023-07-10 17:37:04,081 - web_server - INFO - Successfully posted to sensor.p_pv_forecast = -0.75
2023-07-10 17:37:04,097 - web_server - INFO - Successfully posted to sensor.p_load_forecast = 984.64
2023-07-10 17:37:04,108 - web_server - INFO - Successfully posted to sensor.p_deferrable0 = 0.0
2023-07-10 17:37:04,119 - web_server - INFO - Successfully posted to sensor.p_deferrable1 = 0.0
2023-07-10 17:37:04,132 - web_server - INFO - Successfully posted to sensor.p_deferrable2 = 0.0
2023-07-10 17:37:04,144 - web_server - INFO - Successfully posted to sensor.p_deferrable3 = 0.0
2023-07-10 17:37:04,160 - web_server - INFO - Successfully posted to sensor.p_batt_forecast = -1949.47
2023-07-10 17:37:04,173 - web_server - INFO - Successfully posted to sensor.soc_batt_forecast = 10.0
2023-07-10 17:37:04,186 - web_server - INFO - Successfully posted to sensor.p_grid_forecast = 2934.87
2023-07-10 17:37:04,195 - web_server - INFO - Successfully posted to sensor.total_cost_fun_value = -3.6
2023-07-10 17:37:04,206 - web_server - INFO - Successfully posted to sensor.unit_load_cost = 0.52
2023-07-10 17:37:04,221 - web_server - INFO - Successfully posted to sensor.unit_prod_price = 0.42
2023-07-10 17:38:00,048 - web_server - INFO - Setting up needed data
2023-07-10 17:38:00,050 - web_server - ERROR - ERROR: The passed data is either not a list or the length is not correct, length should be 48
2023-07-10 17:38:00,050 - web_server - ERROR - Passed type is <class 'list'> and length is 48
2023-07-10 17:38:00,052 - web_server - INFO - Retrieve hass get data method initiated...
2023-07-10 17:38:00,708 - web_server - INFO - Retrieving weather forecast data using method = scrapper
2023-07-10 17:38:02,110 - web_server - INFO - Retrieving data from hass for load forecast using method = naive
2023-07-10 17:38:02,110 - web_server - INFO - Retrieve hass get data method initiated...
2023-07-10 17:38:03,674 - web_server - INFO -  >> Performing naive MPC optimization...
2023-07-10 17:38:03,674 - web_server - INFO - Performing naive MPC optimization
2023-07-10 17:38:03,693 - web_server - INFO - Perform an iteration of a naive MPC controller
2023-07-10 17:38:03,807 - web_server - INFO - Status: Infeasible
2023-07-10 17:38:03,807 - web_server - INFO - Total value of the Cost function = -3.6
2023-07-10 17:38:04,119 - web_server - INFO - Setting up needed data
2023-07-10 17:38:04,121 - web_server - INFO -  >> Publishing data...
2023-07-10 17:38:04,122 - web_server - INFO - Publishing data to HASS instance
2023-07-10 17:38:04,141 - web_server - INFO - Successfully posted to sensor.p_pv_forecast = -0.75
2023-07-10 17:38:04,155 - web_server - INFO - Successfully posted to sensor.p_load_forecast = 977.36
2023-07-10 17:38:04,168 - web_server - INFO - Successfully posted to sensor.p_deferrable0 = 0.0
2023-07-10 17:38:04,183 - web_server - INFO - Successfully posted to sensor.p_deferrable1 = 0.0
2023-07-10 17:38:04,194 - web_server - INFO - Successfully posted to sensor.p_deferrable2 = 0.0
2023-07-10 17:38:04,203 - web_server - INFO - Successfully posted to sensor.p_deferrable3 = 0.0
2023-07-10 17:38:04,215 - web_server - INFO - Successfully posted to sensor.p_batt_forecast = -1949.47
2023-07-10 17:38:04,224 - web_server - INFO - Successfully posted to sensor.soc_batt_forecast = 10.0
2023-07-10 17:38:04,235 - web_server - INFO - Successfully posted to sensor.p_grid_forecast = 2927.58
2023-07-10 17:38:04,245 - web_server - INFO - Successfully posted to sensor.total_cost_fun_value = -3.6
2023-07-10 17:38:04,256 - web_server - INFO - Successfully posted to sensor.unit_load_cost = 0.52
2023-07-10 17:38:04,268 - web_server - INFO - Successfully posted to sensor.unit_prod_price = 0.42

EMHASS config:

hass_url: empty
long_lived_token: empty
costfun: profit
logging_level: INFO
optimization_time_step: 30
historic_days_to_retrieve: 2
method_ts_round: first
set_total_pv_sell: false
lp_solver: COIN_CMD
lp_solver_path: /usr/bin/cbc
set_nocharge_from_grid: false
set_nodischarge_to_grid: false
set_battery_dynamic: false
battery_dynamic_max: 1
battery_dynamic_min: -1
load_forecast_method: naive
sensor_power_photovoltaics: sensor.sonnenbatterie_84324_production_w
sensor_power_load_no_var_loads: sensor.house_power_consumption_less_deferrables
number_of_deferrable_loads: 4
list_nominal_power_of_deferrable_loads:
  - nominal_power_of_deferrable_loads: 1500
  - nominal_power_of_deferrable_loads: 1830
  - nominal_power_of_deferrable_loads: 1000
  - nominal_power_of_deferrable_loads: 3300
list_operating_hours_of_each_deferrable_load:
  - operating_hours_of_each_deferrable_load: 2
  - operating_hours_of_each_deferrable_load: 2
  - operating_hours_of_each_deferrable_load: 2
  - operating_hours_of_each_deferrable_load: 2
list_peak_hours_periods_start_hours:
  - peak_hours_periods_start_hours: "02:54"
  - peak_hours_periods_start_hours: "02:00"
  - peak_hours_periods_start_hours: "10:00"
  - peak_hours_periods_start_hours: "03:00"
list_peak_hours_periods_end_hours:
  - peak_hours_periods_end_hours: "15:24"
  - peak_hours_periods_end_hours: "05:00"
  - peak_hours_periods_end_hours: "20:00"
  - peak_hours_periods_end_hours: "20:00"
list_treat_deferrable_load_as_semi_cont:
  - treat_deferrable_load_as_semi_cont: true
  - treat_deferrable_load_as_semi_cont: true
  - treat_deferrable_load_as_semi_cont: true
  - treat_deferrable_load_as_semi_cont: false
load_peak_hours_cost: 0.1907
load_offpeak_hours_cost: 0.1419
photovoltaic_production_sell_price: 0.065
maximum_power_from_grid: 14490
list_pv_module_model:
  - pv_module_model: CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M
list_pv_inverter_model:
  - pv_inverter_model: Fronius_International_GmbH__Fronius_Primo_5_0_1_208_240__240V_
list_surface_tilt:
  - surface_tilt: 21
list_surface_azimuth:
  - surface_azimuth: 350
list_modules_per_string:
  - modules_per_string: 17
list_strings_per_inverter:
  - strings_per_inverter: 1
set_use_battery: true
battery_discharge_power_max: 3300
battery_charge_power_max: 3300
battery_discharge_efficiency: 0.95
battery_charge_efficiency: 0.95
battery_nominal_energy_capacity: 10000
battery_minimum_state_of_charge: 0.1
battery_maximum_state_of_charge: 0.9
battery_target_state_of_charge: 0.1

Don’t know what else might be wrong.

I think I have the wrong sensor in the MPC shell command.

  post_mpc_optim_solcast:
    'curl -i -H "Content-Type: application/json" -X POST -d ''{"load_cost_forecast":{{(
    ([states(''sensor.cecil_st_general_price'')|float(0)] +
    state_attr(''sensor.cecil_st_general_forecast'', ''forecasts'') |map(attribute=''per_kwh'')|list)[:48])
    }}, "prod_price_forecast":{{(
    ([states(''sensor.cecil_st_feed_in_price'')|float(0)] +
    state_attr(''sensor.cecil_st_feed_in_forecast'', ''forecasts'')|map(attribute=''per_kwh'')|list)[:48])
    }}, "pv_power_forecast":{{states(''sensor.solcast_24hrs_forecast'')
    }}, "prediction_horizon":48,"soc_init":{{(states(''sensor.sonnenbatterie_84324_state_charge_user_decimal'')|float(0))/100
    }},"soc_final":1.0,"def_total_hours":[2,2,2,2]}'' http://localhost:5000/action/naive-mpc-optim'
# def_total_hours [Deferrable_0=PoolPump] [Deferrable_1=DW] [Deferrable_2=WM&D] [Deferrable_3=tesla] 

Is sensor.powerwall_charge battery chare percentage between 0 and 100? Then divided by 100 to bring it to between 0 and 1?

sensor.sonnenbatterie_84324_state_charge_user_decimal is already a decimal (actually a string).

I think I need to replace it with sensor.sonnenbatterie_84324_state_charge_user which is the percentage of usable battery charge remaining 0 to 100.

Thanks been wrong the whole time?

So i’ve changed that but still not getting a usefull p_batt_forecast

1 Like

copy the shell command into the developer tools:template to see what the values expand to.

The plan doesn’t look too bad. Your charging of your EV today has registered in the p_load forecast for tomorrow at 9am.

As a consequence it is planning to charge your battery during the cheap window at 4am to meet the EV load at 9am. It looks as if your battery will discharge to the grid at around 7am for 30 minutes.

It then proposes to charge your battery from the grid during midday.

It then tries to charge your battery towards the end of the day as you have soc_final=1.0, so it is trying hard to charge the battery. maybe set soc_final to 0.05 or 0.5.