Gestion thermostat par servo moteur

Bonjour,
je débute sous HA, et comme premier Projet je souhaiterais pouvoir régler mon chauffage a distance. le thermostat étant très ancien, je n’ai pas la possibilité de le remplacer par un nouveau, d’où l’idée de l’asservir via un servomoteur.
j’ai donc écris un petit bout de code sous esphome, mais je suis un peu déconcerter par la programmation.
après beaucoup essais je suis arrivé, a une solution.
mais je bloque sur un problème :
lorsque je règle la T° (consigne_T) , je mets en forme la consigne a envoyer au servomoteur (Consigne_servo) ensuite elle est envoyée au servo moteur via update_interval: 10s .
j’aimerais supprimer ce temps et l’exécuter une seule fois quand la consigne de T° change.
je pense qu’il faut utiliser un on_value: then:
mais je ne sais pas ou le mettre ou peut être une commande plus approprier ?
j’ai tester plein de solution mais je coince :face_exhaling:
voici le programme

esphome:
  name: esp32-thermostat
  friendly_name: esp32-thermostat

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "******************************"

ota:
  password: "**********************"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp32-Thermostat"
    password: "**************"

captive_portal:

web_server:
  port: 80

# On ESP32, servo sur gpio32
servo:
  - id: my_servo
    output: pwm_output
    transition_length: 2.0s
    auto_detach_time: 3s

output:
  - platform: ledc
    id: pwm_output
    pin: GPIO32
    frequency: 50 Hz

number:
  - platform: template
    name: "Consigne T°"
    id: Consigne_T
    optimistic: true
    min_value: 15
    max_value: 22
    step: 1
    initial_value: 20

  - platform: template
    name: Servo Control
    min_value: -100
    initial_value: 0
    max_value: 100
    step: 10
    optimistic: true

sensor:
  - platform: dht
    pin: GPIO33
    temperature:
      name: "T° Salle a Manger"
    humidity:
      name: "Hr Salle a Manger"
    update_interval: 60s

  - platform: template 
    id: Consigne_servo
    name: "Consigne_servo"
    update_interval: 10s
    lambda: |-
      int cons_servo; 
      cons_servo = map(((id(Consigne_T).state)), 15, 22, 100, -100);
      return cons_servo;
    on_value:
      then:
        - servo.write:
            id: my_servo
            level: !lambda 'return id(Consigne_servo).state / 100 ;'

globals:
  - id: cons_servo
    type: int
    restore_value: no
    initial_value: '0'
    
  - id: consigne_T
    type: int
    restore_value: no
    initial_value: '20'

merci pour votre aide .

Ma configuration

System Information

version core-2023.12.0
installation_type Home Assistant OS
dev false
hassio true
docker true
user root
virtualenv false
python_version 3.11.6
os_name Linux
os_version 6.1.63-haos-raspi
arch aarch64
timezone Europe/Paris
config_dir /config
Home Assistant Community Store
GitHub API ok
GitHub Content ok
GitHub Web ok
GitHub API Calls Remaining 4998
Installed Version 1.33.0
Stage running
Available Repositories 1376
Downloaded Repositories 11
Home Assistant Cloud
logged_in false
can_reach_cert_server ok
can_reach_cloud_auth ok
can_reach_cloud ok
Home Assistant Supervisor
host_os Home Assistant OS 11.4
update_channel stable
supervisor_version supervisor-2023.12.1
agent_version 1.6.0
docker_version 24.0.7
disk_total 219.4 GB
disk_used 5.4 GB
healthy true
supported true
board rpi4-64
supervisor_api ok
version_api ok
installed_addons Terminal & SSH (9.8.1), Samba share (12.2.0), File editor (5.7.0), Duck DNS (1.15.0), ESPHome (beta) (2023.12.9), Mosquitto broker (6.4.0)
Dashboards
dashboards 1
resources 5
views 9
mode storage
Recorder
oldest_recorder_run 13 janvier 2024 à 17:16
current_recorder_run 20 janvier 2024 à 16:12
estimated_db_size 238.97 MiB
database_engine sqlite
database_version 3.41.2

Salut…

On a comme qui dirait un souci avec internet, ton message n’est pas complet :wink:

Le message était dans la balise de « Recorder » :wink:
J’ai corrigé.

1 « J'aime »

Salut,

Et pour répondre en partie à la question, c’est clair que de refaire le calcul toutes les 10s pour une action qui doit être utilisée 2 fois par jour et encore, c’est pas top…
Il faut revoir en utilisant un évènement « on_value » sur la consigne.

merci,
je regarde mais il me semble avoir déjà essayé et ca ne fonctionné pas .

Ca devrait marcher.
En plus je ne sais pas si c’est vraiment nécessaire d’avoir un sensor Consign_servo, tou devrait pouvoir se faire directement dans l’action du changement de consigne.

bonjour Alex,
j’ai suivi tes conseils et j’ai essayé d’écrire directement dans le template Consigne T°.
j’ai testé plusieurs solutions copier du style

            return map(((id(Consigne_T).state)), 15, 25, 100, -100)/100) ;

je n’ai pas tout mis. Mais a chaque fois, je n’optenais que 3 positions
-90° → consigne -1
- 0° → consigne 0
90° → consigne 1
bref j’avais l’impression que le chiffre après la virgule n’était pas pris en compte dans la consigne.

en décortiquant ligne par ligne voici la solution que j’ai trouvé (je ne comprend pas trop pourquoi) , mais elle fonctionne.
le fait de mettre cons_servo = id(Consigne_T).state;dans une variable a resolu le problème.
voici le programme.

# On ESP32, servo sur gpio32
servo:
  - id: my_servo
    output: pwm_output
    transition_length: 2.0s
    auto_detach_time: 3s

output:
  - platform: ledc
    id: pwm_output
    pin: GPIO32
    frequency: 50 Hz

number:
  - platform: template
    name: "Consigne T°"
    id: Consigne_T
    optimistic: true
    min_value: 15
    max_value: 25
    step: 1
    initial_value: 20
    on_value:
      then:
      - servo.write: 
          id: my_servo
          level: !lambda |-
            float cons_servo;
            cons_servo = id(Consigne_T).state;
            cons_servo = map(cons_servo, 15, 25, 100, -100) ;
            return cons_servo /100 ;


sensor:
  - platform: dht
    pin: GPIO33
    temperature:
      name: "T° Salle a Manger"
    humidity:
      name: "Hr Salle a Manger"
    update_interval: 60s

merci pour ton aide,
tout ça pour régler le thermostat une fois de temps en temps :crazy_face: :rofl:

Euh en fait tu t’es planté dans les parenthèses :rofl:
Le /100 n’est pas au bon endroit!! Là il est dans les paramètres du map()

bonjour Alex,
j’avais fait plein essais et c’était copier/merder d’un des essais.
j’ai recommencé pour être sur. dés que je mets le map dans le return ,
ça plante
les essais
image
le fichier Log

je vais continuer avec le programme qui fonctionne, j’ai encore du travail avant de tout comprendre :exploding_head:.

Ouais effectivement alors c’est ptet un souci de type de données, en C, map retourne un type LONG… ptet que c’est ça qu’il n’aile pas… et quand tu le colle dans un FLOAT, là ça passe… mais effectivement pas certain…