diff --git a/blueprints/priority_to_ev.yaml b/blueprints/priority_to_ev.yaml new file mode 100644 index 00000000..a5149bf0 --- /dev/null +++ b/blueprints/priority_to_ev.yaml @@ -0,0 +1,136 @@ +blueprint: + name: "Solar Router EV Control" + description: "Controls a solar router based on energy diversion, eletric vehicule connection and grid export conditions" + domain: automation + input: + ev_connected: + name: EV Connected + description: "Sensor indicating if the electric vehicle is connected" + selector: + entity: + domain: binary_sensor + energy_diversion: + name: Energy Diversion (solar_router.router_level) + description: "Sensor for current energy diversion percentage" + selector: + entity: + domain: sensor + energy_sent_to_grid: + name: Energy Sent to Grid (solar_router.real_power) + description: "Sensor for energy being sent to the grid (Ex: use real_power of your solar router)" + selector: + entity: + domain: sensor + solar_router: + name: Solar Router (solar_router.activate) + description: "Switch entity for the solar router" + selector: + entity: + domain: switch + max_diverted_energy: + name: Max Diverted Energy + description: "Maximum percentage of energy that should be diverted" + default: 100 + selector: + number: + min: 0 + max: 100 + unit_of_measurement: "%" + excess_energy_threshold: + name: Excess Energy Threshold + description: "Threshold for excess energy sent to grid (could be negative)" + default: 500 + selector: + number: + min: 0 + max: 3000 + unit_of_measurement: "W" + delay_before_deactivation: + name: Delay Before Deactivation + description: "Delay in seconds before deactivating the solar router" + default: 60 + selector: + number: + min: 0 + max: 300 + unit_of_measurement: "seconds" + max_energy_sent: + name: Max Energy Sent + description: "Maximum energy that can be sent to the grid before reactivating the solar router" + default: 200 + selector: + number: + min: 0 + max: 3000 + unit_of_measurement: "W" + delay_before_activation: + name: Delay Before Activation + description: "Delay in seconds before activating the solar router" + default: 60 + selector: + number: + min: 0 + max: 300 + unit_of_measurement: "seconds" + +trigger: + - platform: event + event_type: automation_reloaded + - platform: state + entity_id: !input ev_connected + - platform: numeric_state + entity_id: !input energy_sent_to_grid + above: !input excess_energy_threshold + for: + seconds: !input delay_before_deactivation + - platform: numeric_state + entity_id: !input energy_sent_to_grid + above: !input max_energy_sent + for: + seconds: !input delay_before_activation + +action: + - choose: + # Condition 1: Deactivate solar router when EV need to be recharged + - conditions: + - condition: state + entity_id: !input ev_connected + state: "on" + - condition: state + entity_id: !input solar_router + state: "on" + - condition: numeric_state + entity_id: !input energy_diversion + above: !input max_diverted_energy + - condition: numeric_state + entity_id: !input energy_sent_to_grid + above: !input excess_energy_threshold + sequence: + - service: switch.turn_off + target: + entity_id: !input solar_router + # Condition 2: Reactivate solar router when EV battery is full + - conditions: + - condition: state + entity_id: !input ev_connected + state: "on" + - condition: state + entity_id: !input solar_router + state: "off" + - condition: numeric_state + entity_id: !input energy_sent_to_grid + above: !input max_energy_sent + sequence: + - service: switch.turn_on + target: + entity_id: !input solar_router + # Condition 3: Activate solar router when EV disconnected + - conditions: + - condition: state + entity_id: !input ev_connected + state: "off" + sequence: + - service: switch.turn_on + target: + entity_id: !input solar_router + \ No newline at end of file diff --git a/cliff.toml b/cliff.toml index 2cfb754d..8497f532 100644 --- a/cliff.toml +++ b/cliff.toml @@ -61,6 +61,7 @@ commit_parsers = [ { message = "^refactor", group = "🚜 Refactor" }, { message = "^style", group = "🎨 Styling" }, { message = "^test", group = "🧪 Testing" }, + { message = "^build", group = "🏗️ Build" }, { message = "^chore\\(release\\): prepare for", skip = true }, { message = "^chore\\(deps.*\\)", skip = true }, { message = "^chore\\(pr\\)", skip = true }, diff --git a/docs/bleuprint_priority_to_ev.md b/docs/bleuprint_priority_to_ev.md new file mode 100644 index 00000000..6aa97dea --- /dev/null +++ b/docs/bleuprint_priority_to_ev.md @@ -0,0 +1,49 @@ +# Blueprint Priority_To_EV + +This blueprint is designed to activate and deactivate the solar router when EV requiring charge is connected and enough energy is produced to charge this EV. + +Here is a transcription of the prompt which help me to create this blueprint wiht AI. +It clearly explain how it behaves: + +``` +I would like to write a blueprint for Home Assistant that implements the following algorithm: + +// EV is disconnected +IF NOT ev_connected +THEN activate the solar router + +// EV is connected and its battery needs to be charged +IF ev_connected + AND energy_diversion > max_diverted_energy (%) + AND energy_sent_to_grid is greater than excess_energy_threshold + FOR delay_before_deactivation in seconds +THEN deactivate the solar router + +// EV battery is fully charged +IF ev_connected + AND the solar router is deactivated + AND the energy sent back to the grid is greater than max_energy_sent + FOR delay_before_activation +THEN activate the solar router. + +The blueprint should be written in English and each variable should be commented. +``` + +To install this blueprint, refer to [Home assistant documention](https://www.home-assistant.io/docs/automation/using_blueprints/). + +The URL to use is : [https://raw.githubusercontent.com/XavierBerger/Solar-Router-for-ESPHome/refs/heads/main/blueprints/priority_to_ev.yaml](https://raw.githubusercontent.com/XavierBerger/Solar-Router-for-ESPHome/refs/heads/main/blueprints/priority_to_ev.yaml) + +!!! note + EV connected is a binary sensor. If your EV charge is displaying a string saying id EV is connected or not it will be required to create a custom sensors to create this binary sensor. + + Example for MyEnergi Zappi: + + ```yaml + template: + - binary_sensor: + - name: "EV Connected Status" + unique_id: ev_connected_status + state: "{{ is_state('sensor.myenergi_zappi_plug_status', 'EV Connected') }}" + device_class: plug + + ``` \ No newline at end of file diff --git a/docs/en/alternatives.md b/docs/en/alternatives.md index ed68e626..1a85527e 100644 --- a/docs/en/alternatives.md +++ b/docs/en/alternatives.md @@ -12,4 +12,4 @@ If it doesn't fully feat your needs, you may have a look to the following projec * [PV-Routeur Solaire ESP Home](https://domo.rem81.com/index.php/2023/07/18/pv-routeur-solaire/) from **Remy**, Routeur solaire à base de ESPHome qui a aussi été source d'inspiration pour **Solar-Router-for-ESPHome** !!! note "Missing alternative?" - Feel free to open an issue on [GitHub](https://github.com/hacf-fr/Solar-Router-for-ESPHome/issues) and we'll update this page with this alternative. \ No newline at end of file + Feel free to open an issue on [GitHub](https://github.com/hacf-fr/Solar-Router-for-ESPHome/issues) and we'll update this page with this alternative. diff --git a/mkdocs.yml b/mkdocs.yml index 036596da..4d63f025 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -46,6 +46,7 @@ nav: - Overview: scheduler.md - Forced Run: scheduler_forced_run.md - Home Assistant: + - Blueprint Priority_to_EV: bleuprint_priority_to_ev.md - Recorder configuration: recorder_configuration.md - Debug sensors: debug_sensors.md - About: diff --git a/solar_router/engine_1switch.yaml b/solar_router/engine_1switch.yaml index c231fbaa..8ed233b8 100644 --- a/solar_router/engine_1switch.yaml +++ b/solar_router/engine_1switch.yaml @@ -86,6 +86,19 @@ number: then: - light.turn_on: green_led + # Regulator opening is required by engine_common ad-hoc sensor + # Note: there is maybe a refactor to do or a doc to write to explain regulator_opening vs router_level + - platform: template + name: "Regulator Opening" + id: regulator_opening + min_value: 0 + max_value: 100 + step: 100 + unit_of_measurement: "%" + optimistic: True + mode: slider + internal: true + # Define the power level to start divertion - platform: template name: "Start power level" diff --git a/solar_router/engine_common.yaml b/solar_router/engine_common.yaml index 14d3c22e..8772f3c1 100644 --- a/solar_router/engine_common.yaml +++ b/solar_router/engine_common.yaml @@ -23,6 +23,13 @@ sensor: then: script.execute: energy_regulation + - platform: template + name: "Regulator Opening Sensor" + id: regulator_opening_sensor + unit_of_measurement: "%" + accuracy_decimals: 0 + lambda: return id(regulator_opening).state; + substitutions: # By default led are pin control is not inverted green_led_inverted: "False" @@ -32,7 +39,9 @@ substitutions: # By default leds are hidden hide_leds: "True" -# Component managing time. +# ---------------------------------------------------------------------------------------------------- +# Time management +# ---------------------------------------------------------------------------------------------------- # If activate switch is ON, yellow led update is performed every secondes time: - platform: sntp @@ -49,7 +58,7 @@ time: condition: lambda: return id(real_power).state == NAN; then: - # When NAN is returns, it means that an error occurs. Yellow LED blink fast + # When NAN is returned, it means that an error occurs - light.turn_on: id: yellow_led effect: fast diff --git a/solar_router/power_meter_fronius.yaml b/solar_router/power_meter_fronius.yaml index 24439b8f..5cbe6a6c 100644 --- a/solar_router/power_meter_fronius.yaml +++ b/solar_router/power_meter_fronius.yaml @@ -1,4 +1,5 @@ -<<: !include power_meter_common.yaml +packages: + - !include power_meter_common.yaml esphome: min_version: 2025.5.0 @@ -102,8 +103,4 @@ time: on_time: - seconds: /1 then: - - if: - condition: - - lambda: return id(power_meter_activated) != 0; - then: - - script.execute: power_meter_source + - script.execute: power_meter_source diff --git a/solar_router/power_meter_home_assistant.yaml b/solar_router/power_meter_home_assistant.yaml index 1def5df3..957d3a0d 100644 --- a/solar_router/power_meter_home_assistant.yaml +++ b/solar_router/power_meter_home_assistant.yaml @@ -1,4 +1,5 @@ -<<: !include power_meter_common.yaml +packages: + - !include power_meter_common.yaml # ---------------------------------------------------------------------------------------------------- # Define sensor for power collection @@ -7,20 +8,28 @@ sensor: # Sensor showing the actual power exchange - platform: homeassistant - id: real_power + id: real_power_reader entity_id: ${main_power_sensor} internal: False - name: "Real Power" + name: "Real Power Reader" device_class: "power" unit_of_measurement: "W" filters: - multiply: ${power_sign} + on_value: + then: + - lambda: |- + id(real_power).publish_state(x); # Sensor showing the actual consumption - platform: homeassistant - id: consumption + id: consumption_reader entity_id: ${consumption_sensor} internal: False - name: "Consumption" + name: "Consumption Reader" device_class: "power" unit_of_measurement: "W" + on_value: + then: + - lambda: |- + id(consumption).publish_state(x); diff --git a/solar_router/power_meter_proxy_client.yaml b/solar_router/power_meter_proxy_client.yaml index 136b3f56..b6269d46 100644 --- a/solar_router/power_meter_proxy_client.yaml +++ b/solar_router/power_meter_proxy_client.yaml @@ -1,4 +1,5 @@ -<<: !include power_meter_common.yaml +packages: + - !include power_meter_common.yaml esphome: min_version: 2024.11.1 @@ -92,8 +93,4 @@ time: on_time: - seconds: /1 then: - - if: - condition: - - lambda: return id(power_meter_activated) != 0; - then: - - script.execute: power_meter_source + - script.execute: power_meter_source diff --git a/solar_router/power_meter_shelly_em.yaml b/solar_router/power_meter_shelly_em.yaml index 290823fb..71c8d044 100644 --- a/solar_router/power_meter_shelly_em.yaml +++ b/solar_router/power_meter_shelly_em.yaml @@ -1,4 +1,5 @@ -<<: !include power_meter_common.yaml +packages: + - !include power_meter_common.yaml esphome: min_version: 2025.5.0 @@ -74,8 +75,4 @@ time: on_time: - seconds: /1 then: - - if: - condition: - - lambda: return id(power_meter_activated) != 0; - then: - - script.execute: power_meter_source + - script.execute: power_meter_source diff --git a/solar_router/temperature_limiter_DS18B20.yaml b/solar_router/temperature_limiter_DS18B20.yaml index 023cde13..aab7c9c3 100644 --- a/solar_router/temperature_limiter_DS18B20.yaml +++ b/solar_router/temperature_limiter_DS18B20.yaml @@ -3,7 +3,8 @@ substitutions: temperature_update_interval: 5s red_led_inverted: "False" -<<: !include temperature_limiter_common.yaml +packages: + - !include temperature_limiter_common.yaml one_wire: - platform: gpio diff --git a/solar_router/temperature_limiter_home_assistant.yaml b/solar_router/temperature_limiter_home_assistant.yaml index 3f9b2f75..c93a884d 100644 --- a/solar_router/temperature_limiter_home_assistant.yaml +++ b/solar_router/temperature_limiter_home_assistant.yaml @@ -4,7 +4,8 @@ substitutions: red_led_inverted: "False" -<<: !include temperature_limiter_common.yaml +packages: + - !include temperature_limiter_common.yaml sensor: # Sensor showing the temprature to monitor