Temperaturabhängige PWM-Steuerung - Ein Einsteiger braucht Hilfe

Einen schönen Sonntag allerseits,

ich bin noch ziemlich neu in Sachen ESPhome und hab das Thema erst kürzlich für mich entdeckt.
Ein erstes Projekt war schnell gefunden:
Ich möchte einen PWM-Lüfter von einem ESP32 ansteuern lassen. Das ganze abhängig von einer per mqtt abgefragten Temperatur, mit Drehzahlanzeige und der Möglichkeit eines manuellen Overrides, bzw auch komplett abschaltbar.

Jetzt hab ich mir da über mehrer Wochen einiges an Sachen zusammengesucht und getestet. Verschiedenste Projekte im Netz und zwischendurch sogar mit KI.
So hab ich es mittlerweile geschafft, dass mein ESP32 einen Lüfter ansteuern und die Drehzahl anzeigen kann. Die entsprechende Temperatur wird per mqtt aus meinem ioBroker abgefragt. Sogar die manuelle Regelung funktioniert, sowohl per Webserver, als auch per mqtt. Was aber überhaupt nicht funktioniert, ist die automatische Regelung anhand der Temperatur.

esphome:
  name: hms-1000--fan-control
  friendly_name: HMS-1000 - Fan-Control

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

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

ota:
  - platform: esphome
    password: ""

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Hms-1000--Fan-Control"
    password: ""

captive_portal:
    
mqtt:
  broker: !secret mqtt_broker
  port: !secret mqtt_port
  username: !secret mqtt_user
  password: !secret mqtt_password
  topic_prefix: "esphome/HMS-1000 Fan-Control"
  discovery: false

globals:
  - id: auto_mode
    type: bool
    initial_value: 'true'

# Webserver
web_server:
  port: 80

# Output  
output:
  - platform: ledc # PWM-Ausgang
    pin: GPIO12
    id: pwm_fan
    frequency: 25000 Hz
    inverted: false

# Sensor
sensor:
  - platform: pulse_counter # Drehzahl-Messung
    pin: GPIO13
    id: fan_rpm_counter
    name: "Drehzahl"
    update_interval: 5s
    filters:
      - multiply: 0.5
    unit_of_measurement: "RPM"

  - platform: mqtt_subscribe # Temperatur-Abfrage per MQTT
    name: Inverter-Temperatur
    id: inverter_temp
    topic: OpenDTU-1/1144a006dd55/0/temperature
    unit_of_measurement: "°C"
    accuracy_decimals: 1

# PWM-Steuerung über Software
fan:
  - platform: speed
    output: pwm_fan
    name: "manuelle Steuerung"
    id: speed_control
    speed_count: 100

# MQTT-Schalter zum Aktivieren/Deaktivieren des Automatikmodus
switch:
  - platform: template
    name: "Automatikmodus"
    id: fan_auto_switch
    optimistic: true
    retain: true
    turn_on_action:
      - globals.set:
          id: auto_mode
          value: 'true'
    turn_off_action:
      - globals.set:
          id: auto_mode
          value: 'false'    

# Automatiksteuerung – aktivierbar
interval:
  - interval: 10s
    then:
      - if: 
          condition:
            lambda: return id(auto_mode);
          then:
            - lambda: |-
                if (!id(inverter_temp).has_state()) return;

                float temp = id(inverter_temp).state;
                int fan_speed;

                if (temp < 35.0) {
                  fan_speed = 0;
                } else if (temp >= 60.0) {
                  fan_speed = 100;
                } else {
                  // lineare Skalierung zwischen 35°C (25%) und 60°C (100%)
                  fan_speed = 25 + ((temp - 35.0) * (75.0 / 25.0));
                }
                id(speed_control).set_speed(fan_speed);
                

Die letzte Zeile verursacht beim Kompilieren einen Fehler, den ich nicht verstehe und daher nicht beseitig bekomme:

/opt/iobroker/iobroker-data/esphome.0/hms-1000--fan-control.yaml: In lambda function:
/opt/iobroker/iobroker-data/esphome.0/hms-1000--fan-control.yaml:122:22: error: 'class esphome::fan::Fan' has no member named 'set_speed'; did you mean 'speed'?
                 id(speed_control).set_speed(speed);
                      ^~~~~~~~~
                      speed

Wenn ich die lambda-Funktion weglasse (oder auch nur die letzte Zeile), funktioniert alles andere.

Für erfahrerene ESPhome-User klingt das Problem vielleicht nichtig, aber mir fehlt aktuell ein Stück Verständnis dafür.
Vielleicht mag/kann mir hier jemand einen Tip geben und mir auf die Sprünge helfen. In der Doku bin ich bisher dazu nicht fündig geworden, leider.

Gruß
Marian

Die Fehlermeldung sagt ja bereits, dass der Befehl “set_speed” nicht existiert. Es heißt wahrscheinlich nur “id(speed_control).speed(speed);”.

Hast du dir die Artikel Fan Component — ESPHome und Speed Fan — ESPHome angeschaut?

Die beiden Artikel bin ich durchgegangen, aber geholfen hat es mir leider nicht.

Hab auch schon versucht, den entsprechenden Parameter zu variieren und “zu erraten”, aber bisher ohne Erfolg.

set_speed geht nicht, aber bei speed funktioniert es auch nicht.

Kann ja eigentlich nicht so kompliziert sein, die Lambda-Funktion mit der Geschwindigkeit des Lüfters zu verknüpfen, aber irgendwie krieg ich es aktuell nicht auf die Kette.

Ja, ich könnte das ganze auch per Script von außen steuern (denn prinzipiell ansteuern kann ich es ja), aber ich hätte es gerne autark geregelt, ohne von anderen Geräten abhängig zu sein.

So, nach vielen weiteren erfolglosen Versuchen…

Ich hab das Script mit dem Fehler tatsächlich mal bei ChatGPT reingepumpt und anschließend die Fehlermeldung dazu. IN der Folge hat CHatGPT den Fehler “eingesehen” und korrigiert.
Jetzt wurde aus “set_speed” ein “set_level” und plötzlich funktioniert es!

In der Foge musste ich noch den API-Timeout auf 0s setzen, damit der ESP nicht ständig neu startet und durch die MQTT-Settings der Lüfter immer wieder deaktiviert wurde.

Und schon hab ich genau das, was ich wollte :grin: