Here are some of my configurations to get EMHASS working with Amber Electric (Australia) Custom Component.
@madpilot @kc_au @ThirtyDursty
The magic happens in the shell commands:
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.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list)
}},\"load_cost_forecast\":{{(
state_attr('sensor.amber_general_forecast', 'forecasts') |map(attribute='per_kwh')|list)
}}}' 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.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list)
}},{{states('sensor.solcast_24hrs_forecast')}},\"load_cost_forecast\":{{(
state_attr('sensor.amber_general_forecast', 'forecasts') |map(attribute='per_kwh')|list)
}}}' http://localhost:5000/action/dayahead-optim"
post_mpc_optim: "curl -i -H \"Content-Type: application/json\" -X POST -d '{\"load_cost_forecast\":{{(
([states('sensor.amber_general_price')|float(0)] +
state_attr('sensor.amber_general_forecast', 'forecasts') |map(attribute='per_kwh')|list)[:48])
}}, \"prod_price_forecast\":{{(
([states('sensor.amber_feed_in_price')|float(0)] +
state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list)[:48])
}}, \"prediction_horizon\":{{min(48,
(state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)+1)
}},\"soc_init\":{{states('sensor.powerwall_charge')|float(0)/100}},\"soc_final\":0.05,\"def_total_hours\":[8,3,2,2]}' http://localhost:5000/action/naive-mpc-optim"
But let me unpack this for you first, I recommend you do a lot of work in the Developer Tools Template first.
{{state_attr('sensor.p_batt_forecast', 'forecasts')|map(attribute='p_batt_forecast')|list|length}}
{{state_attr('sensor.p_batt_forecast', 'forecasts')|map(attribute='p_batt_forecast')|list}}
"soc_init":{{states('sensor.powerwall_charge')|float(0)/100}}
"prediction_horizon":{{min(48,state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length+1)}}
"load_cost_forecast":{{([states('sensor.amber_general_price')|float] +
state_attr('sensor.amber_general_forecast', 'forecasts') |map(attribute='per_kwh')|list)[:48]}}
"prod_price_forecast":{{([states('sensor.amber_feed_in_price')|float] +
state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list)[:48]}}
"load_now": {{(states('sensor.powerwall_load_now')|float(0)*1000)|round(0)}}
"pv_now": {{(states('sensor.powerwall_solar_now')|float(0)*1000)|round(0)}}
"def_total_hours [EV 11 kW]": {{ state_attr('sensor.duka_charging_rate_sensor','time_left')|int(2)}}
"def_total_hours [Pool Filter 1.4 kW]": 4
"def_total_hours [HVAC humidity 4 kW]": {{max(0,(state_attr('climate.family','current_humidity')|int(0) - 60)/10)|int(0)}}
"def_total_hours [HVAC temp 4 kW]": {{max(0,(state_attr('climate.bedroom','current_temperature')|float(0) -
state_attr('climate.daikin_ap46401','temperature')|float))}}
"def_total_hours [HVAC No People 4 kW]": {{states('zone.home')}}
"def_total_hours [Pool Heater 5 kW]": {{states('input_number.pool_temperature_set_point')|int -
states('input_number.pool_temperature')|int}}
curl -i -H "Content-Type: application/json" -X POST -d '{"prod_price_forecast":{{(
(state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list) )
}},"load_cost_forecast":{{(
(state_attr('sensor.amber_general_forecast', 'forecasts') |map(attribute='per_kwh')|list) )
}},"prediction_horizon":{{(state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)
}},"soc_init":{{states('sensor.powerwall_charge')|float(0)/100
}},"soc_final":0.05,"def_total_hours":[4,5,3,1]}' http://localhost:5000/action/naive-mpc-optim
post_mpc_optim: "curl -i -H \"Content-Type: application/json\" -X POST -d '{\"prod_price_forecast\":{{(
[states('sensor.amber_feed_in_price')|float(0)] +
(state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list)[:47])
}},\"load_cost_forecast\":{{(
[states('sensor.amber_general_price')|float(0)] +
(state_attr('sensor.amber_general_forecast', 'forecasts') |map(attribute='per_kwh')|list)[:47])
}},\"prediction_horizon\":{{min(48,
(state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)+1)
}},\"soc_init\":{{states('sensor.powerwall_charge')|float(0)/100}},\"soc_final\":0.05,\"def_total_hours\":[4,5]}' http://localhost:5000/action/naive-mpc-optim"
My Automations, either a single day-ahead optimisation or MPC running every minute.
alias: EMHASS day-ahead optimization
description: ''
trigger:
- platform: time_pattern
minutes: '25'
hours: '5'
condition: []
action:
- service: shell_command.post_amber_forecast
data: {}
- service: shell_command.publish_data
data: {}
mode: single
alias: EMHASS MPC optimization
description: ''
trigger:
- platform: time_pattern
minutes: /1
condition: []
action:
- service: shell_command.post_mpc_optim
data: {}
- service: shell_command.publish_data
data: {}
mode: single
alias: p_deferable1 automation
description: ''
trigger:
- platform: numeric_state
entity_id: sensor.p_deferrable1
above: '0.1'
for:
hours: 0
minutes: 2
seconds: 0
- platform: numeric_state
entity_id: sensor.p_deferrable1
for:
hours: 0
minutes: 2
seconds: 0
below: '0.1'
condition: []
action:
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.p_deferrable1
above: '0.1'
sequence:
- type: turn_on
device_id: 03a766ec3275e2c80020c5f5a3d8e603
entity_id: switch.pool_heater_pump
domain: switch
- service: notify.mobile_app_pixel_6
data:
message: Pool Heater on
default:
- type: turn_off
device_id: 03a766ec3275e2c80020c5f5a3d8e603
entity_id: switch.pool_heater_pump
domain: switch
- service: notify.mobile_app_pixel_6
data:
message: Pool Heater off
mode: single
alias: p_batt automation
description: ''
trigger:
- platform: numeric_state
entity_id: sensor.p_batt_forecast
below: '-4000'
condition: []
action:
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.p_batt_forecast
below: '-3000'
sequence:
- service: notify.mobile_app_pixel_6
data:
title: p_batt alert {{states('sensor.p_batt_forecast')}} - mode:backup
message: d{{states('sensor.amber_general_price')}} $/kWh
- service: tesla_gateway.set_operation
data:
real_mode: backup
- conditions:
- condition: numeric_state
entity_id: sensor.p_batt_forecast
above: '4900'
sequence:
- service: tesla_gateway.set_operation
data:
real_mode: autonomous
backup_reserve_percent: 1
- service: notify.mobile_app_pixel_6
data:
title: >-
p_batt alert {{states('sensor.p_batt_forecast')}} -
mode:autonomous
message: d{{states('sensor.amber_general_price')}} $/kWh
default:
- service: notify.mobile_app_pixel_6
data:
title: >-
p_batt alert {{states('sensor.p_batt_forecast')}} -
mode:self_consumption
message: d{{states('sensor.amber_general_price')}} $/kWh
- service: tesla_gateway.set_operation
data:
real_mode: self_consumption
backup_reserve_percent: 2
mode: single