Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions docs/en/temperature_fan_control.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Temperature fan control

This package is designed to manage a fan with the objective to control the temperature of the solar router.
This module is reading the temperature from a `temperature limiter`.
The fan can be configured to start spinning as soon as the start temperature is reached and stop spinning when the measured temperature comes below the stop temperature.

??? Note "More about the mechanism avoiding regulation bouncing"
The two thresholds regulation used here is named **hysteresis**. This mechanism avoids regulation bouncing.
See ***More details about hysteresis and Schmitt trigger*** in [temperature_limiter](temperature_limiter.md) page.


!!! danger "WARNING: Conduct some tests before letting the system regulate alone"
This fan control logic may have some bugs. It is strongly advised to validate the behaviour of your system carefully before letting the system working by its own.

## Prerequisites

This package is not standalone. It relies on symbols provided by two other packages that must be included in your configuration:

- an `engine_*` package (e.g. `engine_1dimmer.yaml`) that provides the `activate` switch,
- a `temperature_limiter_*` package (e.g. `temperature_limiter_DS18B20.yaml`) that provides the `safety_temperature` sensor.

## Cooling direction

The fan is meant to cool the object monitored by `safety_temperature`. Fan **on** when the temperature rises above `fan_start_temperature`, fan **off** when it falls below `fan_stop_temperature`. if you need the opposite behaviour, this package is not the right fit.

## Threshold invariant

The two thresholds are coupled: `fan_start_temperature > fan_stop_temperature` is always enforced. If you change one of them to a value that would break the invariant, the other one is nudged automatically by 1 °C so a valid hysteresis is preserved:

- setting `fan_stop_temperature` to a value `>=` the current `fan_start_temperature` pushes `fan_start_temperature` to `fan_stop_temperature + 1`,
- setting `fan_start_temperature` to a value `<=` the current `fan_stop_temperature` pulls `fan_stop_temperature` to `fan_start_temperature - 1`.

You can therefore edit either value in any order without ever landing on an invalid configuration.

## Wiring

The energy available on a pin of the ESP32 is not sufficient to directly power the fan. It is then required to add an additional circuit to use 5V or 12V with the fan.

The following schematic represents the wiring of the fan:

![FanControl](images/fan_controller.png){width=400}

## Configuration

To use this package, add the following lines to your configuration file:

```yaml linenums="1"
packages:
fan_controller:
url: https://github.com/hacf-fr/Solar-Router-for-ESPHome/
files:
- path: solar_router/temperature_fan_control.yaml
vars:
fan_control_pin: GPIO4
```

### Variables

| Variable | Required | Default | Description |
| ---------------------- | -------- | --------- | -------------------------------------------------------------------------------------------- |
| `fan_control_pin` | yes | — | GPIO pin driving the fan control circuit. |
| `fan_control_inverted` | no | `"False"` | Set to `"True"` if the driving circuit inverts the logic (e.g. active‑low transistor stage). |
62 changes: 62 additions & 0 deletions docs/fr/temperature_fan_control.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Contrôle du ventilateur

Ce package est conçu pour piloter un ventilateur afin de contrôler la température du routeur solaire.
Ce module lit la température fournie par un `temperature limiter`.
Le ventilateur peut être configuré pour démarrer dès que la température de démarrage est atteinte et s'arrêter lorsque la température mesurée passe sous la température d'arrêt.

??? Note "Détails du mécanisme de régulation anti-rebond"
La régulation à deux seuils utilisée ici est appelée **hystérésis**. Ce mécanisme évite les oscillations de la régulation.
Voir ***Plus de détails sur l'hystérésis et le trigger de Schmitt*** sur la page [temperature_limiter](temperature_limiter.md).


!!! danger "ATTENTION : effectuez des tests avant de laisser le système réguler seul"
La logique de contrôle du ventilateur peut contenir des bugs. Il est fortement conseillé de valider soigneusement le comportement de votre système avant de le laisser fonctionner seul.

## Prérequis

Ce package n'est pas autonome. Il repose sur des identifiants fournis par deux autres packages qui doivent être inclus dans votre configuration :

- un package `engine_*` (par exemple `engine_1dimmer.yaml`) qui fournit l'interrupteur `activate`,
- un package `temperature_limiter_*` (par exemple `temperature_limiter_DS18B20.yaml`) qui fournit le capteur `safety_temperature`.

## Sens de régulation

Le ventilateur est destiné à refroidir l'élément surveillé par `safety_temperature`. Il se met en marche lorsque la température dépasse `fan_start_temperature` et s'arrête lorsqu'elle descend en dessous de `fan_stop_temperature`. Si vous avez besoin d'un fonctionnement inverse, ce paquet ne convient pas.
Comment thread
XavierBerger marked this conversation as resolved.

## Invariant des seuils

Les deux seuils sont couplés : `fan_start_temperature > fan_stop_temperature` est garanti en permanence. Si vous modifiez l'un des deux à une valeur qui casserait cet invariant, l'autre est automatiquement ajusté de 1 °C pour préserver une hystérésis valide :

- fixer `fan_stop_temperature` à une valeur `>=` à l'actuel `fan_start_temperature` remonte `fan_start_temperature` à `fan_stop_temperature + 1`,
- fixer `fan_start_temperature` à une valeur `<=` à l'actuel `fan_stop_temperature` descend `fan_stop_temperature` à `fan_start_temperature - 1`.

Vous pouvez donc modifier l'un ou l'autre des seuils dans n'importe quel ordre sans jamais tomber sur une configuration invalide.

## Câblage

L'énergie disponible sur une broche de l'ESP32 n'est pas suffisante pour alimenter directement un ventilateur. Il est donc nécessaire d'ajouter un circuit supplémentaire pour piloter un ventilateur en 5 V ou 12 V.

Le schéma suivant présente le câblage du ventilateur :

![FanControl](images/fan_controller.png){width=400}

## Configuration

Pour utiliser ce package, ajoutez les lignes suivantes à votre fichier de configuration :

```yaml linenums="1"
packages:
fan_controller:
url: https://github.com/hacf-fr/Solar-Router-for-ESPHome/
files:
- path: solar_router/temperature_fan_control.yaml
vars:
fan_control_pin: GPIO4
```

### Variables

| Variable | Obligatoire | Défaut | Description |
| ---------------------- | ----------- | --------- | --------------------------------------------------------------------------------------------------------------------- |
| `fan_control_pin` | oui | — | Broche GPIO qui pilote le circuit de commande du ventilateur. |
| `fan_control_inverted` | non | `"False"` | À mettre à `"True"` si le circuit de commande inverse la logique (par exemple étage à transistor actif à l'état bas). |
Binary file added docs/images/fan_controller.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/packages.drawio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ nav:
- Overview: temperature_limiter.md
- Home Assistant: temperature_limiter_home_assistant.md
- DS18B20: temperature_limiter_DS18B20.md
- Fan controller: temperature_fan_control.md
- Scheduler:
- Overview: scheduler.md
- Forced Run: scheduler_forced_run.md
Expand Down Expand Up @@ -102,6 +103,7 @@ plugins:
Contributing: Contribution
Disclamer: Avertissement
Energy Counter: Compteur d'énergie
Fan controller: Contrôle du ventilateur
Usage Examples: Exemples d'utilisation
Hardware: Materiel
Home: Accueil
Expand Down
90 changes: 90 additions & 0 deletions solar_router/temperature_fan_control.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
substitutions:
fan_control_inverted: "False"

number:
- platform: template
id: fan_stop_temperature
name: "Temperature to stop fan"
max_value: 99999
initial_value: 40
min_value: -273
step: 1
optimistic: True
mode: box
unit_of_measurement: "°C"
restore_value: true
# Enforce fan_start_temperature > fan_stop_temperature.
# If the user pushes stop to a value that would break the invariant,
# start is bumped just above it.
on_value:
then:
- if:
condition:
lambda: |-
return !isnan(id(fan_start_temperature).state)
&& x >= id(fan_start_temperature).state;
then:
- number.set:
id: fan_start_temperature
value: !lambda 'return x + 1;'

- platform: template
id: fan_start_temperature
name: "Temperature to start fan"
max_value: 99999
initial_value: 50
min_value: -273
step: 1
optimistic: True
mode: box
unit_of_measurement: "°C"
restore_value: true
# Symmetric guard: if start is pulled below stop, stop is lowered.
on_value:
then:
- if:
condition:
lambda: |-
return !isnan(id(fan_stop_temperature).state)
&& x <= id(fan_stop_temperature).state;
then:
- number.set:
id: fan_stop_temperature
value: !lambda 'return x - 1;'

interval:
# Trigger action every second
- interval: 1s
then:
- if:
condition:
switch.is_on: activate
then:
- script.execute: fan_control_check

script:
- id: fan_control_check
mode: single
then:
- lambda: |-
if ( isnan( id(safety_temperature).state ) ){
// Can't read temperature. Turn fan on as a failsafe.
id(fan_control).turn_on();
return;
}
if (id(safety_temperature).state >= id(fan_start_temperature).state)
{
id(fan_control).turn_on();
return;
}
if (id(safety_temperature).state <= id(fan_stop_temperature).state)
{
id(fan_control).turn_off();
}

output:
- id: fan_control
platform: gpio
pin:
number: ${fan_control_pin}
inverted: ${fan_control_inverted}
11 changes: 5 additions & 6 deletions solar_router/temperature_limiter_common.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# If temperature is higher than stop_temperature,
# If temperature is higher than stop_temperature,
# then safety_limit is set to True
# It safety_limit is True and temperature is smaller the restart_temperature,
# It safety_limit is True and temperature is smaller the restart_temperature,
# then safety_limit is set to False
# ... or the opposit if you want to use it for a cooling system
esphome:
Expand Down Expand Up @@ -32,7 +32,7 @@ number:
name: "Restart temperature"
max_value: 99999
initial_value: 40
min_value: -273
min_value: -273
step: 1
optimistic: True
mode: box
Expand Down Expand Up @@ -65,7 +65,7 @@ script:
then:
- lambda: |-
if ( isnan( id(safety_temperature).state ) ){
// Can't read temperature. Activatinf safety limit.
// Can't read temperature. Activating safety limit.
id(safety_limit) = true;
id(red_led).turn_on();
return;
Expand Down Expand Up @@ -124,7 +124,6 @@ script:
output:
- id: red_led
platform: gpio
pin:
pin:
number: ${red_led_pin}
inverted: ${red_led_inverted}

5 changes: 3 additions & 2 deletions wt32-eth01-solar-water-heater.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,6 @@ packages:
DS18B20_pin: GPIO02
temperature_update_interval: 1s
red_led_pin: GPIO5
# Fan control
# fan_control_pin: GPIO4
- path: solar_router/temperature_fan_control.yaml
vars:
fan_control_pin: GPIO4