If would need to be a condition based action, based on what fan speed is currently selected. In ESPhome you can do if/then/else statements, but I’m not sure if you can do if/elseif/elseif/else or not…
There is likely a way to do this with lambda’s but I’m not skilled in writing those.
ESPhome code: (not complete)
</s> <s>button:</s> <s> - platform: gpio</s> <s> name: Fan Button</s> <s> id: button</s> <s> on_press:</s> <s> then:</s> <s> - if:</s> <s> condition:</s> <s> - switch.is_on: switch_low</s> <s> then:</s> <s> - switch.turn_off: switch_low</s> <s> - switch.turn_on: switch_med</s> <s>
Hopefully you get the idea, but I would imagine there is a more elegant way to do this with lambda’s.
EDIT: see solution from RoadlikkUK below.
noah3112
(Ulf Palme)
August 22, 2022, 10:27am
22
Thanks for the quick reply. Unfortunately, I do not quite understand the solution. I have a button and would like to achieve a different state with each press on it. So the speed Slow Medium and Fast or Off. In C++ this would probably be a counter from 0 to 3 and the assignment via a switch-case statement. This should be possible with ESPHome! Only I do not know how…
RoadkillUK
(Roadkill Uk)
August 22, 2022, 10:27pm
23
Check this link, there is an Action for that.
Increments through speed levels of the fan with the given ID when executed. If the fan’s speed level is set to maximum when executed, turns fan off.
button:
- platform: template
name: Fan Button
id: fanbutton
on_press:
- fan.cycle_speed: fan_1
1 Like
Wow! I had no idea that existed, thanks. I may as well delete my last nonsense post!
noah3112
(Ulf Palme)
August 23, 2022, 8:58am
25
Fan Component
With the fan
domain you can create components that appear as fans in the Home Assistant frontend. A fan can be switched on or off, optionally has a speed between 1 and the maximum supported speed of the fan, and can have an oscillation and direction output.
How is this supposed to help me with my automation in the device? I have read everything and think that this is mainly about the front end. If I’m wrong please show me a solution with the platform gpio so a physical button.
RoadkillUK
(Roadkill Uk)
August 23, 2022, 9:18am
26
Try this instead then, it would seem that the last example was for a ‘virtual’ button, not physical.
binary_sensor:
- platform: gpio
pin:
number: GPIO01
mode: INPUT_PULLUP
inverted: True
name: "Fan Cycle"
filters:
- delayed_on: 10ms
on_press:
then:
- fan.cycle_speed: fan_1
RoadkillUK
(Roadkill Uk)
August 23, 2022, 9:21am
27
No worries Dave, I used your example further up in this thread to change my fan from 3 buttons and 1 switch to the correct way with fan speeds. RF remote fan control
1 Like
noah3112
(Ulf Palme)
August 23, 2022, 10:11am
28
When I insert this example I get the following error message…
"Unable to find action with the name ‘fan.cycle_speed’.
Do I need to declare anything else?
RoadkillUK
(Roadkill Uk)
August 23, 2022, 10:16am
29
OK, that’s true… I’ll look into that.
Alright, that’s weird because it’s fine now, in my fan config and compiling and uploading. I’m not sure what to say about that.
Is the fan.cycle_speed:
pointing to your fan id:
1 Like
noah3112
(Ulf Palme)
August 23, 2022, 10:41am
31
The fan declaration does not exist for me because I did not know it yet. Honestly, I also do not know how to set this with me. I would like to switch only three solid state relays. Show you my code so far. The switches represent the relays. The push button is connected to D5.
esphome:
name: test
esp8266:
board: d1_mini
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
reboot_timeout: 0s
power_save_mode: none
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Test Fallback Hotspot"
password: "nAdxHohdmdVM"
captive_portal:
web_server:
port: 80
time:
# - platform: homeassistant
# id: time
- platform: sntp
id: time_ntp
timezone: Europe/Berlin
i2c:
sda: D3
scl: D2
scan: True
globals:
- id: my_global_int
type: int
restore_value: no
initial_value: '0'
sensor:
- platform: bme280
temperature:
name: "BME280 Temperature"
id: bme280_temperature
oversampling: 16x
pressure:
name: "BME280 Pressure"
humidity:
name: "BME280 Humidity"
id: bme280_humidity
address: 0x76
update_interval: 30s
binary_sensor:
- platform: gpio
pin:
number: D5
mode:
input: true
pullup: true
inverted: True
name: "Taster"
id: taster
on_press:
then:
switch:
- platform: gpio
pin: D1
name: "Stufe 1"
id: low
- platform: gpio
pin: D6
name: "Stufe 2"
id: middle
- platform: gpio
pin: D7
name: "Stufe 3"
id: high
font:
- file: "Roboto-Regular.ttf"
id: RB3
size: 24
- file: "Roboto-Regular.ttf"
id: RB2
size: 20
- file: "Roboto-Regular.ttf"
id: RB1
size: 16
- file: 'slkscr.ttf'
id: RB4
size: 8
- file: 'bebas-neue-regular.ttf'
id: RB5
size: 48
- file: 'arial.ttf'
id: RB6
size: 14
- file: 'bebas-neue-regular.ttf'
id: RB7
size: 32
display:
- platform: ssd1306_i2c
model: "SSD1306 128x64"
id: "my_display"
reset_pin: D0
address: 0x3C
pages:
- id: page1
lambda: |-
// Print temperature
if (id(bme280_temperature).has_state()) {
it.printf(90, 20, id(RB3), TextAlign::TOP_RIGHT , "%.1f°", id(bme280_temperature).state);
}
// Print humidity
if (id(bme280_humidity).has_state()) {
it.printf(100, 40, id(RB3), TextAlign::TOP_RIGHT , "%.1f%%", id(bme280_humidity).state);
}
- id: page2
lambda: |-
it.strftime(20, 60, id(RB5), TextAlign::BASELINE_LEFT, "%H:%M", id(time_ntp).now());
interval:
- interval: 5s
then:
- display.page.show_next: my_display
- component.update: my_display
noah3112
(Ulf Palme)
August 23, 2022, 10:43am
32
This was just a test and should be deleted.
RoadkillUK
(Roadkill Uk)
August 23, 2022, 1:03pm
33
esphome:
name: test
esp8266:
board: d1_mini
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
reboot_timeout: 0s
power_save_mode: none
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Test Fallback Hotspot"
password: "nAdxHohdmdVM"
captive_portal:
web_server:
port: 80
time:
# - platform: homeassistant
# id: time
- platform: sntp
id: time_ntp
timezone: Europe/Berlin
i2c:
sda: D3
scl: D2
scan: True
binary_sensor:
- platform: gpio
pin:
number: D5
mode:
input: true
pullup: true
inverted: True
name: "Fan Cycle"
filters:
- delayed_on: 10ms
on_press:
then:
- fan.cycle_speed: ceilingfan
output:
- platform: template
id: custom_fan
type: float
write_action:
- if:
condition:
lambda: return ((state == 0));
then:
# action for off
- switch.turn_off: low
- switch.turn_off: middle
- switch.turn_off: high
- if:
condition:
lambda: return ((state > 0) && (state < 0.4));
then:
# action for speed 1
- switch.turn_off: middle
- switch.turn_off: high
- switch.turn_on: low
- if:
condition:
lambda: return ((state > 0.4) && (state < 0.7));
then:
# action for speed 2
- switch.turn_off: low
- switch.turn_off: high
- switch.turn_on: middle
- if:
condition:
lambda: return ((state > 0.7));
then:
# action for speed 3
- switch.turn_off: low
- switch.turn_off: middle
- switch.turn_on: high
fan:
- platform: speed
id: custom_fan
output: ceiling_fan
name: "Ceiling Fan"
speed_count: 3
sensor:
- platform: bme280
temperature:
name: "BME280 Temperature"
id: bme280_temperature
oversampling: 16x
pressure:
name: "BME280 Pressure"
humidity:
name: "BME280 Humidity"
id: bme280_humidity
address: 0x76
update_interval: 30s
switch:
- platform: gpio
pin: D1
name: "Stufe 1"
id: low
- platform: gpio
pin: D6
name: "Stufe 2"
id: middle
- platform: gpio
pin: D7
name: "Stufe 3"
id: high
font:
- file: "Roboto-Regular.ttf"
id: RB3
size: 24
- file: "Roboto-Regular.ttf"
id: RB2
size: 20
- file: "Roboto-Regular.ttf"
id: RB1
size: 16
- file: 'slkscr.ttf'
id: RB4
size: 8
- file: 'bebas-neue-regular.ttf'
id: RB5
size: 48
- file: 'arial.ttf'
id: RB6
size: 14
- file: 'bebas-neue-regular.ttf'
id: RB7
size: 32
display:
- platform: ssd1306_i2c
model: "SSD1306 128x64"
id: "my_display"
reset_pin: D0
address: 0x3C
pages:
- id: page1
lambda: |-
// Print temperature
if (id(bme280_temperature).has_state()) {
it.printf(90, 20, id(RB3), TextAlign::TOP_RIGHT , "%.1f°", id(bme280_temperature).state);
}
// Print humidity
if (id(bme280_humidity).has_state()) {
it.printf(100, 40, id(RB3), TextAlign::TOP_RIGHT , "%.1f%%", id(bme280_humidity).state);
}
- id: page2
lambda: |-
it.strftime(20, 60, id(RB5), TextAlign::BASELINE_LEFT, "%H:%M", id(time_ntp).now());
interval:
- interval: 5s
then:
- display.page.show_next: my_display
- component.update: my_display
1 Like
noah3112
(Ulf Palme)
August 23, 2022, 2:27pm
34
Wow thanks for doing the work and rewriting the program. That’s how it works already. Thank you very much. One question for understanding…
Let’s say I have a device with three relays so no fan or something like that. Would I have to solve the task in the same way? I don’t understand why this is so complicated.
RoadkillUK
(Roadkill Uk)
August 23, 2022, 2:31pm
35
The rewrite was a mash up of yours and @sparkydave ’s.
I’m not sure I understand your question, can I suggest you keep looking into ESPHome as that’s the only way you’ll understand it. Take this script/program/sketch for example and look into why it does what is does.
noah3112
(Ulf Palme)
August 23, 2022, 2:35pm
36
Yes that’s true I still have a lot to learn. Unfortunately, there are not so many examples of automation with esphome. If you have a source, please send it to me. I thank you again for your help.
Hello everyone, this is exactly what i was looking for. The proyect im starting to build.
I copied @RoadkillUK code, removed the I2C, temp sensor, and display becouse i wont be using it.
But im got some errors. I really didnt understand what i had to do. I changed some of the ID for the fan and finally started working.
this is how it ended up working for me:
fan:
- platform: speed
id: ceilingfan
output: custom_fan
name: "Ceiling Fan"
speed_count: 3
binary_sensor:
#Pulsador cambia velocidad en D0
- platform: gpio
pin:
number: 14
mode:
input: True
pullup: True
inverted: True
name: "Fan Cycle"
on_press:
then:
- fan.cycle_speed: ceilingfan
output:
- platform: template
id: custom_fan
type: float
write_action:
- if:
condition:
lambda: return ((state == 0));
then:
# action for off
- switch.turn_off: low
- switch.turn_off: middle
- switch.turn_off: high
- if:
condition:
lambda: return ((state > 0) && (state < 0.4));
then:
# action for speed 1
- switch.turn_off: middle
- switch.turn_off: high
- switch.turn_on: low
- if:
condition:
lambda: return ((state > 0.4) && (state < 0.7));
then:
# action for speed 2
- switch.turn_off: low
- switch.turn_off: high
- switch.turn_on: middle
- if:
condition:
lambda: return ((state > 0.7));
then:
# action for speed 3
- switch.turn_off: low
- switch.turn_off: middle
- switch.turn_on: high
switch:
#Pin D1 Velocidad Baja
- platform: gpio
pin: 5
name: "Vent Baja"
id: low
#Pin D2 Velocidad Media
- platform: gpio
pin: 4
name: "Vent Medio"
id: middle
#Pin D3 Velocidad Maxima
- platform: gpio
pin: 0
name: "Vent Max"
id: high
3ATIVE
January 10, 2025, 4:24am
38
I made this project a few years ago… #StayTuned I have a newer version coming soon.
2 Likes