I came across the post
Can you share your template formula for the PV forecast, as to build the pv_forecast array? I am trying to figure out how to build the array so I can use it for forecast.solar.
thank you
I came across the post
Can you share your template formula for the PV forecast, as to build the pv_forecast array? I am trying to figure out how to build the array so I can use it for forecast.solar.
thank you
Happy to help, but the post you linked to has the template which Iām using.
What else were you hoping to get?
I have coded this now:
\"pv_power_forecast\":{{[states('sensor.inverter_ingangsvermogen')|int(0)]
+ state_attr('sensor.template_test_solar_forecast','values_list')|selectattr('period_start','gt',utcnow())
| map(attribute='pv_estimate')|map('multiply',2000)|map('int')|list }}
Resulting in this:
UndefinedError: 'int object' has no attribute 'period_start'
Can you tell me where to define the attributes period_start and pv_estimate
selectattr('period_start','gt',utcnow()
and
map(attribute='pv_estimate')
Clearly I am missing something here. thx
period_start is part of the output of this (in my setup):
state_attr(āsensor.solcast_pv_forecast_forecast_todayā, ādetailedHourlyā)
It gives this:
[{āperiod_startā: datetime.datetime(2024, 6, 17, 0, 0, tzinfo=zoneinfo.ZoneInfo(key=āEurope/Amsterdamā)), āpv_estimateā: 0.0, āpv_estimate10ā: 0.0, āpv_estimate90ā: 0.0}, {āperiod_startā: datetime.datetime(2024, 6, 17, 1, 0, tzinfo=zoneinfo.ZoneInfo(key=āEurope/Amsterdamā)), āpv_estimateā: 0.0, āpv_estimate10ā: 0.0, āpv_estimate90ā: 0.0}, {āperiod_startā: datetime.datetime(2024, 6, 17, 2, 0, tzinfo=zoneinfo.ZoneInfo(key=āEurope/Amsterdamā)),
So most likely your āstate_attr(āsensor.template_test_solar_forecastā,āvalues_listā)ā does not contain the correct information. Is this also retrieved with the solcast integration?
Ah, that must be the issue. I am using Forecast.Solar now, so this wonāt work then.
Maybe go for solcast instead of forecast.solar to make things easy for me.
The solcast integration is having some issues at the moment.
Forecast solar should work you just need to get the data in a use able format.
The developer tools template editor is your friend.
So far my setup using the MPC is working well, I did lose out this morning but Amber smartshift was going to do the same thing EMHASS wanted to do.
Going to look at the ML fit model. It is possbile to use both MPC and ML at the same time?
In my case I am trying to account for morning spikes that never eventuate.
Yes you can use MPC & ML to get a comprehensive solution.
The morning false peaks are problematic as it drives EMHASS to hold back (or even charge overnight). A useful compromise I have is to set battery_discarge_weight to 0.15 (charge weight 0.00), which tends to hold charge overnight for morning peak rather than fully discharging at night, then recharging overnight at a high price.
One of the great things about EMHASS is you can tune/ modify the inputs so you can apply an 20% reduction to future price forecasts, or when Amber publish the advanced forecasts via the API we can use those.
Thanks Mark,
Im sure this has been asked a heap of times, but do you have the code for your current apexcharts setup?
It looks so much easier to read compaired to my own.
No worries:
type: custom:apexcharts-card
apex_config:
chart:
height: auto
header:
show: true
title: EMHASS Daily Forecast
show_states: true
colorize_states: true
graph_span: 36h
span:
start: minute
offset: +0h
all_series_config:
stroke_width: 1
now:
show: true
label: Now
yaxis:
- min: -7
max: 13
decimals: 0
apex_config:
forceNiceScale: true
tick_amount: 4
series:
- entity: sensor.consumption_savings_dmo
float_precision: 0
color: black
name: Savings (vs DMO)
show:
legend_value: false
in_chart: false
- entity: sensor.total_cost_fun_value
unit: $
invert: true
float_precision: 0
name: Cost
show:
legend_value: false
in_chart: false
transform: return x *-1
- entity: sensor.consumption_forecast
unit: kWh
float_precision: 0
name: House
show:
legend_value: false
in_chart: false
- entity: sensor.pv_forecast_energy
unit: kWh
float_precision: 0
color: orange
name: Solar
show:
legend_value: false
in_chart: false
- entity: sensor.p_pv_forecast
type: line
stroke_width: 2
color: orange
extend_to: false
show:
in_header: false
legend_value: false
data_generator: |
return entity.attributes.forecasts.map((entry) => {
return [new Date(entry.date), entry.p_pv_forecast/1000];
});
- entity: sensor.p_load_forecast
type: line
color: purple
extend_to: false
show:
in_header: false
legend_value: false
stroke_width: 1
data_generator: |
return entity.attributes.forecasts.map((entry) => {
return [new Date(entry.date), entry.p_load_forecast/1000];
});
- entity: sensor.p_batt_forecast
curve: stepline
color: lightgreen
extend_to: false
show:
in_header: false
legend_value: false
stroke_width: 1
type: area
data_generator: |
return entity.attributes.battery_scheduled_power.map((entry) => {
return [new Date(entry.date), entry.p_batt_forecast/1000];
});
- entity: sensor.p_grid_forecast
curve: stepline
color: lightgray
type: area
extend_to: false
show:
in_header: false
legend_value: false
stroke_width: 1
data_generator: |
return entity.attributes.forecasts.map((entry) => {
return [new Date(entry.date), entry.p_grid_forecast/1000];
});
- entity: sensor.p_deferrable0
curve: stepline
color: blue
name: Pool Pump
extend_to: false
show:
in_header: false
legend_value: false
stroke_width: 1
data_generator: |
return entity.attributes.deferrables_schedule.map((entry) => {
return [new Date(entry.date), entry.p_deferrable0/1000];
});
- entity: sensor.p_deferrable1
curve: stepline
color: red
name: Pool Heater
extend_to: false
show:
in_header: false
legend_value: false
stroke_width: 1
data_generator: |
return entity.attributes.deferrables_schedule.map((entry) => {
return [new Date(entry.date), entry.p_deferrable1/1000];
});
- entity: sensor.p_deferrable3
curve: stepline
name: HVAC
color: blue
extend_to: false
show:
in_header: false
legend_value: false
stroke_width: 1
data_generator: |
return entity.attributes.deferrables_schedule.map((entry) => {
return [new Date(entry.date), entry.p_deferrable3/1000];
});
- entity: sensor.p_deferrable4
curve: stepline
color: red
name: Hot Water
extend_to: false
show:
in_header: false
legend_value: false
stroke_width: 1
data_generator: |
return entity.attributes.deferrables_schedule.map((entry) => {
return [new Date(entry.date), entry.p_deferrable4/1000];
});
- entity: sensor.p_deferrable2
curve: stepline
color: black
name: Car
extend_to: false
show:
in_header: false
legend_value: false
stroke_width: 1
data_generator: |
return entity.attributes.deferrables_schedule.map((entry) => {
return [new Date(entry.date), entry.p_deferrable2/1000];
});
- entity: sensor.p_deferrable5
curve: stepline
name: Car2
color: grey
extend_to: false
show:
in_header: false
legend_value: false
stroke_width: 1
data_generator: |
return entity.attributes.deferrables_schedule.map((entry) => {
return [new Date(entry.date), entry.p_deferrable5/1000];
});
view_layout:
position: main
type: custom:apexcharts-card
experimental:
color_threshold: true
graph_span: 36h
span:
start: minute
offset: '-0h'
header:
show: true
title: Battery, Price & Cost Forecast
show_states: true
colorize_states: true
now:
show: true
label: Now
series:
- entity: sensor.unit_load_cost
float_precision: 2
yaxis_id: first
curve: stepline
extend_to: false
show:
in_header: before_now
legend_value: false
stroke_width: 1
color: red
unit: $/kWh
color_threshold:
- value: 0
color: cyan
- value: 0.19
color: green
- value: 0.3
color: yellow
- value: 0.4
color: red
data_generator: |
return entity.attributes.unit_load_cost_forecasts.map((entry) => {
return [new Date(entry.date), entry.unit_load_cost];
});
- entity: sensor.unit_prod_price
float_precision: 2
yaxis_id: first
curve: stepline
unit: $/kWh
extend_to: false
show:
in_header: before_now
legend_value: false
color: cyan
stroke_width: 1
data_generator: |
return entity.attributes.unit_prod_price_forecasts.map((entry) => {
return [new Date(entry.date), entry.unit_prod_price];
});
- entity: sensor.amber_feed_in_forecast
float_precision: 2
yaxis_id: first
curve: stepline
extend_to: false
show:
in_header: after_now
legend_value: false
color: orange
stroke_width: 1
name: feed in forecast
data_generator: |
return entity.attributes.forecasts.map((entry) => {
return [new Date(entry.start_time), entry.per_kwh];
});
- entity: sensor.soc_batt_forecast
float_precision: 0
yaxis_id: second
time_delta: +30m
extend_to: false
show:
in_header: before_now
legend_value: false
color: green
stroke_width: 1
name: battery SOC
data_generator: |
return entity.attributes.battery_scheduled_soc.map((entry) => {
return [new Date(entry.date), entry.soc_batt_forecast]; });
- entity: sensor.filtered_powerwall_soc
yaxis_id: second
type: line
stroke_width: 1
extend_to: false
color: green
show:
in_header: false
legend_value: false
in_chart: true
- entity: input_number.amber_closing_import_price
curve: stepline
yaxis_id: first
extend_to: false
stroke_width: 1
color: red
show:
in_header: false
legend_value: false
in_chart: true
- entity: input_number.amber_closing_export_price
curve: stepline
yaxis_id: first
extend_to: false
stroke_width: 1
color: blue
show:
in_header: false
legend_value: false
yaxis:
- id: first
decimals: 1
max: 1
min: 0
apex_config:
tickAmount: 2
logarithmic: false
- id: second
show: false
opposite: false
decimals: 1
max: 100
min: 0
apex_config:
tickAmount: 2
view_layout:
position: main
Jeez, hope you have battery so you can make a buck.
@rcruikshank By the way, thatās a nice way to show the electricity price, is it in the home assistant? If so, what kind of integration is it?
Morning spike has collapsed here, EMHASS is however getting seduced into charging overnight to meet these high forecasts that then disappear.
Iām finding battery_discharge_weight is useful to get EMHASS to keep some reserve, but I would dearly love to be able to use the advanced price forecasts from Amber, when they include them in the API, or run local ML to generate my own tempered price forecasts.
Unforunatley not EMHASS, thatās from the Amber Electicity website.
iām looking for a similar solution, think iāll start with the discharge_weight
Thatās the issue. I can charge the battery overnight at a cost but will the spike eventuate? It didnāt (again). So Iāve once again charged the battery at an inflated cost (42c) and now itās discharging at a loss so it can charge again from the sun for an even worse spike this evening. My battery is a bit tired at 6 years old and only contains about 7 or 8kWh and now it has to cover this tonight:
Iāll have to sit under an electric blanket all night. Canāt run the aircon if the price is this high and itās probably more likely to occur tonight. Seems the morning forecasts are furphies.
Sorry, furphy, Australian colloquialism for false report or improbable story; rumor .
Hello everyone,
thank you so much for this awesome piece of software!
I know this has been discussed in the past but I just cannot get it to work.
So here is the deal:
I am running the lastes docker image of EMHASS:
htpc:~# docker inspect emhass | grep -i version
"io.hass.base.version": "2024.03.0",
"io.hass.version": "2024.03.0",
"org.opencontainers.image.version": "v0.10.1"
htpc:/etc/emhass# docker pull davidusb/emhass-docker-standalone
Digest: sha256:607300ff655fa7e69b63890e64e77aec6f8726a1bf829a774976631a14ca8d68
Status: Image is up to date for davidusb/emhass-docker-standalone:latest
and this is the configuration I use:
retrieve_hass_conf:
freq: 30 # The time step to resample retrieved data from hass in minutes
days_to_retrieve: 2 # We will retrieve data from now and up to days_to_retrieve days
var_PV: 'sensor.sw29_power' # Photovoltaic produced power sensor in Watts
var_load: 'sensor.power_load_no_var_loads' # Household power consumption sensor in Watts (deferrable loads should be substracted)
load_negative: False # Set to True if the retrived load variable is negative by convention
set_zero_min: True # A special treatment for a minimum value saturation to zero. Values below zero are replaced by nans
var_replace_zero: # A list of retrived variables that we would want to replace nans with zeros
- 'sensor.sw29_power'
var_interp: # A list of retrived variables that we would want to interpolate nan values using linear interpolation
- 'sensor.sw29_power'
- 'sensor.power_load_no_var_loads'
method_ts_round: 'nearest' # Set the method for timestamp rounding, options are: first, last and nearest
continual_publish: False # Save published sensor data and check for state change every freq minutes
optim_conf:
set_use_battery: False # consider a battery storage
delta_forecast: 1 # days
num_def_loads: 2
P_deferrable_nom: # Watts
- 450.0
- 60.0
def_total_hours: # hours
- 5
- 3.5
def_start_timestep: # timesteps
- 0
- 0
def_end_timestep: # timesteps
- 40
- 19
treat_def_as_semi_cont: # treat this variable as semi continuous
- True
- True
set_def_constant: # set as a constant fixed value variable with just one startup for each 24h
- False
- True
# weather_forecast_method: 'solcast' # options are 'scrapper', 'csv', 'list', 'solcast' and 'solar.forecast'
weather_forecast_method: 'scrapper' # options are 'scrapper', 'csv', 'list', 'solcast' and 'solar.forecast'
load_forecast_method: 'csv' # options are 'csv' to load a custom load forecast from a CSV file or 'naive' for a persistance model
load_cost_forecast_method: 'hp_hc_periods' # options are 'hp_hc_periods' for peak and non-peak hours contracts and 'csv' to load custom cost from CSV file
list_hp_periods: # list of different tariff periods (only needed if load_cost_forecast_method='hp_hc_periods')
- period_hp_1:
- start: '00:00'
- end: '23:59'
load_cost_hp: 0.41 # peak hours load cost in ā¬/kWh (only needed if load_cost_forecast_method='hp_hc_periods')
load_cost_hc: 0.41 # non-peak hours load cost in ā¬/kWh (only needed if load_cost_forecast_method='hp_hc_periods')
prod_price_forecast_method: 'constant' # options are 'constant' for constant fixed value or 'csv' to load custom price forecast from a CSV file
prod_sell_price: 0.0 # power production selling price in ā¬/kWh (only needed if prod_price_forecast_method='constant')
set_total_pv_sell: False # consider that all PV power is injected to the grid (self-consumption with total sell)
lp_solver: 'default' # set the name of the linear programming solver that will be used. Options are 'PULP_CBC_CMD', 'GLPK_CMD' and 'COIN_CMD'.
lp_solver_path: 'empty' # set the path to the LP solver, COIN_CMD default is /usr/bin/cbc
set_nocharge_from_grid: False # avoid battery charging from the grid
set_nodischarge_to_grid: True # avoid battery discharging to the grid
set_battery_dynamic: False # add a constraint to limit the dynamic of the battery power in power per time unit
battery_dynamic_max: 0.9 # maximum dynamic positive power variation in percentage of battery maximum power
battery_dynamic_min: -0.9 # minimum dynamic negative power variation in percentage of battery maximum power
weight_battery_discharge: 0.0 # weight applied in cost function to battery usage for discharge
weight_battery_charge: 0.0 # weight applied in cost function to battery usage for charge
plant_conf:
P_from_grid_max: 9000 # The maximum power that can be supplied by the utility grid in Watts
P_to_grid_max: 9000 # The maximum power that can be supplied to the utility grid in Watts
module_model: # The PV module model
- 'JA_Solar_JAM54S30_415_MR'
inverter_model: # The PV inverter model
- 'Hoymiles_Power_Electronics_Inc___HMS_800_2T_NA__240V_'
surface_tilt: # The tilt angle of your solar panels
- 30
surface_azimuth: # The azimuth angle of your PV installation
- 180
modules_per_string: # The number of modules per string
- 1
strings_per_inverter: # The number of used strings per inverter
- 2
inverter_is_hybrid: False # Set if it is a hybrid inverter (PV+batteries) or not
For simplicity reasons I am passing all zeros for load_forecast_method for now.
The two deferrable loads are a warm water heat pump (450W or off) and a dishwasher (~60W), which shall run once a day and be done before 5pm
Here is what I get:
My questions are:
I am getting that the optimization assignment is āinfeasableā but the device contrainsts cannot be altered, so I would expect the optimization to honor these contrainst given in the configuration file. Can anyone shed some light on this? Any hints are greatly appreaciated! Cheers, Jan
When the assignment is infeasible
then the graphs wonāt make sense or follow your parameters. It normally means that something isnāt quite right.
My simple guess is becuase your PV never gets above 450w itās unable to optimise this correctly.
As a next step, Iād try one of the following:
optimal
result.