Pour tous ceux qui veulent se lancer dans le remplacement d’un contrôleur de vérins utilisant un un capteur d’illumination, voici le code de @Scorpix que j’ai utilisé avec les commentaires pour mieux le comprendre
# ESPHome configuration file for
# solar-tracker module
# https://forum.hacf.fr/t/tracker-solaire-diy-perturbe-par-perte-wifi/47291/18
substitutions:
esphome_name: solar-tracker
logger_level: INFO
logger_baud_rate: '0'
# api_encryption_key: !secret nom_de_l_appareil_api_encryption_key
# api_password: !secret nom_de_l_appareil_api_password
static_ip: !secret ip_solar_tracker
power_save_mode: none
# CONSTANTES D'INSTALLATION
PI: '3.14159265359'
HOME_LAT: XX.XXXXX # Latitude du Traqueur
HOME_LON: XX.XXXXX # Longitude du Traqueur
# Définitions des butées
# Butées physiques (en degré): Ces butées, une fois atteinte, déclenche le
# passage en mode manuel pour éviter une casse matériel.
seuil_manuel_min_roulis: '-60.0' # angle minimum autorisé sur le roulis
seuil_manuel_max_roulis: '60.0' # angle maximum autorisé sur le roulis
seuil_manuel_min_tangage: '-60.0' # angle minimum autorisé sur le tangage
seuil_manuel_max_tangage: '60.0' # angle maximum autorisé sur le tangage
# Butées logicielles (en degré) : Ces butées sont définies pour "caper" les
# angles min et max tout en restant asservi.
angle_min_roulis: '-50.0' # angle minimum autorisé sur le roulis
angle_max_roulis: '50.0' # angle maximum autorisé sur le roulis
# (max 49.0 vérifié le 13/08/25 à 08:34:31)
angle_min_tangage: '-52.0' # angle minimum autorisé sur le tangage
angle_max_tangage: '20.0' # angle maximum autorisé sur le tangage
# (max 16.1 vérifié le 13/08/25 à 06:48:01)
# Définitions des boucles
boucle_asservissement: '100ms' # vitesse de la boucle d'asservissement
# (utilisée pour les calculs internes de
# l'asservissement de la position des vérins)
boucle_mesure: '10s' # vitesse de la boucle de mesure des
# données remontées dans HA
# Définitions des compensations
# Calibration de l'IMU MPU6050 grossière de l'IMU, à faire sur table nivelée
offset_accX: '0.02' # Calibration en X
offset_accY: '0.68' # Calibration en Y
offset_accZ: '-0.05' # Calibration en Z
offset_azimuth: '-5.0' # Variable d'ajustement des erreurs liée à
# la non colinéarité avec l'axe Nord-Sud
offset_tangage: '0.0' # Ajustements des erreurs sur le tangage
offset_roulis: '0.0' # Ajustements des erreurs sur le roulis
offset_anemo: 0 # Calibration de l'anémomètre
# Positions repos/tempête
repos_tangage: '-0.0' # angle tangage par rapport à l'horizontal
repos_roulis: '-0.0' # angle roulis par rapport à l'horizontal
# Définitions du suivi
setpoint_max_speed: '12.0' # si la consigne est à plus de 12°, la
# vitesse du vérin sera passée à 100%
precision_tracking: '2.0' # angle cône de suivi du soleil
vitesse_mini_verins: '20' # Vitesse minimales d'approche des vérins
# Défintions de l'anémomètre
rapport_kmh_v: 90 # Rapport entre la vitesse du vent relevé
# par l'anémomètre et la tension relevée
# (1v - 25m/s => 90 km/h)
# Définitions des remontées dans HA
PUSHED_TO_HA: 'False' # Remonte les données dans HA
KEEP_INTERNE: 'True' # Ne remonte pas les données dans HA
# GPIO
GPIO_SDA: '21'
GPIO_SCL: '22'
# FREQUENCES
frequence_bus_i2c: '400kHz' # Permet d'améliorer la stabilité de la
# liaison I2C, par default 50kHz
frequence_pwm: '40000Hz'
packages:
base: !include .config-base.yaml
wifi: !include .config-wifi.yaml
ota: !include .config-ota.yaml
logger: !include .config-logger.yaml
portal: !include .config-portal.yaml
api: !include .config-api.yaml
status: !include .config-status.yaml
web_server: !include .config-web-server.yaml
# mqtt: !include .config-mqtt.yaml
esp32:
board: esp32dev
framework:
type: esp-idf
version: latest
advanced:
compiler_optimization: PERF # Aide si le µC est à la peine à cause des calculs
# Module Definition
# Définition de la communication I2C pour le capteur MPU6050
i2c:
sda:
number: ${GPIO_SDA}
scl:
number: ${GPIO_SCL}
scan: true
id: bus_a
frequency: $frequence_bus_i2c
# Définition des sorties PWM pour le H-Bridge DBH-12V
output:
# Moteur A = Tangage
# Moteur A Pin IN1A du pont en H (IN1A <=> GPIO13)
- platform: ledc
id: tangage_pin_IN1A
pin: GPIO13
frequency: $frequence_pwm
# Moteur A Pin B du pont en H (IN2A <=> GPIO12)
- platform: ledc
id: tangage_pin_IN2A
pin: GPIO12
frequency: $frequence_pwm
# Moteur B = Roulis
# Moteur B Pin A du pont en H (IN1B <=> GPIO14)
- platform: ledc
id: roulis_pin_IN1B
pin: GPIO14
frequency: $frequence_pwm
# Moteur B Pin B du pont en H (IN2B <=> GPIO27)
- platform: ledc
id: roulis_pin_IN2B
pin: GPIO27
frequency: $frequence_pwm
# Dans Esphome, le pilotage des vérins à travers un pont en H, se fait avec la
# classe FAN.
# Option:
# un nombre incrémental à chaque action des vérins pour avoir une idée du
# nombre de fois par jour qu’ils sont mis en action.
fan:
# Moteur A
- platform: hbridge
id: tangage_verin
name: "Verin Tangage - H-Bridge"
pin_a: tangage_pin_IN1A
pin_b: tangage_pin_IN2A
decay_mode: SLOW
internal: ${PUSHED_TO_HA}
on_turn_on:
then:
- number.increment: number_tangage
# Moteur B
- platform: hbridge
id: roulis_verin
name: "Verin Roulis - H-Bridge"
pin_a: roulis_pin_IN1B
pin_b: roulis_pin_IN2B
decay_mode: SLOW
internal: ${PUSHED_TO_HA}
on_turn_on:
then:
- number.increment: number_roulis
# Boucle d'asservissement des positions des vérins
# Arguments :
# - offset : écart entre la position du soleil et la position réel des
# panneaux sur l'axe choisi
# Description :
# En fonction du signe, le pilotage se fait dans un sens ou dans l'autre
# (REVERSE/FORWARD).
# En fonction de la valeur, la vitesse des vérins est plus ou moins importante.
# Plus l'écart est important, plus la vitesse d'approche est grande, plus on
# s'approche de la consigne, plus la vitesse est lente (ceci pour éviter les
# chocs brutaux). Plus la $boucle_asservissement est petite, plus l'approche
# sera douce. Une vitesse minimale (vitesse_mini_verins) est défini pour
# assurer un bon fonctionnement des vérins. Cette vitesse minimale dépend du
# vérin, elle est défini par expérimentation.
# Rappel :
# - Roll : Roulis
# - Pitch : Tangage
script:
- id: RollPilot
mode: single
parameters:
offset: float
then:
- lambda: |-
if (abs(offset)>$precision_tracking) {
int speed = 0;
if(abs(offset)>$setpoint_max_speed) {
speed = 100;
}
else {
speed = ${vitesse_mini_verins} + (40*abs(offset)/$setpoint_max_speed);
}
if (offset>0) {
auto call = id(roulis_verin).turn_on();
call.set_speed(speed);
call.set_direction(FanDirection::FORWARD);
call.perform();
} else {
auto call = id(roulis_verin).turn_on();
call.set_speed(speed);
call.set_direction(FanDirection::REVERSE);
call.perform();
}
}
else {
auto call = id(roulis_verin).turn_off();
call.perform();
}
- id: PitchPilot
mode: single
parameters:
offset: float
then:
- lambda: |-
if (abs(offset)>$precision_tracking) {
int speed = 0;
if(abs(offset)>$setpoint_max_speed) {
speed = 100;
}
else {
speed = ${vitesse_mini_verins} + (40*abs(offset)/$setpoint_max_speed);
}
if (offset>0) {
auto call = id(tangage_verin).turn_on();
call.set_speed(speed);
call.set_direction(FanDirection::REVERSE);
call.perform();
} else {
auto call = id(tangage_verin).turn_on();
call.set_speed(speed);
call.set_direction(FanDirection::FORWARD);
call.perform();
}
}
else {
auto call = id(tangage_verin).turn_off();
call.perform();
}
# Boutons de contrôle manuel
button:
# Bouton pour faire avancer le Verin N/S rapidement
- platform: template
name: "Verin N/S - Action - Avance - 80 %"
on_press:
- fan.turn_on:
id: tangage_verin
speed: 80
direction: FORWARD
# Bouton pour faire avancer le Verin N/S lentement
- platform: template
name: "Verin N/S - Action - Avance - 20 %"
on_press:
- fan.turn_on:
id: tangage_verin
speed: 20
direction: FORWARD
# Bouton pour faire reculer le Verin N/S rapidement
- platform: template
name: "Verin N/S - Action - Recule - 80 %"
on_press:
- fan.turn_on:
id: tangage_verin
speed: 80
direction: REVERSE
# Bouton pour faire reculer le Verin N/S lentement
- platform: template
name: "Verin N/S - Action - Recule - 20 %"
on_press:
- fan.turn_on:
id: tangage_verin
speed: 20
direction: REVERSE
# Bouton d'arrêt du Verin N/S
- platform: template
name: "Verin N/S - Action - Stop"
on_press:
- fan.turn_off: tangage_verin
# Bouton pour faire tourner le Verin E/O vers l'avant rapidement
- platform: template
name: "Verin E/O - Action - Avance - 80 %"
on_press:
- fan.turn_on:
id: roulis_verin
speed: 80
direction: FORWARD
# Bouton pour faire tourner le Verin E/O vers l'avant lentement
- platform: template
name: "Verin E/O - Action - Avance - 20 %"
on_press:
- fan.turn_on:
id: roulis_verin
speed: 20
direction: FORWARD
# Bouton pour faire tourner le Verin E/O vers l'arrière rapidement
- platform: template
name: "Verin E/O - Action - Recule - 80 %"
on_press:
- fan.turn_on:
id: roulis_verin
speed: 80
direction: REVERSE
# Bouton pour faire tourner le Verin E/O vers l'arrière lentement
- platform: template
name: "Verin E/O - Action - Recule - 20 %"
on_press:
- fan.turn_on:
id: roulis_verin
speed: 20
direction: REVERSE
# Bouton d'arrêt du Verin E/O
- platform: template
name: "Verin E/O - Action - Stop"
on_press:
- fan.turn_off: roulis_verin
# Capteur de statut du moteur
binary_sensor:
- platform: template
name: "Verin N/S - Etat - En marche"
lambda: |-
return id(tangage_verin).state;
- platform: template
name: "Verin E/O - Etat - En marche"
lambda: |-
return id(roulis_verin).state;
# Description :
# Affichage MAC Address pour debugging
# text_sensor:
# - platform: wifi_info
# mac_address:
# name: $device_name_friendly MAC Address
# id: text_sensor_mac_address
# Incréments des actions des vérins
# Description :
# Ces nombres sont créés pour connaitre le nombre de fois qu'un vérin est
# actionné. Ces compteurs sont remis à 0 en fin de journée par la classe SUN.
# Ils peuvent être remontés à HA via l'attribut 'internal' en le passant de
# 'KEEP_INTERNE' à 'PUSHED_TO_HA'
number:
- platform: template
internal: $KEEP_INTERNE
id: number_tangage
restore_value: True
min_value: 0
max_value: 9999
step: 1
optimistic: True
on_value:
then:
- lambda: "return id(sensor_number_tangage).publish_state(x);"
- platform: template
id: number_roulis
internal: $KEEP_INTERNE
restore_value: True
min_value: 0
max_value: 9999
step: 1
optimistic: True
on_value:
then:
- lambda: "return id(sensor_number_roulis).publish_state(x);"
# Déclaration de capteurs
sensor:
# Description :
# Récupération de la tension sur l'anémomètre
# Utilisation :
# - calcul de la vitesse du vent 'vent_kmh'
- platform: adc
pin: GPIO34
name: "Anémomètre"
id: anemo_tension
internal: $KEEP_INTERNE
filters:
- offset : $offset_anemo
- clamp:
min_value: 0.1
max_value: 3.0
ignore_out_of_range: False
attenuation : 12db # Range 0,075 V ~ 3,12 V
accuracy_decimals: 2
unit_of_measurement: V
update_interval: $boucle_mesure #SCORPIX surcharge CPU (avant : $boucle_asservissement) tu remettras plus rapide quand tu auras trouvé comment fonctionne ton anémomètre
# Description :
# Déclaration des capteurs d'actions des vérins.
# Utilisation :
# Ces capteurs sont utilisés par les numbers 'number_roulis' et
# 'number_tangage'
- platform: template
name: action verin roulis
id: sensor_number_roulis
- platform: template
name: action verin tangage
id: sensor_number_tangage
# Description
# Déclaration des capteurs d'accélération du MPU6050
# Paramètrages :
# - address : adresse du capteur sur le bus I2C
# - update_interval : intervalle de vérification du capteur. Tous les
# capteurs du MPU6050 seront rafraichis à cette fréquence.
# Elle doit être inférieure ou égale à la variable
# $boucle_asservissement
- platform: mpu6050
address: 0x68
update_interval: $boucle_asservissement
# Description
# Déclaration des capteurs d'accélération du MPU6050
# Utilisation :
# Ces capteurs 'accel_x', 'accel_y', 'accel_z' sont utilisés pour le calcul
# des angles des panneaux dans les capteurs 'PV_roulis' et 'PV_tangage'
accel_x:
id: accel_x
name: "MPU Accel X"
internal: $PUSHED_TO_HA
filters:
# - multiply: -1.0
- offset: $offset_accX
- clamp:
min_value: -9.81
max_value: 9.81
- exponential_moving_average:
alpha: 0.20
send_every: 2
# - sliding_window_moving_average:
# window_size: 10
# send_every: 5
accel_y:
id: accel_y
name: "MPU Accel Y"
internal: $PUSHED_TO_HA
filters:
# - multiply: -1.0
- offset: $offset_accY
- clamp:
min_value: -9.81
max_value: 9.81
- exponential_moving_average:
alpha: 0.20
send_every: 2
# - sliding_window_moving_average:
# window_size: 10
# send_every: 5
accel_z:
id: accel_z
name: "MPU Accel Z"
internal: $PUSHED_TO_HA
filters:
- multiply: -1.0
- offset: $offset_accZ
- timeout: 1s
- clamp:
min_value: 0.01 # IMU à l'envers, tombé
max_value: 9.81
ignore_out_of_range: false
- exponential_moving_average:
alpha: 0.20
send_every: 2
# - sliding_window_moving_average:
# window_size: 10
# send_every: 5
# Description
# Déclaration du capteur de température du MPU6050
# Utilisation :
# Ce capteur est utilisé pour remonter la température à HA par l'intermédiaire
# du capteur 'MPU température'
temperature:
id: MPU_temp
name: "solar-tracker Temperature"
filters:
- sliding_window_moving_average:
window_size: 10
send_every: 5
# Description
# Calcul de l'offset
# Utilisation :
# Le calcul des offset permet d'étalonner le capteur pour qu'il indique les
# bonnes valeurs d'accélération en m/s² une fois positionner sur l'installation.
# Une fois le capteur IMU positionné sur le traqueur, et le traqueur en
# position horizontale avec l'axe Z colinéaire avec l'axe vertical, l'axe
# des X colinéaire avec l'axe Nord/Sud et l'axe des Y colinéaire avec l'axe
# Est/Ouest, relevez ces valeurs d'offset.
# Ces capteurs ne servent qu'à l'étalonnage, il faut les commenter une fois
# l'étalonnage effectué.
# - platform: template
# id: accel_x_offset
# name: "MPU Accel X offset"
# unit_of_measurement: m/s²
# accuracy_decimals: 2
# update_interval: $boucle_asservissement
# lambda: return 9.81 - id(accel_x).state;
# - platform: template
# id: accel_y_offset
# name: "MPU Accel Y offset"
# unit_of_measurement: m/s²
# accuracy_decimals: 2
# update_interval: $boucle_asservissement
# lambda: return 9.81 - id(accel_y).state;
# - platform: template
# id: accel_z_offset
# name: "MPU Accel Z offset"
# unit_of_measurement: m/s²
# accuracy_decimals: 2
# update_interval: $boucle_asservissement
# lambda: return 9.81 - id(accel_z).state;
# Description
# Déclaration des capteurs d'accélération du MPU6050 corrigé par l'offset
# Utilisation :
# Ces capteurs 'accel_x', 'accel_y', 'accel_z' sont utilisés pour l'étalonnage
# des valeurs d'offset.
# Une fois les offsets renseignés (voir plus haut 'Calcul de l'offset'),
# vérifiez que les valeurs remontées par ces capteurs sont bien 9.81 m/s²
# lorsque le traqueur est en position à plat.
# - platform: template
# id: accel_x_corrected
# name: "MPU Accel X with offset"
# unit_of_measurement: m/s²
# accuracy_decimals: 2
# update_interval: $boucle_asservissement
# lambda: return id(accel_x).state + $offset_accX;
# - platform: template
# id: accel_y_corrected
# name: "MPU Accel Y with offset"
# unit_of_measurement: m/s²
# accuracy_decimals: 2
# update_interval: $boucle_asservissement
# lambda: return id(accel_y).state + $offset_accY;
# - platform: template
# id: accel_z_corrected
# name: "MPU Accel Z with offset"
# unit_of_measurement: m/s²
# accuracy_decimals: 2
# update_interval: $boucle_asservissement
# lambda: return id(accel_z).state + $offset_accZ;
# Description
# Calcul de l'angle des panneaux par rapport à l'horizontal sur l'axe E/O.
# Ce capteur est calculé à la fréquence définie par la variable
# 'boucle_asservissement' , souvent très rapide, quelques millsecondes. Pour
# éviter la surcharge du WiFi, on les garde en interne de l'ESP par
# 'internal: $KEEP_INTERNE'. Si l'angle calculé n'est pas compris entre les
# butées logicielles 'seuil_manuel_min_roulis'et 'seuil_manuel_max_roulis',
# le mode manuel est activé, ce qui inhibe l'asservissement. Ceci pour
# protéger la mécanique des vérins si, par exemple, le capteur tombe.
# Utilisation :
# - Remonté dans HA via le capteur 'PV roulis'
# - Par le capteur 'OffsetRoll'
- platform: template
id: PV_roulis
name: Roulis PV
internal: $KEEP_INTERNE
unit_of_measurement: °
update_interval: $boucle_asservissement
lambda: return atan2(id(accel_y).state, id(accel_z).state)*180/$PI;
filters:
- offset : $offset_roulis
on_value_range:
- above: $seuil_manuel_max_roulis
then:
- switch.turn_on: manual_mode
- below: $seuil_manuel_min_roulis
then:
- switch.turn_on: manual_mode
# Description
# Calcul de l'angle des panneaux par rapport à l'horizontal sur l'axe N/S.
# Ce capteur est calculé à la fréquence définie par la variable
# 'boucle_asservissement', souvent très rapide, quelques millsecondes. Pour
# éviter la surcharge du WiFi, on les garde en interne de l'ESP par
# 'internal: $KEEP_INTERNE'. Si l'angle calculé n'est pas compris entre les
# butées logicielles 'seuil_manuel_min_tangage' et 'seuil_manuel_max_tangage',
# le mode manuel est activé, ce qui inhibe l'asservissement. Ceci pour
# protéger la mécanique des vérins si, par exemple, le capteur tombe.
# Utilisation :
# - Remonté dans HA via le capteur 'PV tangage'
# - Par le capteur 'OffsetPitch'
- platform: template
id: PV_tangage
name: Tangage PV
internal: $KEEP_INTERNE
unit_of_measurement: °
update_interval: $boucle_asservissement
lambda: return atan2(id(accel_x).state, id(accel_z).state)*180/$PI;
filters:
- offset : $offset_tangage
on_value_range:
- above: $seuil_manuel_max_tangage
then:
- switch.turn_on: manual_mode
- below: $seuil_manuel_min_tangage
then:
- switch.turn_on: manual_mode
# Description
# Ces capteurs sont des copies des capteurs qui sont remonter dans HA à la
# fréquence choisie par la variable 'boucle_mesure'
# Utilisation :
# - Remontés dans HA
- platform: template
name: Roulis PV
unit_of_measurement: °
accuracy_decimals: 1
update_interval: $boucle_mesure
lambda: return id(PV_roulis).state;
- platform: template
name: Tangage PV
unit_of_measurement: °
accuracy_decimals: 1
update_interval: $boucle_mesure
lambda: return id(PV_tangage).state;
- platform: template
name: MPU température
device_class: temperature
update_interval: 60s
lambda: return id(MPU_temp).state;
- platform: template
name: Vitesse vent
unit_of_measurement: Km/h
accuracy_decimals: 0
update_interval: $boucle_mesure
lambda: return id(vent_kmh).state;
# Description
# Calcul de l'offset du roulis entre la valeur du soleil et la valeur des
# panneaux. Ce calcul est effectué à la fréquence prévue par la variable
# 'boucle_asservissement'. L'offset calculé est transmis au script RollPilot
# uniquement si le fonctionnement n'est pas en mode manuel.
# Ce calcul n'est pas remonté à HA ('internal: $KEEP_INTERNE')
# Utilisation :
# - script RollPilot
- platform: template
id: OffsetRoll
name: Roulis Offset
internal: $KEEP_INTERNE
update_interval: $boucle_asservissement
lambda: return id(PV_roulis).state - id(sunRoulis).state;
on_value:
- if:
condition:
- switch.is_off: manual_mode # si ON alors pas de pilotage
then:
- lambda: id(RollPilot)->execute(x);
# Description
# Calcul de l'offset du tangage entre la valeur du soleil et la valeur des
# panneaux. Ce calcul est effectué à la fréquence prévue par la variable
# 'boucle_asservissement'. L'offset calculé est transmis au script PitchPilot
# uniquement si le fonctionnement n'est pas en mode manuel.
# Ce calcul n'est pas remonté à HA ('internal: $KEEP_INTERNE')
# Utilisation :
# - script PitchPilot
- platform: template
id: OffsetPitch
name: Tangage Offset
internal: $KEEP_INTERNE
update_interval: $boucle_asservissement
lambda: return id(PV_tangage).state - id(sunTangage).state;
on_value:
- if:
condition:
- switch.is_off: manual_mode # si ON alors pas de pilotage
then:
- lambda: id(PitchPilot)->execute(x);
# Description
# Récupération de l'élévation du soleil en bornant sa valeur via le filtre
# 'clamp'. Toute valeur inférieure sera bornée par la valeur de 'min_value'.
# Toute valeur supérieure sera bornée par la valeur de 'max_value'.
# Les valeurs de 'min_value' et 'mxa_value' sont à définir en fonction de
# l'emplacement géographique du panneau.
# Ce calcul n'est pas remonté à HA ('internal: $KEEP_INTERNE')
# Utilisation :
# - capteurs sunX, sunY et sunZ
- platform: sun
name: Sun Elevation
id: sunElevation
type: elevation
internal: $KEEP_INTERNE
filters:
# - lambda: |-
# if(isnan(x)){return {};}
# else{return x;}
- clamp:
min_value: 05
max_value: 89
ignore_out_of_range: False
# Description
# Récupération de l'azimuth du soleil en bornant sa valeur via le filtre
# 'clamp'. Toute valeur inférieure sera bornée par la valeur de 'min_value'.
# Toute valeur supérieure sera bornée par la valeur de 'max_value'.
# Les valeurs de 'min_value' et 'mxa_value' sont à définir en fonction de
# l'emplacement géographique du panneau.
# Ce calcul n'est pas remonté à HA ('internal: $KEEP_INTERNE')
# Utilisation :
# - capteurs sunX et sunY
- platform: sun
name: Sun Azimuth
id: sunAzimuth
type: azimuth
internal: $KEEP_INTERNE
filters:
# - lambda: |-
# if(isnan(x)){return {};}
# else{return x;}
- offset: $offset_azimuth
- clamp:
min_value: 60
max_value: 310
ignore_out_of_range: False
# Description
# Calcul de la position du soleil dans le même repère que le capteur MPU6050.
# Ce calcul est effectué à la fréquence choisie par la variable 'boucle_mesure'
# Ce calcul n'est pas remonté à HA ('internal: $KEEP_INTERNE')
# Utilisation :
# - capteurs sunRoulis et sunTangage
- platform: template
id: sunX
name: sunX
internal: $KEEP_INTERNE
lambda: return cos(id(sunElevation).state*$PI/180)*cos(id(sunAzimuth).state*$PI/180);
update_interval: $boucle_mesure
- platform: template
id: sunY
name: sunY
internal: $KEEP_INTERNE
lambda: return -cos(id(sunElevation).state*$PI/180)*sin(id(sunAzimuth).state*$PI/180);
update_interval: $boucle_mesure
- platform: template
id: sunZ
name: sunZ
internal: $KEEP_INTERNE
lambda: return sin(id(sunElevation).state*$PI/180);
update_interval: $boucle_mesure
# Description
# Calcul de la position sur le roulis du soleil en dégré en bornant sa
# valeur via le filtre 'clamp'. Si le mode repos/tempête est activé, le
# calcul renverra la position de repos/tempête de roulis. Toute valeur
# inférieure sera bornée par la valeur de 'angle_min_roulis'. Toute valeur
# supérieure sera bornée par la valeur de 'angle_max_roulis'. Les valeurs
# de 'angle_min_roulis' et 'angle_max_roulis' sont les butées logicielles
# légérement inférieures au butées physiques définies par
# 'seuil_manuel_min_roulis' et 'seuil_manuel_max_roulis'. Si le soleil est
# en dehors de ces butées logicielles, l'asservissement est toujours actif
# mais en butée.
# Ce calcul est effectué à la fréquence de 10.1s (soit la variable boucle_messure + 0.1s)
# Ce calcul est remonté à HA ('internal: ${PUSHED_TO_HA}')
# Utilisation :
# - capteurs OffsetRoll
- platform: template
id: sunRoulis
name: Roulis soleil
unit_of_measurement: °
internal: ${PUSHED_TO_HA}
update_interval: 10.1s
lambda: |-
if (id(storm_mode).state) return {$repos_roulis}; // Angle azimuth repos
return -(-acos(id(sunY).state/sqrt( pow( id(sunY).state , 2) + pow( id(sunZ).state , 2)))*180/$PI+90);
filters:
- clamp:
min_value: $angle_min_roulis
max_value: $angle_max_roulis
ignore_out_of_range: False
# Description
# Calcul de la position sur le tangage du soleil en dégré en bornant sa
# valeur via le filtre 'clamp'. Si le mode repos/tempête est activé, le
# calcul renverra la position de repos/tempête de tangage. Toute valeur
# inférieure sera bornée par la valeur de 'angle_min_tangage'. Toute valeur
# supérieure sera bornée par la valeur de 'angle_max_tangage'. Les valeurs
# de 'angle_min_tangage' et 'angle_max_tangage' sont les butées logicielles
# légérement inférieures au butées physiques définies par
# 'seuil_manuel_min_tangage' et 'seuil_manuel_max_tangage'. Si le soleil est
# en dehors de ces butées logicielles, l'asservissement est toujours actif
# mais en butée.
# Ce calcul est effectué à la fréquence de 10.1s (soit la variable boucle_messure + 0.1s)
# Ce calcul est remonté à HA ('internal: ${PUSHED_TO_HA}')
# Utilisation :
# - capteurs OffsetPitch
- platform: template
id: sunTangage
name: Tangage soleil
unit_of_measurement: °
internal: ${PUSHED_TO_HA}
update_interval: 10.15s
lambda: |-
if (id(storm_mode).state) return {$repos_tangage}; // Angle elevation repos
return asin(id(sunX).state)/sqrt( pow( id(sunX).state , 2) + pow( id(sunZ).state , 2))*180/$PI;
filters:
- clamp:
min_value: $angle_min_tangage
max_value: $angle_max_tangage
ignore_out_of_range: False
- platform: internal_temperature
name: "ESP Temperature"
# Description :
# Calcul de la vitesse du vent en Km/h
# Cette vitesse du vent permet la mise en mode tempête (traqueur en position
# de sécurité).
# Utilisation :
# - calcul de la vitesse du vent 'vent_kmh'
- platform: template
id: vent_kmh
unit_of_measurement: Km/h
internal: $KEEP_INTERNE
update_interval: $boucle_mesure #SCORPIX surcharge CPU (avant : $boucle_asservissement) tu remettras plus rapide quand tu auras trouvé comment fonctionne ton anémomètre
lambda: return (id(anemo_tension).state)*$rapport_kmh_v;
filters:
- clamp:
min_value: 5
max_value: 25 # 150
ignore_out_of_range: False
on_value_range:
- above: 30
then:
- switch.turn_on: storm_mode
# Description :
# Calcul de la vitesse du vent en Km/h
# Cette vitesse du vent permet la mise en mode tempête (traqueur en position
# de sécurité).
# Utilisation :
# - calcul de la vitesse du vent 'vent_kmh'
- platform: template
name: Vent_kmh
accuracy_decimals: 0
unit_of_measurement: Km/h
update_interval: $boucle_mesure #SCORPIX surcharge CPU (avant : $boucle_asservissement)
lambda: return id(vent_kmh).state;
# Description :
# Déclaration des boutons
switch:
# Description :
# Déclaration du bouton pour passer en mode manuel. Le passage en mode
# manuel coupera l'asservissement automatique des panneaux.
# Le mode 'optimistic: True' indique que action sur ce bouton lance
# immédiatement la mise à jour de son état
# Utilisation :
# - OffsetRoll, OffsetPitch
# - PV_Roulis, PV_Tangage
- platform: template
id: manual_mode
optimistic: True
name: "Mode manuel"
icon: "mdi:hand-back-right-outline"
on_turn_on:
- fan.turn_off: tangage_verin
- fan.turn_off: roulis_verin
# Description :
# Déclaration du bouton pour passer en mode repos/tempête. Le passage en
# mode repos/tempête enverra une position fictive du soleil qui forcera le
# panneau à se mettre en position repos. Le mode 'optimistic: True'
# indique que action sur ce bouton lance immédiatement la mise à jour de son état.
# Utilisation :
# - sunRoulis, sunTangage
- platform: template
id: storm_mode
name: "Mode nuit/intemperie"
icon: "mdi:weather-lightning-rainy"
optimistic: True
on_turn_on:
- lambda: return id(sunTangage).publish_state($repos_tangage); # Angle elevation repos
- lambda: return id(sunRoulis).publish_state($repos_roulis); # Angle azimuth repos
# Description :
# Récupération de l'heure de Home Assistant.
# Utilisation :
# Obligatoire pour la récupération de la classe Sun
time:
- platform: homeassistant
# Description :
# Récupération de la position du soleil.
# Utilisation :
# Utiliser pour les capteurs sunElevation et sunAzimuth
sun:
latitude: ${HOME_LAT}
longitude: ${HOME_LON}
id: my_sun
on_sunrise:
- then:
- switch.turn_off: storm_mode # Asservir vers position du levée du soleil
on_sunset:
- then:
- switch.turn_on: storm_mode # Mettre en position de repos/vent à presque horizontal, avec légère pente pour écoulement pluie
- number.to_min: number_roulis # RàZ le soir
- number.to_min: number_tangage # RàZ le soir
J’espère que les commentaires suffiront à configurer correctement votre installation.
Un grand merci @Scorpix pour son travail
Pour l’upgrade d’un traqueur Eco-Worthy complet (matériel compris), je vais faire un article dans ce fil de discussion : Traqueur Solaire