|
# https://www.home-assistant.io/integrations/input_number |
|
input_number: |
|
# Inverters nominal power, usually 400W, 500W, 1000W, etc |
|
inverters_nominal_power: |
|
name: Inverters Nominal Power |
|
unit_of_measurement: W |
|
min: 0 |
|
max: 2000 |
|
step: 50 |
|
mode: slider |
|
# Manual control of the production limit of inverters |
|
inverters_power_limit: |
|
name: Inverters Power Limit |
|
unit_of_measurement: W |
|
min: 0 |
|
max: 500 |
|
step: 1 |
|
mode: slider |
|
# Target excess or import to stay close to |
|
inverters_excess_setpoint: |
|
name: Inverters Excess Setpoint |
|
unit_of_measurement: W |
|
min: -2000 |
|
max: 2000 |
|
step: 100 |
|
mode: slider |
|
# Target excess or import to stay close to, when 3ERL asks to limit the solar production |
|
inverters_excess_setpoint_limiter: |
|
name: Inverters Excess Setpoint With Limiter |
|
unit_of_measurement: W |
|
min: -1000 |
|
max: 1000 |
|
step: 100 |
|
mode: slider |
|
# Total number of inverters. Inverters should be named Inverter 1, Inverter 2, etc |
|
inverters_count: |
|
name: Inverters Count |
|
min: 0 |
|
max: 30 |
|
step: 1 |
|
mode: slider |
|
|
|
# https://www.home-assistant.io/integrations/rest |
|
rest: |
|
# Get the 3ERL trend (https://3erl.fr) for 3ERL subscribers |
|
- resource: https://3erl.fr/api.json |
|
scan_interval: 60 |
|
binary_sensor: |
|
- name: "3ERL: Bridage Demandé" |
|
icon: "mdi:car-speed-limiter" |
|
unique_id: 347A6F4D-6B09-4A20-9C2C-D611ED23EF4B |
|
value_template: "{{ value_json['Bridage'] }}" |
|
sensor: |
|
- name: "3ERL: Tendance du jour" |
|
icon: "mdi:trending-up" |
|
unique_id: 31F1BED4-8100-44A4-88BA-DB45450611CF |
|
# multiply by 10 because the value is in câŹ/kWh |
|
value_template: | |
|
{% set data = value_json['PREP_Profile'] %} |
|
{% if data == '3+' %} đąđąđą |
|
{% elif data == '2+' %} đąđą |
|
{% elif data == '1+' %} đą |
|
{% elif data == '0' %} â ïž |
|
{% elif data == '1-' %} âïž |
|
{% elif data == '2-' %} âïžâïž |
|
{% elif data == '3-' %} âïžâïžâïž |
|
{% else %} âïž |
|
{% endif %} |
|
|
|
# Get the electricity market price trend from RTE |
|
- resource_template: https://www.services-rte.com/cms/open_data/v1/price/table?startDate={{ now().strftime('%d%%2F%m%%2F%Y') }} |
|
scan_interval: 60 |
|
sensor: |
|
- name: "ĂlectricitĂ©: Prix de rĂšglement des Ă©carts positifs" |
|
icon: "mdi:currency-eur" |
|
unique_id: EA2D2A8C-5327-47C8-92EF-C16E9BE7A4C5 |
|
state_class: measurement |
|
unit_of_measurement: "âŹ/MWh" |
|
value_template: "{{ value_json['values'][0]['pre']['positive'] | float }}" |
|
- name: "ĂlectricitĂ©: Prix de rĂšglement des Ă©carts nĂ©gatifs" |
|
icon: "mdi:currency-eur" |
|
unique_id: 95AE2165-7E9A-40BA-A555-1C7B7B93B26D |
|
value_template: "{{ value_json['values'][0]['pre']['negative'] | float }}" |
|
state_class: measurement |
|
unit_of_measurement: "âŹ/MWh" |
|
|
|
mqtt: |
|
# https://www.home-assistant.io/integrations/sensor.mqtt |
|
sensor: |
|
- name: Inverters YieldTotal |
|
unique_id: D6A6659B-EE6A-4C3F-91F4-C0FBD46E8CF5 |
|
state_class: total_increasing |
|
device_class: energy |
|
unit_of_measurement: "kWh" |
|
state_topic: "opendtu/ac/yieldtotal" |
|
value_template: "{{ value|float }}" |
|
# availability_topic: "opendtu/ac/is_valid" |
|
# payload_available: "1" |
|
# payload_not_available: "0" |
|
|
|
- name: Inverters YieldDay |
|
unique_id: "01e37eed-3045-4eee-a786-1249567fe310" |
|
state_class: total_increasing |
|
device_class: energy |
|
unit_of_measurement: "kWh" |
|
state_topic: "opendtu/ac/yieldday" |
|
value_template: "{{ value|float / 1000.0 }}" |
|
# availability_topic: "opendtu/ac/is_valid" |
|
# payload_available: "1" |
|
# payload_not_available: "0" |
|
|
|
- name: Inverters Produced PowerDC |
|
unique_id: "01e37eed-3045-4eee-a786-1249567fe316" |
|
state_class: measurement |
|
device_class: power |
|
unit_of_measurement: W |
|
state_topic: "opendtu/dc/power" |
|
value_template: "{{ value|int }}" |
|
availability_topic: "opendtu/dc/is_valid" |
|
payload_available: "1" |
|
payload_not_available: "0" |
|
|
|
- name: Inverters Produced Power |
|
unique_id: "01e37eed-3045-4eee-a786-1249567fe315" |
|
state_class: measurement |
|
device_class: power |
|
unit_of_measurement: W |
|
state_topic: "opendtu/ac/power" |
|
value_template: "{{ value|int }}" |
|
availability_topic: "opendtu/ac/is_valid" |
|
payload_available: "1" |
|
payload_not_available: "0" |
|
|
|
# https://www.home-assistant.io/integrations/utility_meter/ |
|
utility_meter: |
|
# Compute the daily yield of all inverters |
|
inverters_energy_meter_daily: |
|
name: Inverters Energy Meter Daily |
|
unique_id: 4C4D8D06-C9D2-4408-B21A-1274A6E0F041 |
|
source: sensor.inverters_yieldday |
|
cycle: daily |
|
|
|
template: |
|
# https://www.home-assistant.io/integrations/sensor/ |
|
- sensor: |
|
- name: Inverters Energy |
|
unique_id: 6E14EC86-0965-463E-BFBF-6008B61B56AF |
|
state_class: total_increasing |
|
device_class: energy |
|
unit_of_measurement: "kWh" |
|
state: "{{ [states('sensor.inverters_yieldtotal')|float(0), states('sensor.inverters_energy')|float(0) ] | max }}" |
|
|
|
# Compute the quantity of power that is not produced when inverters are limited |
|
- name: Inverters Lost Power |
|
unique_id: B1C00B87-BC48-4801-ABF0-AC10ABF28B0B |
|
state_class: measurement |
|
device_class: power |
|
unit_of_measurement: "W" |
|
state: >- |
|
{% set sum = namespace(value=0) %} |
|
{% set count = states('input_number.inverters_count')|int(0) %} |
|
{% for i in range(1, count + 1) %} |
|
{% set p = states('sensor.inverter_' + i|string + '_power')|float(0) %} |
|
{% set l = [0, [100, states('number.inverter_' + i|string + '_limit_nonpersistent_relative')|float(100)]|min]|max %} |
|
{% set loss = 0 if l == 0 else p * (100 - l) / l %} |
|
{% set sum.value = sum.value + loss %} |
|
{% endfor %} |
|
{{ sum.value }} |
|
|
|
# Compute the quantity of power that inverters would produce |
|
- name: Inverters Total Power |
|
unique_id: BA5A10EE-CD10-4DF8-80AE-287D1CBAFD30 |
|
state_class: measurement |
|
device_class: power |
|
unit_of_measurement: "W" |
|
state: >- |
|
{% set sum = namespace(value=0) %} |
|
{% set count = states('input_number.inverters_count')|int(0) %} |
|
{% for i in range(1, count + 1) %} |
|
{% set p = states('sensor.inverter_' + i|string + '_power')|float(0) %} |
|
{% set l = [0, [100, states('number.inverter_' + i|string + '_limit_nonpersistent_relative')|float(100)]|min]|max %} |
|
{% set total = 0 if l == 0 else p * 100 / l %} |
|
{% set sum.value = sum.value + total %} |
|
{% endfor %} |
|
{{ sum.value }} |
|
|
|
# Compute the number of inverters currently producing power |
|
- name: Inverters Producing Count |
|
unique_id: 7FAAECB4-2105-4F86-B63E-A1962F7FC81E |
|
state: >- |
|
{% set count = states('input_number.inverters_count')|int(0) %} |
|
{{ range(1, count + 1)|map('regex_replace', '(\d+)', "sensor.inverter_\\1_power")|map('states')|map('is_number')|reject("false")|list|count }} |
|
|
|
# https://www.home-assistant.io/docs/automation/ |
|
automation: |
|
# Detect changes to "Inverters Power Limit" input and propagate it to imverters |
|
- id: "0000000000038" |
|
alias: "Inverters: Update Power Limit" |
|
trigger: |
|
- trigger: state |
|
entity_id: |
|
- input_number.inverters_power_limit |
|
condition: [] |
|
action: |
|
- action: number.set_value |
|
data: |
|
value: "{{[states.input_number.inverters_nominal_power.state|int, [0, states.input_number.inverters_power_limit.state|int]|max]|min}}" |
|
target: |
|
entity_id: |
|
- number.inverter_1_limit_nonpersistent_absolute |
|
- number.inverter_2_limit_nonpersistent_absolute |
|
- number.inverter_3_limit_nonpersistent_absolute |
|
- number.inverter_4_limit_nonpersistent_absolute |
|
- number.inverter_5_limit_nonpersistent_absolute |
|
- number.inverter_6_limit_nonpersistent_absolute |
|
|
|
# Each 2 minutes, compute the new limit to set to inverters |
|
- id: "0000000000039" |
|
alias: "Inverters: Auto Update Power Limit" |
|
trigger: |
|
- trigger: time_pattern |
|
minutes: /2 |
|
condition: |
|
- condition: state |
|
entity_id: binary_sensor.opendtu_status |
|
state: "on" |
|
- condition: template |
|
value_template: | |
|
{{['sensor.grid_power']|map('states')|map('is_number')|min}} |
|
- condition: template |
|
value_template: | |
|
{% set count = states('input_number.inverters_count')|int(0) %} |
|
{{ range(1, count + 1)|map('regex_replace', '(\d+)', "sensor.inverter_\\1_power")|map('states')|map('is_number')|reject("false")|list|count > 0 }} |
|
action: |
|
- variables: |
|
new_limit: >- |
|
{% set available = states('sensor.inverters_producing_count')|float(0) %} |
|
{% set nominalPower = states('input_number.inverters_nominal_power')|float(0) %} |
|
{% set setpointWithoutLimiter = states('input_number.inverters_excess_setpoint')|float(0) %} |
|
{% set setpointWithLimiter = states('input_number.inverters_excess_setpoint_limiter')|float(0) %} |
|
{% set limiterEnabled = states('binary_sensor.3erl_bridage_demande') == 'on' %} |
|
{% set setpoint = setpointWithLimiter if limiterEnabled else setpointWithoutLimiter %} |
|
{% set grid = states('sensor.grid_power')|float %} |
|
{% set error = ((grid - setpoint) / available) | int if available > 0 else 0 %} |
|
{{ [nominalPower, [10, states.input_number.inverters_power_limit.state|int + error]|max]|min }} |
|
- action: input_number.set_value |
|
data: |
|
value: "{{ new_limit }}" |
|
target: |
|
entity_id: |
|
- input_number.inverters_power_limit |
|
|
|
# For 3ERL subscribers, activate or deactivate the automation to automatically limit the inverters when 3ERL asks for it |
|
- id: "0000000000040" |
|
alias: "Inverters: Auto Activate 3ERL Limit" |
|
triggers: |
|
- trigger: state |
|
entity_id: |
|
- binary_sensor.3erl_bridage_demande |
|
- trigger: homeassistant |
|
event: start |
|
conditions: [] |
|
actions: |
|
- if: |
|
- condition: state |
|
entity_id: binary_sensor.3erl_bridage_demande |
|
state: "on" |
|
then: |
|
- action: automation.turn_on |
|
target: |
|
entity_id: automation.inverters_auto_update_power_limit |
|
else: |
|
- action: automation.turn_off |
|
target: |
|
entity_id: automation.inverters_auto_update_power_limit |
|
- action: input_number.set_value |
|
data: |
|
value: "{{ states.input_number.inverters_nominal_power.state }}" |
|
target: |
|
entity_id: input_number.inverters_power_limit |
|
|
|
# For those having OpenEVSE car charger, when vehicule is connected, automatically increase the excess so that the EV can start charging |
|
- id: "0000000000041" |
|
alias: "Inverters: Auto Update Setpoint" |
|
triggers: |
|
- trigger: state |
|
entity_id: |
|
- binary_sensor.openevse_vehicle_connected |
|
- sensor.openevse_vehicle_battery_level |
|
conditions: [] |
|
actions: |
|
- if: |
|
- condition: state |
|
entity_id: binary_sensor.openevse_vehicle_connected |
|
state: "on" |
|
- condition: numeric_state |
|
entity_id: sensor.openevse_vehicle_battery_level |
|
below: 100 |
|
then: |
|
- action: input_number.set_value |
|
metadata: {} |
|
data: |
|
value: -600 |
|
target: |
|
entity_id: input_number.inverters_excess_setpoint_limiter |
|
else: |
|
- action: input_number.set_value |
|
metadata: {} |
|
data: |
|
value: -300 |
|
target: |
|
entity_id: input_number.inverters_excess_setpoint_limiter |