EMHASS: An Energy Management for Home Assistant

I have deferable loads set to 0
My power_no_var_loads is my consumption sensor.

Ive tried piecing it together but it still has no value close together,

What do the logs say?

Are you using daily or mpc optimisation?

By the looks its mpc naive, Im not sure if this influences. also my logs are the same as displayed data. If your talking about the logs within Emhass add on.

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 '

rest_command:
  naive_mpc_optim:
    url: http://localhost:5000/action/naive-mpc-optim
    method: POST
    content_type: "application/json"
    payload: >-
      {
        "prod_price_forecast": {{
          ([states('sensor.home_feed_in_price')|float(0)] +
          (state_attr('sensor.home_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list))
          | tojson 
        }},
        "load_cost_forecast": {{
          ([states('sensor.home_general_price')|float(0)] + 
          state_attr('sensor.home_general_forecast', 'forecasts') |map(attribute='per_kwh')|list) 
          | tojson 
        }},
        "pv_power_forecast": {{
          ([states('sensor.solar_total')|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
        }},
        "prediction_horizon": {{
          min(48, (state_attr('sensor.home_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)+1)
        }},
        "soc_init": {{(states('sensor.battery_total_2')|int(0))/400}},
        "soc_final":0.2
      }

Try and include the following variables with your MPC call.:

        "alpha": 1,
        "beta": 0,

https://emhass.readthedocs.io/en/latest/forecasts.html#now-current-values-in-forecasts

Could i ask were i would be putting it?

I tried and it broke the sensor and battery data deleted.
Im not sure exaclty were it should be placed

Anywhere in the payload is fine;

Just note there is no , in the last element of the payload.

naive_mpc_optim:
    url: http://localhost:5000/action/naive-mpc-optim
    method: POST
    content_type: "application/json"
    payload: >-
      {
        "prod_price_forecast": {{
          ([states('sensor.amber_feed_in_price')|float(0)] +
          (state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list))
          | tojson 
        }},
        "load_cost_forecast": {{
          ([states('sensor.amber_general_price')|float(0)] + 
          state_attr('sensor.amber_general_forecast', 'forecasts') |map(attribute='per_kwh')|list) 
          | tojson 
        }},
        "load_power_forecast": {{
          ([states('sensor.power_load_no_var_loads')|int] +
          (states('input_text.fi_fo_buffer').split(', ')|map('multiply',1000)|map('int')|list)[1:]
          )| tojson 
        }},

        "prediction_horizon": {{
          min(48, (state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)+1)
        }},
        "alpha": 1,
        "beta": 0,
        "num_def_loads": 6,
        "def_total_hours": {{[states('sensor.def_total_hours_pool_filter')|int(0),
                              states('sensor.def_total_hours_pool_heatpump')|int(0),
                              states('sensor.def_total_hours_ev')|int(0),
                              states('sensor.def_total_hours_hvac')|int(0),
                              states('sensor.def_total_hours_hws')|int(0),
                              states('sensor.def_total_hours_ev2')|int(0)]}},
        "def_end_timestep":[0, 0, 0, 0, 0, 0],
        "P_deferrable_nom":  [300,
                              6333, 
                              {{ states('sensor.p_nom_ev')}}, 
                              {{ states('input_number.p_nom_hvac')}}, 
                              600, 
                              {{ states('sensor.p_nom_ev2')}}],
        "treat_def_as_semi_cont": [1, 1, 0, 0, 1, 0],
        "set_def_constant": [0, 0, 0, 0, 0, 0],
        "def_start_penalty": [1, 1, 1, 1, 1, 1],
        "soc_init": {{ max(0,states('sensor.energy_site_percentage_charged')|int(0))/100 }},
        "soc_final": {{ max(1,states('sensor.gateway_battery')|int(0)/100) }}
      }

I tried this and it doesnt calculate
The battery goes to 0

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 '

rest_command:
  naive_mpc_optim:
    url: http://localhost:5000/action/naive-mpc-optim
    method: POST
    content_type: "application/json"
    payload: >-
      {
        "prod_price_forecast": {{
          ([states('sensor.home_feed_in_price')|float(0)] +
          (state_attr('sensor.home_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list))
          | tojson 
        }},
        "load_cost_forecast": {{
          ([states('sensor.home_general_price')|float(0)] + 
          state_attr('sensor.home_general_forecast', 'forecasts') |map(attribute='per_kwh')|list) 
          | tojson 
        }},
        "pv_power_forecast": {{
          ([states('sensor.solar_total')|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
        }},
        "prediction_horizon": {{
          min(48, (state_attr('sensor.home_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)+1)
        }},
        "soc_init": {{(states('sensor.battery_total_2')|int(0))/400}},
        "soc_final":0.2
        "alpha": 1,
        "beta": 0,
      }

You need to move your commas around.

The last item on the list doesnā€™t have a comma and you need to add one to soc_final:

        soc_final":0.2,
        "alpha": 1,
        "beta": 0
      }

Yep nailed it,

The code worked but its still similar results. I cant see why as im feeding the excact sensor into emhass.

Could you share your EMHASS logs that show the input and output please?

You can see from my logs that my PV and load sensors exactly match my inputs.


2024-09-03 06:31:00,377 - web_server - INFO - Passed runtime parameters: {'load_cost_forecast': [0.16, 0.12, 0.09, 0.07, 0.07, 0.04, 0.04, 0.04, 0.03, 0.02, 0.03, 0.04, 0.04, 0.04, 0.04, 0.04, 0.05, 0.06, 0.08, 0.26, 0.29, 0.34, 0.4, 0.44, 0.43, 0.41, 0.39, 0.38, 0.36, 0.23, 0.22, 0.21, 0.21, 0.21, 0.2, 0.2, 0.2, 0.19, 0.19, 0.19, 0.19, 0.19, 0.19], 'prod_price_forecast': [0.04, 0, -0.02, -0.04, -0.04, -0.04, -0.04, -0.05, -0.05, -0.06, -0.05, -0.05, -0.05, -0.05, -0.05, -0.04, -0.04, -0.03, -0.01, 0.01, 0.04, 0.09, 0.15, 0.18, 0.17, 0.15, 0.13, 0.13, 0.11, 0.1, 0.09, 0.09, 0.09, 0.08, 0.08, 0.08, 0.08, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07], 'load_power_forecast': [400, 300, 300, 400, 400, 600, 500, 300, 300, 300, 300, 300, 300, 300, 300, 300, 400, 300, 300, 300, 300, 400, 400, 400, 400, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 500, 300, 400, 300, 300, 400, 400, 600, 500, 300, 300, 300, 300, 300, 300, 300, 300, 300, 400, 300, 300, 300, 300, 400, 400, 400, 400, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 500, 300], 'pv_power_forecast': [372, 2114, 3797, 5456, 7053, 8526, 9773, 10796, 11623, 12178, 12497, 12569, 12404, 12013, 11357, 10505, 9376, 8002, 6411, 4655, 2746, 839, 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, 115, 647, 1996, 3250, 4499, 5687, 6758, 7623, 8316, 8818, 9123, 9242, 9269, 9177, 8890, 8474, 7552, 6164, 4951, 3734, 2273, 723, 145, 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, 165, 893, 2145, 3510, 4828, 6009, 7022, 7919, 8724, 9360, 9794, 10071, 10184, 10033, 9753, 9439, 8841, 7875, 6564, 5106, 3565, 1766, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'prediction_horizon': 43, 'alpha': 1, 'beta': 0, 'num_def_loads': 6, 'def_total_hours': [8, 0, 0, 4, 0, 0], 'def_end_timestep': [0, 0, 0, 0, 0, 0], 'P_deferrable_nom': [300, 6333, 11520, 9000, 600, 11520], 'def_current_state': [0, 0, 0, 0, 0, 0], 'def_start_penalty': [1, 1, 1, 1, 1, 1], 'treat_def_as_semi_cont': [1, 1, 0, 0, 1, 0], 'set_def_constant': [0, 0, 0, 0, 0, 0], 'soc_init': 0.0, 'soc_final': 1}
2024-09-03 06:31:00,378 - web_server - INFO -  >> Setting input data dict
2024-09-03 06:31:00,378 - web_server - INFO - Setting up needed data
2024-09-03 06:31:00,384 - web_server - INFO - Retrieve hass get data method initiated...
2024-09-03 06:31:00,914 - web_server - INFO - Retrieving weather forecast data using method = list
2024-09-03 06:31:00,923 - web_server - INFO -  >> Performing naive MPC optimization...
2024-09-03 06:31:00,923 - web_server - INFO - Performing naive MPC optimization
2024-09-03 06:31:00,956 - web_server - INFO - Perform an iteration of a naive MPC controller
2024-09-03 06:31:01,172 - web_server - DEBUG - Deferrable load 0: Proposed optimization window: 0 --> 0
2024-09-03 06:31:01,172 - web_server - DEBUG - Deferrable load 0: Validated optimization window: 0 --> 0
2024-09-03 06:31:01,181 - web_server - DEBUG - Deferrable load 1: Proposed optimization window: 0 --> 0
2024-09-03 06:31:01,181 - web_server - DEBUG - Deferrable load 1: Validated optimization window: 0 --> 0
2024-09-03 06:31:01,190 - web_server - DEBUG - Deferrable load 2: Proposed optimization window: 0 --> 0
2024-09-03 06:31:01,190 - web_server - DEBUG - Deferrable load 2: Validated optimization window: 0 --> 0
2024-09-03 06:31:01,196 - web_server - DEBUG - Deferrable load 3: Proposed optimization window: 0 --> 0
2024-09-03 06:31:01,196 - web_server - DEBUG - Deferrable load 3: Validated optimization window: 0 --> 0
2024-09-03 06:31:01,201 - web_server - DEBUG - Deferrable load 4: Proposed optimization window: 0 --> 0
2024-09-03 06:31:01,202 - web_server - DEBUG - Deferrable load 4: Validated optimization window: 0 --> 0
2024-09-03 06:31:01,213 - web_server - DEBUG - Deferrable load 5: Proposed optimization window: 0 --> 0
2024-09-03 06:31:01,213 - web_server - DEBUG - Deferrable load 5: Validated optimization window: 0 --> 0
2024-09-03 06:31:02,171 - web_server - INFO - Status: Optimal
2024-09-03 06:31:02,172 - web_server - INFO - Total value of the Cost function = -0.67
2024-09-03 06:31:03,218 - web_server - INFO - Passed runtime parameters: {'custom_unit_load_cost_id': {'entity_id': 'sensor.unit_load_cost', 'unit_of_measurement': '$/kWh', 'friendly_name': 'Load Cost'}, 'custom_unit_prod_price_id': {'entity_id': 'sensor.unit_prod_price', 'unit_of_measurement': '$/kWh', 'friendly_name': 'Prod Price'}}
2024-09-03 06:31:03,218 - web_server - INFO -  >> Setting input data dict
2024-09-03 06:31:03,218 - web_server - INFO - Setting up needed data
2024-09-03 06:31:03,223 - web_server - INFO -  >> Publishing data...
2024-09-03 06:31:03,223 - web_server - INFO - Publishing data to HASS instance
2024-09-03 06:31:03,256 - web_server - INFO - Successfully posted to sensor.p_pv_forecast = 372
2024-09-03 06:31:03,278 - web_server - INFO - Successfully posted to sensor.p_load_forecast = 400
2024-09-03 06:31:03,299 - web_server - INFO - Successfully posted to sensor.p_pv_curtailment = 0.0
2024-09-03 06:31:03,320 - web_server - INFO - Successfully posted to sensor.p_deferrable0 = 0.0
2024-09-03 06:31:03,340 - web_server - INFO - Successfully posted to sensor.p_deferrable1 = 0.0
2024-09-03 06:31:03,361 - web_server - INFO - Successfully posted to sensor.p_deferrable2 = 0.0
2024-09-03 06:31:03,382 - web_server - INFO - Successfully posted to sensor.p_deferrable3 = 0.0
2024-09-03 06:31:03,402 - web_server - INFO - Successfully posted to sensor.p_deferrable4 = 0.0
2024-09-03 06:31:03,423 - web_server - INFO - Successfully posted to sensor.p_deferrable5 = 0.0
2024-09-03 06:31:03,443 - web_server - INFO - Successfully posted to sensor.p_batt_forecast = 0.0
2024-09-03 06:31:03,467 - web_server - INFO - Successfully posted to sensor.soc_batt_forecast = 0.0
2024-09-03 06:31:03,488 - web_server - INFO - Successfully posted to sensor.p_grid_forecast = 28.0
2024-09-03 06:31:03,505 - web_server - INFO - Successfully posted to sensor.total_cost_fun_value = -0.57
2024-09-03 06:31:03,520 - web_server - INFO - Successfully posted to sensor.optim_status = Optimal
2024-09-03 06:31:03,541 - web_server - INFO - Successfully posted to sensor.unit_load_cost = 0.16
2024-09-03 06:31:03,562 - web_server - INFO - Successfully posted to sensor.unit_prod_price = 0.04

2024-09-03 16:32:46,663 - web_server - INFO - >> Publishing dataā€¦
2024-09-03 16:32:46,663 - web_server - INFO - Publishing data to HASS instance
2024-09-03 16:32:46,677 - web_server - INFO - Successfully posted to sensor.p_pv_forecast = 2624.68
2024-09-03 16:32:46,690 - web_server - INFO - Successfully posted to sensor.p_load_forecast = 961.7
2024-09-03 16:32:46,701 - web_server - INFO - Successfully posted to sensor.p_pv_curtailment = 0.0
2024-09-03 16:32:46,711 - web_server - INFO - Successfully posted to sensor.p_deferrable0 = 0.0
2024-09-03 16:32:46,720 - web_server - INFO - Successfully posted to sensor.p_batt_forecast = -460.0
2024-09-03 16:32:46,729 - web_server - INFO - Successfully posted to sensor.soc_batt_forecast = 100.0
2024-09-03 16:32:46,740 - web_server - INFO - Successfully posted to sensor.p_grid_forecast = -1202.97
2024-09-03 16:32:46,748 - web_server - INFO - Successfully posted to sensor.total_cost_fun_value = 7.98
2024-09-03 16:32:46,755 - web_server - INFO - Successfully posted to sensor.optim_status = Optimal
2024-09-03 16:32:46,764 - web_server - INFO - Successfully posted to sensor.unit_load_cost = 0.13
2024-09-03 16:32:46,773 - web_server - INFO - Successfully posted to sensor.unit_prod_price = 0.08
2024-09-03 16:32:50,425 - web_server - INFO - Passed runtime parameters: {ā€˜prod_price_forecastā€™: [0.08, 0.09, 0.34, 0.34, 0.34, 0.33, 0.33, 0.21, 0.32, 0.14, 0.11, 0.09, 0.08, 0.08, 0.08, 0.08, 0.07, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.08, 0.09, 0.09, 0.08, 0.07, 0.07, 0.04, 0.02, -0.01, -0.06, -0.06, -0.07, -0.07, -0.08, -0.08, -0.08, -0.08, -0.07, -0.06, -0.05, -0.06, -0.03, -0.02], ā€˜load_cost_forecastā€™: [0.13, 0.15, 0.42, 0.42, 0.42, 0.41, 0.41, 0.28, 0.39, 0.23, 0.19, 0.17, 0.16, 0.16, 0.16, 0.16, 0.15, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.16, 0.17, 0.17, 0.16, 0.15, 0.15, 0.11, 0.09, 0.06, 0.02, 0.02, 0.01, 0.01, -0.0, -0.0, -0.0, -0.0, 0.01, 0.02, 0.02, 0.01, 0.02, 0.02], ā€˜pv_power_forecastā€™: [2952, 1234, 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, 64, 661, 1724, 2779, 3966, 5806, 7524, 8939, 10218, 11224, 11969, 12478, 12751, 12757, 12401, 11880, 11055, 9956, 8365, 6629, 4916, 2846, 900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ā€˜prediction_horizonā€™: 48, ā€˜soc_initā€™: 0.995, ā€˜soc_finalā€™: 0.2}
2024-09-03 16:32:50,426 - web_server - INFO - >> Setting input data dict
2024-09-03 16:32:50,426 - web_server - INFO - Setting up needed data
2024-09-03 16:32:50,429 - web_server - INFO - Retrieve hass get data method initiatedā€¦
2024-09-03 16:32:52,025 - web_server - INFO - Retrieving weather forecast data using method = list
2024-09-03 16:32:52,026 - web_server - INFO - Retrieving data from hass for load forecast using method = naive
2024-09-03 16:32:52,027 - web_server - INFO - Retrieve hass get data method initiated.

I canā€™t see you setting alpha and beta in this call.

Do you restart home assistant after you made this changes?

2024-09-04 18:01:27,619 - web_server - INFO - Successfully posted to sensor.p_load_forecast = 1006.93
2024-09-04 18:01:27,630 - web_server - INFO - Successfully posted to sensor.p_pv_curtailment = 0.0
2024-09-04 18:01:27,641 - web_server - INFO - Successfully posted to sensor.p_deferrable0 = 0.0
2024-09-04 18:01:27,652 - web_server - INFO - Successfully posted to sensor.p_batt_forecast = 10006.93
2024-09-04 18:01:27,666 - web_server - INFO - Successfully posted to sensor.soc_batt_forecast = 68.62
2024-09-04 18:01:27,683 - web_server - INFO - Successfully posted to sensor.p_grid_forecast = -9000.0
2024-09-04 18:01:27,697 - web_server - INFO - Successfully posted to sensor.total_cost_fun_value = 3.63
2024-09-04 18:01:27,710 - web_server - INFO - Successfully posted to sensor.optim_status = Optimal
2024-09-04 18:01:27,722 - web_server - INFO - Successfully posted to sensor.unit_load_cost = 0.23
2024-09-04 18:01:27,735 - web_server - INFO - Successfully posted to sensor.unit_prod_price = 0.16
2024-09-04 18:01:30,229 - web_server - INFO - Passed runtime parameters: {ā€˜prod_price_forecastā€™: [0.16, 0.16, 0.14, 0.12, 0.12, 0.1, 0.07, 0.07, 0.08, 0.08, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.05, 0.05, 0.06, 0.06, 0.06, 0.06, 0.06, 0.07, 0.07, 0.01, 0.03, 0.04, 0.01, -0.0, -0.03, -0.06, -0.06, -0.07, -0.07, -0.07, -0.07, -0.07, -0.06, -0.06, -0.05, -0.03, 0.0, 0.02, 0.02, 0.07, 0.1, 0.12], ā€˜load_cost_forecastā€™: [0.23, 0.22, 0.2, 0.18, 0.17, 0.16, 0.15, 0.15, 0.16, 0.16, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.14, 0.14, 0.14, 0.14, 0.14, 0.15, 0.15, 0.08, 0.11, 0.11, 0.08, 0.07, 0.04, 0.02, 0.02, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.02, 0.03, 0.04, 0.07, 0.07, 0.07, 0.12, 0.16, 0.17], ā€˜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, 80, 707, 1772, 2805, 4082, 5783, 7396, 8919, 10152, 11064, 11745, 12184, 12481, 12404, 12180, 11646, 10887, 9866, 8427, 6747, 5381, 3474, 1463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ā€˜prediction_horizonā€™: 48, ā€˜soc_initā€™: 0.795, ā€˜soc_finalā€™: 0.2, ā€˜alphaā€™: 1, ā€˜betaā€™: 0}
2024-09-04 18:01:30,229 - web_server - INFO - >> Setting input data dict
2024-09-04 18:01:30,230 - web_server - INFO - Setting up needed data
2024-09-04 18:01:30,232 - web_server - INFO - Retrieve hass get data method initiatedā€¦
2024-09-04 18:01:31,804 - web_server - INFO - Retrieving weather forecast data using method = list
2024-09-04 18:01:31,805 - web_server - INFO - Retrieving data from hass for load forecast using method = naive
2024-09-04 18:01:31,806 - web_server - INFO - Retrieve hass get data method initiatedā€¦
2024-09-04 18:01:35,433 - web_server - INFO - >> Performing naive MPC optimizationā€¦
2024-09-04 18:01:35,433 - web_server - INFO - Performing naive MPC optimization
2024-09-04 18:01:35,453 - web_server - INFO - Perform an iteration of a naive MPC controller
2024-09-04 18:01:35,667 - web_server - INFO - Status: Optimal
2024-09-04 18:01:35,667 - web_server - INFO - Total value of the Cost function = -23.74
2024-09-04 18:01:36,536 - web_server - INFO - Passed runtime parameters: {}
2024-09-04 18:01:36,536 - web_server - INFO - >> Setting input data dict
2024-09-04 18:01:36,536 - web_server - INFO - Setting up needed data
2024-09-04 18:01:36,538 - web_server - INFO - >> Publishing dataā€¦
2024-09-04 18:01:36,539 - web_server - INFO - Publishing data to HASS instance
2024-09-04 18:01:36,552 - web_server - INFO - Successfully posted to sensor.p_pv_forecast = 0
2024-09-04 18:01:36,562 - web_server - INFO - Successfully posted to sensor.p_load_forecast = 1006.93
2024-09-04 18:01:36,572 - web_server - INFO - Successfully posted to sensor.p_pv_curtailment = 0.0
2024-09-04 18:01:36,581 - web_server - INFO - Successfully posted to sensor.p_deferrable0 = 0.0
2024-09-04 18:01:36,590 - web_server - INFO - Successfully posted to sensor.p_batt_forecast = 10006.93
2024-09-04 18:01:36,599 - web_server - INFO - Successfully posted to sensor.soc_batt_forecast = 68.62
2024-09-04 18:01:36,610 - web_server - INFO - Successfully posted to sensor.p_grid_forecast = -9000.0
2024-09-04 18:01:36,618 - web_server - INFO - Successfully posted to sensor.total_cost_fun_value = 3.63
2024-09-04 18:01:36,624 - web_server - INFO - Successfully posted to sensor.optim_status = Optimal
2024-09-04 18:01:36,633 - web_server - INFO - Successfully posted to sensor.unit_load_cost = 0.23
2024-09-04 18:01:36,642 - web_server - INFO - Successfully posted to sensor.unit_prod_price = 0.16
2024-09-04 18:01:40,225 - web_server - INFO - Passed runtime parameters: {ā€˜prod_price_forecastā€™: [0.16, 0.16, 0.14, 0.12, 0.12, 0.1, 0.07, 0.07, 0.08, 0.08, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.05, 0.05, 0.06, 0.06, 0.06, 0.06, 0.06, 0.07, 0.07, 0.01, 0.03, 0.04, 0.01, -0.0, -0.03, -0.06, -0.06, -0.07, -0.07, -0.07, -0.07, -0.07, -0.06, -0.06, -0.05, -0.03, 0.0, 0.02, 0.02, 0.07, 0.1, 0.12], ā€˜load_cost_forecastā€™: [0.23, 0.22, 0.2, 0.18, 0.17, 0.16, 0.15, 0.15, 0.16, 0.16, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.14, 0.14, 0.14, 0.14, 0.14, 0.15, 0.15, 0.08, 0.11, 0.11, 0.08, 0.07, 0.04, 0.02, 0.02, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.02, 0.03, 0.04, 0.07, 0.07, 0.07, 0.12, 0.16, 0.17], ā€˜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, 80, 707, 1772, 2805, 4082, 5783, 7396, 8919, 10152, 11064, 11745, 12184, 12481, 12404, 12180, 11646, 10887, 9866, 8427, 6747, 5381, 3474, 1463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ā€˜prediction_horizonā€™: 48, ā€˜soc_initā€™: 0.795, ā€˜soc_finalā€™: 0.2, ā€˜alphaā€™: 1, ā€˜betaā€™: 0}
2024-09-04 18:01:40,225 - web_server - INFO - >> Setting input data dict
2024-09-04 18:01:40,225 - web_server - INFO - Setting up needed data
2024-09-04 18:01:40,228 - web_server - INFO - Retrieve hass get data method initiatedā€¦
2024-09-04 18:01:42,102 - web_server - INFO - Retrieving weather forecast data using method = list
2024-09-04 18:01:42,103 - web_server - INFO - Retrieving data from hass for load forecast using method = naive
2024-09-04 18:01:42,104 - web_server - INFO - Retrieve hass get data method initiatedā€¦
2024-09-04 18:01:45,623 - web_server - INFO - >> Performing naive MPC optimizationā€¦
2024-09-04 18:01:45,623 - web_server - INFO - Performing naive MPC optimization
2024-09-04 18:01:45,637 - web_server - INFO - Perform an iteration of a naive MPC controller
2024-09-04 18:01:45,851 - web_server - INFO - Status: Optimal
2024-09-04 18:01:45,851 - web_server - INFO - Total value of the Cost function = -23.74
2024-09-04 18:01:46,737 - web_server - INFO - Passed runtime parameters: {}
2024-09-04 18:01:46,737 - web_server - INFO - >> Setting input data dict
2024-09-04 18:01:46,737 - web_server - INFO - Setting up needed data
2024-09-04 18:01:46,739 - web_server - INFO - >> Publishing dataā€¦
2024-09-04 18:01:46,739 - web_server - INFO - Publishing data to HASS instance
2024-09-04 18:01:46,753 - web_server - INFO - Successfully posted to sensor.p_pv_forecast = 0
2024-09-04 18:01:46,763 - web_server - INFO - Successfully posted to sensor.p_load_forecast = 1006.93
2024-09-04 18:01:46,772 - web_server - INFO - Successfully posted to sensor.p_pv_curtailment = 0.0
2024-09-04 18:01:46,781 - web_server - INFO - Successfully posted to sensor.p_deferrable0 = 0.0
2024-09-04 18:01:46,789 - web_server - INFO - Successfully posted to sensor.p_batt_forecast = 10006.93
2024-09-04 18:01:46,798 - web_server - INFO - Successfully posted to sensor.soc_batt_forecast = 68.62
2024-09-04 18:01:46,808 - web_server - INFO - Successfully posted to sensor.p_grid_forecast = -9000.0
2024-09-04 18:01:46,833 - web_server - INFO - Successfully posted to sensor.total_cost_fun_value = 3.63
2024-09-04 18:01:46,842 - web_server - INFO - Successfully posted to sensor.optim_status = Optimal
2024-09-04 18:01:46,852 - web_server - INFO - Successfully posted to sensor.unit_load_cost = 0.23
2024-09-04 18:01:46,862 - web_server - INFO - Successfully posted to sensor.unit_prod_price = 0.16
2024-09-04 18:01:50,230 - web_server - INFO - Passed runtime parameters: {ā€˜prod_price_forecastā€™: [0.16, 0.16, 0.14, 0.12, 0.12, 0.1, 0.07, 0.07, 0.08, 0.08, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.05, 0.05, 0.06, 0.06, 0.06, 0.06, 0.06, 0.07, 0.07, 0.01, 0.03, 0.04, 0.01, -0.0, -0.03, -0.06, -0.06, -0.07, -0.07, -0.07, -0.07, -0.07, -0.06, -0.06, -0.05, -0.03, 0.0, 0.02, 0.02, 0.07, 0.1, 0.12], ā€˜load_cost_forecastā€™: [0.22, 0.23, 0.2, 0.18, 0.17, 0.16, 0.15, 0.15, 0.16, 0.16, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.14, 0.14, 0.14, 0.14, 0.14, 0.15, 0.15, 0.08, 0.11, 0.11, 0.08, 0.07, 0.04, 0.02, 0.02, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.02, 0.03, 0.04, 0.07, 0.07, 0.07, 0.12, 0.16, 0.17], ā€˜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, 80, 707, 1772, 2805, 4082, 5783, 7396, 8919, 10152, 11064, 11745, 12184, 12481, 12404, 12180, 11646, 10887, 9866, 8427, 6747, 5381, 3474, 1463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ā€˜prediction_horizonā€™: 48, ā€˜soc_initā€™: 0.795, ā€˜soc_finalā€™: 0.2, ā€˜alphaā€™: 1, ā€˜betaā€™: 0}
2024-09-04 18:01:50,231 - web_server - INFO - >> Setting input data dict
2024-09-04 18:01:50,231 - web_server - INFO - Setting up needed data
2024-09-04 18:01:50,234 - web_server - INFO - Retrieve hass get data method initiatedā€¦
2024-09-04 18:01:51,831 - web_server - INFO - Retrieving weather forecast data using method = list
2024-09-04 18:01:51,833 - web_server - INFO - Retrieving data from hass for load forecast using method = naive
2024-09-04 18:01:51,839 - web_server - INFO - Retrieve hass get data method initiatedā€¦
2024-09-04 18:01:55,290 - web_server - INFO - >> Performing naive MPC optimizationā€¦
2024-09-04 18:01:55,290 - web_server - INFO - Performing naive MPC optimization
2024-09-04 18:01:55,304 - web_server - INFO - Perform an iteration of a naive MPC controller
2024-09-04 18:01:55,518 - web_server - INFO - Status: Optimal
2024-09-04 18:01:55,519 - web_server - INFO - Total value of the Cost function = -23.74
2024-09-04 18:01:56,400 - web_server - INFO - Passed runtime parameters: {}
2024-09-04 18:01:56,400 - web_server - INFO - >> Setting input data dict
2024-09-04 18:01:56,400 - web_server - INFO - Setting up needed data
2024-09-04 18:01:56,402 - web_server - INFO - >> Publishing dataā€¦
2024-09-04 18:01:56,402 - web_server - INFO - Publishing data to HASS instance
2024-09-04 18:01:56,415 - web_server - INFO - Successfully posted to sensor.p_pv_forecast = 0
2024-09-04 18:01:56,426 - web_server - INFO - Successfully posted to sensor.p_load_forecast = 1006.93
2024-09-04 18:01:56,436 - web_server - INFO - Successfully posted to sensor.p_pv_curtailment = 0.0
2024-09-04 18:01:56,445 - web_server - INFO - Successfully posted to sensor.p_deferrable0 = 0.0
2024-09-04 18:01:56,454 - web_server - INFO - Successfully posted to sensor.p_batt_forecast = 10006.93
2024-09-04 18:01:56,463 - web_server - INFO - Successfully posted to sensor.soc_batt_forecast = 68.62
2024-09-04 18:01:56,474 - web_server - INFO - Successfully posted to sensor.p_grid_forecast = -9000.0
2024-09-04 18:01:56,483 - web_server - INFO - Successfully posted to sensor.total_cost_fun_value = 3.63
2024-09-04 18:01:56,490 - web_server - INFO - Successfully posted to sensor.optim_status = Optimal
2024-09-04 18:01:56,500 - web_server - INFO - Successfully posted to sensor.unit_load_cost = 0.22
2024-09-04 18:01:56,510 - web_server - INFO - Successfully posted to sensor.unit_prod_price = 0.16
2024-09-04 18:02:00,271 - web_server - INFO - Passed runtime parameters: {ā€˜prod_price_forecastā€™: [0.16, 0.16, 0.14, 0.12, 0.12, 0.1, 0.07, 0.07, 0.08, 0.08, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.05, 0.05, 0.06, 0.06, 0.06, 0.06, 0.06, 0.07, 0.07, 0.01, 0.03, 0.04, 0.01, -0.0, -0.03, -0.06, -0.06, -0.07, -0.07, -0.07, -0.07, -0.07, -0.06, -0.06, -0.05, -0.03, 0.0, 0.02, 0.02, 0.07, 0.1, 0.12], ā€˜load_cost_forecastā€™: [0.22, 0.23, 0.2, 0.18, 0.17, 0.16, 0.15, 0.15, 0.16, 0.16, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.13, 0.13, 0.14, 0.14, 0.14, 0.14, 0.14, 0.15, 0.15, 0.08, 0.11, 0.11, 0.08, 0.07, 0.04, 0.02, 0.02, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.02, 0.03, 0.04, 0.07, 0.07, 0.07, 0.12, 0.16, 0.17], ā€˜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, 80, 707, 1772, 2805, 4082, 5783, 7396, 8919, 10152, 11064, 11745, 12184, 12481, 12404, 12180, 11646, 10887, 9866, 8427, 6747, 5381, 3474, 1463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ā€˜prediction_horizonā€™: 48, ā€˜soc_initā€™: 0.795, ā€˜soc_finalā€™: 0.2, ā€˜alphaā€™: 1, ā€˜betaā€™: 0}
2024-09-04 18:02:00,271 - web_server - INFO - >> Setting input data dict
2024-09-04 18:02:00,271 - web_server - INFO - Setting up needed data
2024-09-04 18:02:00,275 - web_server - INFO - Retrieve hass get data method initiatedā€¦
2024-09-04 18:02:02,287 - web_server - INFO - Retrieving weather forecast data using method = list
2024-09-04 18:02:02,288 - web_server - INFO - Retrieving data from hass for load forecast using method = naive
2024-09-04 18:02:02,288 - web_server - INFO - Retrieve hass get data method initiatedā€¦

Yer i must have copied the wrong bit its still no go for matching consumption to forcast today. But tomorrow it will assume i did the same as today and will be accurate.

My p_load_forecast isnā€™t that good. So my self_consumption is lower as expected with sunny days as I have a 15 kWh battery. I now use the machine learning forecaster with a history of 117 days and the var_model = sensor.power_load_no_var_loads, is there anyway to get a better fit? When I tune the model the number of optimal lags is 70 and I use 96 lags, so I get an error. My pv_forecast is updated every 15 min, hence the 96 lags.

I could step down to 30 min. and use @markpurcell method fi_fo_buffer for the power_load_no_var_loads, but I prefer the 15 min update as I pay for this service. Or maybe it doesnā€™t matter that much? Anyone any suggestions? For the rest the EMHASS works nicely.

Sorry, I have misread your first post. I thought you were including load_power_forecast in your payload.

The only way I have been able to get sensor.load_power_forecast to match the now value is by including the relevant now value on the load_power_forecast payload. EMHASS has access to the sensor.power_load_no_var_load, but doesnā€™t seem to utilise it directly with alpha=1.

Creating the load_power_forecast payload is not simple. I use the now/current value for the first element of the array and then grab historic values from a FIFO buffer I update each 30 minutes.

I suspect this may be a bug in EMHASS as with alpha=1 it should set sensor.load_power_forecast to the current value of power_load_no_var_load, without modification.

Does anyone have a template for a charger for an electric car that takes into account a specified end time and how many timeslots exist in emhass that show the number of endsteps?
Iā€™m trying to think of how to format it but canā€™t.
I have all other data (see image)

Hi Johan,
I think my charging method might be a good place for you to start, of course needs adjustment to your vairable names, kwhā€™s, charging capacity etc.


#percentage of charge we can add to a max of 90%, based on the volvo integration
- platform: template
  sensors:
    xc40_additional_charge_percentage:
      unit_of_measurement: "%"
      device_class: power_factor
      value_template: >
        {% set current_charge = states('sensor.volvo_yv1x778_battery_charge_level') | int(0) %}
        {% if current_charge >= 90 %}
          {{ 0 }}
        {% else %}
          {{ (90 - current_charge) }}
        {% endif %}





#multiplied by battery capacity 67 khw
- platform: template
  sensors:
    xc40_additional_charge_kwh:
      unit_of_measurement: "kWh"
      device_class: energy
      value_template: >
        {{ 67 * (states('sensor.xc40_additional_charge_percentage') | int) / 100 }}

#charging with a max of 6kwh

- platform: template
  sensors:
    xc40_additional_charge_hours:
      unit_of_measurement: "h"
      device_class: duration
      value_template: >
        {{ ((states('sensor.xc40_additional_charge_kwh') | float) / 6.0) | round(0, "ceil", 0) }}

#check the easee charger if the car is connected, otherwise the number of hours is 0
- platform: template
  sensors:
    xc40_additional_charge_hours_if_conncted:
      unit_of_measurement: "h"
      device_class: duration
      value_template: >
        {{ (states('sensor.xc40_additional_charge_hours') |int if (states('sensor.ec68ea5q_status') in ("awaiting_start", "ready_to_charge", "charging" )) else 0) }}


- platform: template
  sensors:
    xc40_additional_charge_watts:
      unit_of_measurement: "w"
      device_class: power
      value_template: >
        {{ min(6700, ((states('sensor.xc40_additional_charge_kwh') | float) / 6.0) * 6700) | round(0, "ceil", 0) }}

# needs to be ready at 8am, how many hours till then
- platform: template
  sensors:
    hours_until_next_8am:
      friendly_name: "Hours Until Next 8 AM"
      unit_of_measurement: "h"
      device_class: duration
  
      value_template: >-
        {% if now().hour >= 8 %}
          {{ (24 - now().hour + 7) + (0 if now().minute > 30 else 1) }}
        {% else %}
          {{ (8 - now().hour) + (0 if now().minute > 30 else 1) }}
        {% endif %}
1 Like

Thanks, Iā€™ll try. The biggest challenge is that my timeslots change every day from 24-11 as I donā€™t get tomorrowā€™s prices until 13:30. But of course it works if I charge at night. However, sometimes you want to charge directly.

I do something similar. But perform the calculations as part of the rest command.

Summary of User Inputs and Behavior:

  • User Inputs:

    • input_number.mg_emhass_charge_to_soc: Desired state of charge (SOC) for the EV.
    • sensor.mg_soc: Current SOC of the EV.
    • sensor.mg_soc_kwh: Current battery capacity in kWh.
    • input_number.mg_emhass_charge_by_time: Desired end time for charging.
    • binary_sensor.mg_connected_to_charger: Indicates whether the EV is connected to the charger.
  • Behavior:

    • The template calculates the required charging duration (charge_hours) based on the difference between the current and desired SOC, the EVā€™s battery capacity, and the chargerā€™s rate and efficiency.
    • It adjusts the charging schedule to align with EMHASS scheduling intervals (30-minute steps).
    • If the EV is not currently connected to the charger, the start time is shifted by a default assumption of 2 hours.
    • The template then computes the start and end timesteps for charging within the available time frame, ensuring that charging can be completed within the user-specified window. It also adjusts charging parameters to optimize for the available time.

Detailed Explanation:

  1. Desired SOC and Current SOC:

    • The desired SOC is fetched from input_number.mg_emhass_charge_to_soc and converted to a fraction (e.g., 80% becomes 0.8).
    • The current SOC is similarly fetched from sensor.mg_soc and converted to a fraction.
  2. Calculating Required Energy:

    • The total capacity of the battery in kWh is calculated using the current SOC and the corresponding energy in kWh (sensor.mg_soc_kwh).
    • The required kWh to reach the desired SOC is calculated by multiplying the difference between the desired and current SOC by the total battery capacity.
  3. Charging Duration Calculation:

    • The charging rate is set to 7400W (7.4 kW), typical for a home EV charger.
    • The efficiency of the charger is assumed to be 90% (0.9).
    • The charging duration (charge_hours) is computed by dividing the required kWh by the effective charging power and rounding up to the nearest integer. If no charging is required, it defaults to 0.
  4. Determining Charging Schedule:

    • The template then determines the end hour by which charging must be completed, based on input_number.mg_emhass_charge_by_time.
    • The current time is fetched, and the remaining time until the desired end hour is calculated in minutes, converted to EMHASS scheduling timesteps (each timestep representing 30 minutes).
    • If the current hour is past the desired end hour, the calculation accounts for the time wrap-around (from current time to midnight and then to the desired end hour).
  5. Handling EV Connection Status:

    • If the EV is not connected to the charger, the template assumes a default 2-hour delay before charging can start.
    • If connected, charging can start immediately (start_time_shift = 0).
  6. Final Adjustments to Charging Parameters:

    • The template checks if the available time (from start to end timestep) is sufficient to meet the required charging duration.
    • If not, it adjusts the charge_hours to fit within the available time, ensuring maximum charging can occur within the userā€™s constraints.
  7. Output:

    • The calculated values are then outputted as:
      • def_total_hours: Total hours needed for charging.
      • P_deferrable_nom: Nominal charging power.
      • treat_def_as_semi_cont and set_def_constant: Flags related to EMHASS settings.
      • def_start_timestep: Start timestep for charging.
      • def_end_timestep: End timestep for charging.

This Jinja template is carefully designed to calculate and optimize the EV charging schedule within the constraints defined by the user, such as the desired SOC and the preferred end time, while considering the EVā€™s current SOC and charging rate.

ChatGPT can make mistakes - but it did okay explaining the template!

 "num_def_loads": 1,
            {% set desired_soc = states('input_number.mg_emhass_charge_to_soc') | float / 100 %}
            {% set current_soc = states('sensor.mg_soc') | float / 100 %}
            {% set total_capacity_kwh = states('sensor.mg_soc_kwh') | float / current_soc %}
            {% set required_kwh = (desired_soc - current_soc) * total_capacity_kwh %}
            {% set charger_rate_w = 7400 %}
            {% set charger_efficiency = 0.9 %}       
            {# must be >= 0 and int (round up) #}  
            {% set charge_hours = [0, ((required_kwh * 1000 / (charger_rate_w * charger_efficiency)) + 0.5) | round(0) | int ] | max %}   

            {# Convert the charging end hour from mg_emhass_charge_by_time to a timestep aligned with EMHASS scheduling. #}
            {% set end_hour = states('input_number.mg_emhass_charge_by_time') | int %}
            {% set current_time = now() %}
            {% set current_hour = current_time.hour %}
            {% set current_minute = current_time.minute %}
            {% if current_hour <= end_hour %}
              {% set remaining_hours = end_hour - current_hour - 1 %}
              {% set remaining_minutes = 60 - current_minute %}
              {% set total_minutes = remaining_hours * 60 + remaining_minutes %}
              {% set def_end_timestep = (total_minutes / 30) | round(0) %}
            {% else %}
              {% set def_end_timestep = (24 - current_hour + (current_minute/60) + end_hour - 1) * 2 %}
            {% endif %}
            {% set def_end_timestep = [def_end_timestep, min_length] | min | int %}
            
            {% if is_state('binary_sensor.mg_connected_to_charger', 'off') %}
              {# assume MG will be back and plugged in, in two hours (4 30min slots#}
              {% set start_time_shift = 4 %}
            {% else %}
              {% set start_time_shift = 0 %}
            {% endif %}      

            {% if (def_end_timestep - start_time_shift) < charge_hours * 2 %}
              {# can't solve if there isn't enough hours between start and end so reduce charge_hours to maximise charge #}  
              {% set charge_hours = (def_end_timestep - start_time_shift) / 2 %}
            {% endif %}      

            "def_total_hours":  {{[  charge_hours  ]}},  
            "P_deferrable_nom":  {{ [charger_rate_w] }},
            "treat_def_as_semi_cont": [0],
            "set_def_constant": [0],
            "def_start_timestep": [{{start_time_shift}}],
            "def_end_timestep": [{{ def_end_timestep }}],

1 Like

How is it we create a Fifo buffer? Im completely lost with this, i cant even find it in the emhass user manual

1 Like