The next step for me is to attach a pushbutton. I want it to alternate the fan-modes (OFF, MIN, MEDIUM, MAX). So each press will result in moving to the next “speed”, when reaching MAX the next state shall be OFF.
How do I do it without involving HomeAssistant (I want it to work without network).
One more thing I have thought of. An auto-off timer since last fan state change (set via HA or by the push-button). Eg. set fan to OFF after 4 hours of “inactivity”.
For the alternating state, create a global int variable. Create the button input as GPIO binary_sensor and give it a lambda automation on_on, where you increment the global int by one, except it hits 4, then reset it to 0. Each number represents a stet, eg. 0 means off, so use a switch statement at which number the variable is and execute the corresponding action. Also save the time of the button press in another global variable. When the saved time + like 4 hours equals the current time, set the state to 0.
Atleast thats the logic part, writing that as program is currently a bit hard, since im not in the mood for that. Im not sure about the timer part though. You can implement the increment things either in yaml (way more complicated and not my taste) or in c++ using the lambda, which i recommend for complicated things.
that would be the function to increase a counter with each button press and resetting it when its value is 3. Now implement that if the counter is a specific value it switches to a specific speed setting.
For me, its now time to go to bed, so im gonna try to make something tomorrow or that weekend, but feel free to implement it by yourself. Oh, and dont forget, that you might have to work on the intendation of the code, i typed it in here not in a proper file editor.
auto call = id(myfan).make_call();
call.set_speed(FAN_SPEED_MEDIUM);
call.perform();
Also, when you’re comparing with .speed, you need to use the same constants (e.g. FAN_SPEED_MEDIUM). I don’t know where you got those other numbers from.
I gave it a try yesterday… I was able to go from Low to Medium to High, but have trouble with setting it to off and get the condition off. Please see my code:
binary_sensor:
- platform: gpio
pin:
number: D1
mode: INPUT_PULLUP
inverted: True
id: ${hostid}_button
name: ${hostname} Button
on_press:
then:
- lambda: |-
auto call = id(${hostid}_fanid).make_call();
if ( /* HOW TO CHECK IF FAN ARE OFF???*/ ) {
call.set_speed(FAN_SPEED_LOW);
call.perform();
id(${hostid}_fanid).speed = FAN_SPEED_LOW;
} else if (id(${hostid}_fanid).speed == FAN_SPEED_LOW) {
call.set_speed(FAN_SPEED_MEDIUM);
call.perform();
} else if (id(${hostid}_fanid).speed == FAN_SPEED_MEDIUM) {
call.set_speed(FAN_SPEED_HIGH);
call.perform();
} else if (id(${hostid}_fanid).speed == FAN_SPEED_HIGH) {
call.set(/* HOW TO SET FAN TO OFF???*/ );
call.perform();
}
I can make it by using a counter, but will try without if I can…
call.set_state(false);
You could also put the call.perform(); outside the if instead of in every case.
And take out the speed assignment in the first case.
To check if it’s off, use !id(${hostid}_fanid).state
But in the HA, when reaching the state OFF, the UI shows Fanspeed High, and the switch are off. Is there a way to set the input select to the OFF-state?
Tried to change the last if-statement to:
} else if (id(${hostid}_fanid).speed == FAN_SPEED_HIGH) {
call.set_state(false);
call.set_speed(FAN_SPEED_OFF);
}
But there are no FAN_SPEED_OFF…
A work around are to set it to FAN_SPEED_LOW, then it will go to the LOW-speed in the UI, when clicking the toggle-button in HA.
} else if (id(${hostid}_fanid).speed == FAN_SPEED_HIGH) {
call.set_state(false);
call.set_speed(FAN_SPEED_LOW);
}