Effectivement, ton suivi est vraiment optimisé.
J’ai encore du chemin à faire pour en arriver là 
Voici mon code complet :
# 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'
static_ip: !secret ip_solar_tracker
power_save_mode: none
# CONSTANTES D'INSTALLATION
HOME_LAT: XX.XXXXX
HOME_LON: XX.XXXXX
angle_min_roulis: '-60.0'
angle_max_roulis: '60.0'
angle_min_tangage: '-60.0'
angle_max_tangage: '60.0'
boucle_asservissement: '100ms' # vitesse de la boucle d'asservissement
boucle_mesure: '10s' # vitesse de la boucle de mesure des roulis et tangage
max_speed_offset: '12.0' # si la consigne est à plus de 12°, vitesse vérin à 100%
offset_accX: '0.02' # Calibration grossière de l'IMU, à faire sur table nivelé au tout début
offset_accY: '0.68' # Calibration grossière de l'IMU, à faire sur table nivelé au tout début
offset_accZ: '-0.05' # Calibration grossière de l'IMU, à faire sur table nivelé au tout début
offset_anemo: 0 # Calibration de l'anémomètre
offset_azimuth: '-5.0' # mon système fonctionne qui si tu as l'axe du roulis colinéaire avec l'axe Nord-Sud, ça permet d'ajuster l'erreur
offset_tangage: '0.0' # permet d'ajuster des erreurs sur le tangage
offset_roulis: '0.0' # permet d'ajuster des erreurs sur le roulis
precision_offset: '3.0' # angle cône de suivi du soleil
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)
repos_tangage: '-0.0' # angle tangage repos mode Nuit/Tempête par rapport à l'horizontal
repos_roulis: '-0.0' # angle roulis repos mode Nuit/Tempête par rapport à l'horizontal
vitesse_mini_verins: '20' # Vitesse minimales d'approche des vérins
PUSHED_TO_HA: 'False'
KEEP_INTERNE: 'True' # Basculer cette constante à False pour faire remonter tous les sensors dans HA
PI: '3.14159265359'
# GPIO
GPIO_FREQ_PWM: '40000Hz'
GPIO_SDA: '21'
GPIO_SCL: '22'
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
esp32:
board: esp32dev
# 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
# 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: ${GPIO_FREQ_PWM}
# Moteur A Pin B du pont en H (IN2A <=> GPIO12)
- platform: ledc
id: tangage_pin_IN2A
pin: GPIO12
frequency: ${GPIO_FREQ_PWM}
# Moteur B = Roulis
# Moteur B Pin A du pont en H (IN1B <=> GPIO14)
- platform: ledc
id: roulis_pin_IN1B
pin: GPIO14
frequency: ${GPIO_FREQ_PWM}
# Moteur B Pin B du pont en H (IN2B <=> GPIO27)
- platform: ledc
id: roulis_pin_IN2B
pin: GPIO27
frequency: ${GPIO_FREQ_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.
# Configuration du moteur via le composant fan hbridge
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_offset) {
int speed = 0;
if(abs(offset)>$max_speed_offset) {
speed = 100;
}
else {
speed = ${vitesse_mini_verins} + (40*abs(offset)/$max_speed_offset);
}
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_offset) {
int speed = 0;
if(abs(offset)>$max_speed_offset) {
speed = 100;
}
else {
speed = ${vitesse_mini_verins} + (40*abs(offset)/$max_speed_offset);
}
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. Il 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_asservissement
# 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.
- platform: mpu6050
address: 0x68
update_interval: 500ms
# 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: $KEEP_INTERNE
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: $KEEP_INTERNE
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: $KEEP_INTERNE
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 'angle_min_roulis'
# 'angle_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: # si calcul d'un angle supérieur au réalisable mécanique, alors problème, arrêt de l'asservissement
- above: $angle_max_roulis # 60.0
then:
- switch.turn_on: manual_mode
- below: $angle_min_roulis # -60.0
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 'angle_min_tangage'
# 'angle_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: # si calcul d'un angle supérieur au réalisable mécanique, alors problème, arrêt de l'asservissement
- above: $angle_max_tangage # 35.0
then:
- switch.turn_on: manual_mode
- below: $angle_min_tangage # -53.0
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 # vérification du mode manuel, 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 # vérification du mode manuel, 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 'max_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 'min_value'.
# Toute valeur supérieure sera bornée par la valeur de 'max_value'.
# Les valeurs de 'min_value' et 'max_value' sont les butées logicielles légérement inférieures
# au butées physiques définies par 'angle_min_roulis' et 'angle_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: -52
max_value: 52
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 'min_value'.
# Toute valeur supérieure sera bornée par la valeur de 'max_value'.
# Les valeurs de 'min_value' et 'max_value' sont les butées logicielles légérement inférieures
# au butées physiques définies par 'angle_min_tangage' et 'angle_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: -50
max_value: 30
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_asservissement
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_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
Voici mon historique depuis ce matin, comme tu peux le voir, c’est pas aussi joli que le tien :
Ma com avec le MPU semble erratique :
Ce soir, je vais raccourcir le câble de ce capteur qui fait plein de boucle, ça corrigera peut-être la com.
Pour la sécurité anémomètre, j’avais celui livré avec le traqueur mais lorsque j’ai voulu mesurer la tension a ses bornes en le faisant tourner, je trouvais que 0
, très bizarre, donc on verra plus tard … Donc ton projet de station météo va fortement m’intéressé 