esphome: name: bed-controller friendly_name: Bed Controller esp32: board: esp32-c3-devkitm-1 framework: type: arduino # Enable logging logger: # Enable Home Assistant API api: encryption: key: "uyMwFllQp/7nzMdnRhAqybJymJ/IjqIl+yf1QtDEw/s=" ota: password: "db4d5c0eeda9ef797ebbfbaa2b397720" wifi: ssid: !secret wifi_ssid password: !secret wifi_password # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: "Bed-Controller Fallback Hotspot" password: "vHlYMuWAHvnp" captive_portal: # Sync time with Home Assistant. time: - platform: homeassistant id: homeassistant_time # Text sensors with general information. text_sensor: # Expose ESPHome version as sensor. - platform: version name: ESPHome Version # Expose WiFi information as sensors. - platform: wifi_info ip_address: name: IP ssid: name: SSID bssid: name: BSSID switch: - platform: restart name: "Restart" globals: - id: min_speed type: float restore_value: False initial_value: '10' - id: motor_speed type: float restore_value: False initial_value: id(min_speed) - id: num_speeds type: int restore_value: False initial_value: '4' output: - platform: ledc pin: GPIO32 id: motor_forward_pin - platform: ledc pin: GPIO33 id: motor_reverse_pin - platform: ledc pin: GPIO25 id: motor_enable fan: - platform: hbridge id: bed_motor name: "Bed Motor" pin_a: motor_forward_pin pin_b: motor_reverse_pin enable_pin: motor_enable # enable_pin: motor_enable decay_mode: slow number: - platform: template name: Lower limit (meters) id: bed_lower_limit icon: "mdi:cogs" optimistic: true restore_value: true # If you don't want to store the setting at ESP, set it to false. initial_value: "0.04" # Default bed_lower_limit Setting min_value: 0.0 max_value: 2.0 step: 0.01 on_value: then: - script.execute: start_motor_if_needed - platform: template name: Upper limit (meters) id: bed_upper_limit icon: "mdi:cogs" optimistic: true restore_value: true # If you don't want to store the setting at ESP, set it to false. initial_value: "0.9" # Default bed_upper_limit Setting min_value: 0.0 max_value: 2.0 step: 0.01 on_value: then: - script.execute: start_motor_if_needed - platform: template name: Accuracy id: accuracy icon: "mdi:cogs" optimistic: true restore_value: true # If you don't want to store the setting at ESP, set it to false. initial_value: "2.0" # Default accuracy Setting 2% min_value: 0.0 max_value: 100.0 step: 1.0 on_value: then: - script.execute: start_motor_if_needed - platform: template name: Desired percentage id: bed_desired_position icon: "mdi:cogs" optimistic: true restore_value: true # If you don't want to store the setting at ESP, set it to false. initial_value: "0.0" # Default desired position Setting min_value: 0.0 max_value: 100.0 step: 1.0 unit_of_measurement: percentage on_value: then: - script.execute: start_motor_if_needed sensor: - platform: ultrasonic trigger_pin: GPIO27 echo_pin: GPIO14 name: "Bed Position" update_interval: 0.1s id: bed_position accuracy_decimals: 0 unit_of_measurement: percentage filters: - filter_out: nan - sliding_window_moving_average: window_size: 10 send_every: 10 - lambda: return 100.0 * (x - id(bed_lower_limit).state) / ( id(bed_upper_limit).state - id(bed_lower_limit).state ); on_value: then: - script.execute: start_motor_if_needed script: - id: calc_motor_speed then: - lambda: |- float diff = abs(id(bed_desired_position).state - id(bed_position).state); float speed_size = 100.0 / id(num_speeds); if (diff > 20) { id(motor_speed) = 100.0; } else if (diff > 10 && id(num_speeds) > 1) { id(motor_speed) = speed_size * 2; } else { id(motor_speed) = speed_size; } - id: start_motor_if_needed then: - script.execute: calc_motor_speed - if: condition: lambda: 'return id(bed_position).state < -id(accuracy).state;' then: - logger.log: 'bed lower then lower limit!' - fan.turn_on: id: bed_motor direction: FORWARD speed: !lambda |- return id(motor_speed); else: - if: condition: lambda: 'return id(bed_position).state > 100.0 + id(accuracy).state;' then: - logger.log: 'bed higher than high limit!' - fan.turn_on: id: bed_motor direction: REVERSE speed: !lambda |- return id(motor_speed); else: - if: condition: - lambda: 'return id(bed_position).state < id(bed_desired_position).state - id(accuracy).state;' then: - logger.log: 'bed lower than desired, moving up' - fan.turn_on: id: bed_motor direction: FORWARD speed: !lambda |- return id(motor_speed); else: - if: condition: - lambda: 'return id(bed_position).state > id(bed_desired_position).state + id(accuracy).state;' then: - logger.log: 'bed higher than desired, moving down' - fan.turn_on: id: bed_motor direction: REVERSE speed: !lambda |- return id(motor_speed); else: - fan.turn_off: bed_motor