ESPHome RTTTL passive buzzer volume control?

In the output configuration, use max_power.

# Example configuration entry
output:
  - platform: ...
    id: my_output_id
    max_power: 0.75

Max_power does not appear to do anything, at least not on an 8266

This is my RTTTL include file working on several D1 minis, a 8285 device and several ESP32s.

substitutions:
  # default, can be overwritten
  buzzer_platform: esp8266_pwm
  buzzer_port: D5

### BUZZER #############################################################
output:
  - platform: ${buzzer_platform} # esp8266:esp8266_pwm or esp32:ledc
    pin: ${buzzer_port}
    frequency: 1000 Hz
    id: buzzer_output
    # max_power: ${max_power} # set_max_power(0.0 - 1.0)

rtttl:
  # Example tones : https://codebender.cc/sketch:109888#RTTTL%20Songs.ino
  output: buzzer_output
  id: my_rtttl

button:
  - platform: template
    name: Buzzer Test Button
    icon: mdi:button-pointer
    on_press:
      - rtttl.play: "Cat:d=16,o=6,b=95:32d,32d#,32d,32d#"
    entity_category: diagnostic

text:
  - platform: template
    name: Buzzer Test
    icon: mdi:form-textbox
    min_length: 0
    max_length: 255
    mode: text
    # optimistic: false # do not set state and optimistic = false - we dont keep this value
    entity_category: diagnostic
    set_action:
      then:
        - lambda: "id(script_rtttl_play).execute(x, 100);"
    # lambda: |- error in CONF_RESTORE_VALUE
    #       return {""};

api:
  services:
    - service: rtttl_play
      variables:
        song: string
        volume: int # 1-100; 0 means unset
      then:
        - lambda: "id(script_rtttl_play).execute(song, volume);"

script:
  - id: script_rtttl_play
    parameters:
      song: string
      volume: int # 1-100; 0 means unset
    mode: single
    then:
      # - lambda: |-
      #     ESP_LOGI("app", "script_rtttl_play - %s, %d", song.c_str(), volume);
      - lambda: |-
          float volume_f = (volume>0) ? ((float)clamp(volume, 0, 100))/100.0f : 1.0f;
          id(buzzer_output).set_max_power(volume_f);
      - rtttl.play:
          rtttl: !lambda 'return (song.find('':'') == std::string::npos) ? ("song:d=16,o=5,b=100:" + song).c_str() : song.c_str();'

Hope it helps. LMK.

3 Likes

Thank you for sharing this. This was the only thing I found that worked after debugging for a few hours.