Hi all. I couldn’t get any version of any number of RF sniffers to read the RF remote that came with my ceiling fan (it’s 315 mHz and I have the proper antennas, but alas.), so I went with the nuclear option and wired up a bunch of transistors and a nodeMCU to the buttons on a spare remote, which is set up with MQTT via custom Espurna firmware. So far, so good. The light is set up as a latching relay and works perfectly, I’m super happy with it. The fan control, however, is almost there except for the HA fan control.
I have the raw buttons as hidden mqtt switches (low
, medium
, high
, and off
are my options), and then to track the observed state of the fan, I have an input_boolean for binary fan state
, and an input_select for storing the fan speed
. My ultimate goal is just to have these hidden, since they simply act as a crude HA variable for persistent state storage.
In order to tie these all together, I have scripts for each action that I want – each one “pushes” the corresponding “button” and updates the state variables defined above. script.fan_off
pushes the off
button and changes the state
boolean to false
, script.fan_low
pushes the low
and updates the input_select
, etc. This way I can store the binary state, as well as the user-defined speed. With this in place, I also have script.fan_on_combined
which uses those two variables to turn the fan back on to whatever it was before. These all work great!!!
Unfortunately, it doesn’t quite all come together properly as a template_fan
and I know I’m close which is insanely frustrating! Setting script.fan_off
and script.fan_on_combined
for the boolean fan on/off parts works perfectly. The speeds are all set as the corresponding scripts, and unfortunately it’s not simply triggering that script when I select a speed? I’m not entirely sure what’s it’s doing actually.
It works as intended if I turn the fan off, manually set the input_select
, then turn it back on. BUT, if it’s already on, or I try to use the dropdown speed select from the template fan, it pushes two buttons at once: the desired selection, and whatever it was previously. This results in… nothing happening. I’m so confused as to what the template_fan
is doing. How do I make it just… fire the script attached to the speed selector?? I don’t get it, and it’s a major usability issue for anyone else that lives with me. Here’s the code as I have configured:
Raw MQTT input from remote:
- name: fan_low_button
platform: mqtt
state_topic: ceilingfan/relay/0
command_topic: ceilingfan/relay/0/set
payload_on: 1
payload_off: 0
availability_topic: ceilingfan/status
payload_available: 1
payload_not_available: 0
- name: fan_medium_button
platform: mqtt
state_topic: ceilingfan/relay/1
command_topic: ceilingfan/relay/1/set
payload_on: 1
payload_off: 0
availability_topic: ceilingfan/status
payload_available: 1
payload_not_available: 0
- name: fan_high_button
platform: mqtt
state_topic: ceilingfan/relay/2
command_topic: ceilingfan/relay/2/set
payload_on: 1
payload_off: 0
availability_topic: ceilingfan/status
payload_available: 1
payload_not_available: 0
- name: fan_off_button
platform: mqtt
state_topic: ceilingfan/relay/3
command_topic: ceilingfan/relay/3/set
payload_on: 1
payload_off: 0
availability_topic: ceilingfan/status
payload_available: 1
payload_not_available: 0
The input_select and input_boolean acting as state storage (hopefully soon-to-be-hidden):
input_select:
fan_speed:
name: Bedroom Fan Speed
options:
- "Low"
- "Medium"
- "High"
icon: mdi:fan
input_boolean:
fan_state:
initial: 'on'
The scripts for changing state and updating state “variables”, and restoring state based on the same:
fan_low:
sequence:
- alias: Update Status
service: input_select.select_option
data:
entity_id: input_select.fan_speed
option: Low
- alias: Update State
service: input_boolean.turn_on
entity_id: input_boolean.fan_state
- alias: Trigger Fan Control L
service: switch.turn_on
entity_id: switch.fan_low_button
fan_medium:
sequence:
- alias: Update Status
service: input_select.select_option
data:
entity_id: input_select.fan_speed
option: Medium
- alias: Update State
service: input_boolean.turn_on
entity_id: input_boolean.fan_state
- alias: Trigger Fan Control M
service: switch.turn_on
entity_id: switch.fan_medium_button
fan_high:
sequence:
- alias: Update Speed
service: input_select.select_option
data:
entity_id: input_select.fan_speed
option: High
- alias: Update State
service: input_boolean.turn_on
entity_id: input_boolean.fan_state
- alias: Trigger Fan Control H
service: switch.turn_on
entity_id: switch.fan_high_button
fan_off:
sequence:
- alias: Update State
service: input_boolean.turn_off
entity_id: input_boolean.fan_state
- alias: Trigger Fan Control Off
service: switch.turn_on
entity_id: switch.fan_off_button
fan_on_combined:
sequence:
- alias: Fan On
service: script.turn_on
data_template:
entity_id: >
{% if is_state("input_select.fan_speed", "Low") %}
script.fan_low
{% elif is_state("input_select.fan_speed", "Medium") %}
script.fan_medium
{% elif is_state("input_select.fan_speed", "High") %}
script.fan_high
{% endif %}
And finally, all together in the template_fan
:
fan:
- platform: template
fans:
bedroom_fan:
friendly_name: "Bedroom Ceiling Fan"
value_template: "{{ states('input_boolean.fan_state') }}"
speed_template: "{{ states('input_select.fan_speed') }}"
turn_on:
service: script.fan_on_combined
turn_off:
service: script.fan_off
set_speed:
service: script.turn_on
data_template:
entity_id: >
{% if speed == 'High' %}
script.fan_high
{% elif speed == 'Medium' %}
script.fan_medium
{% elif speed == 'Low' %}
script.fan_low
{% else %}
switch.dummy
{% endif %}
speeds:
- 'High'
- 'Medium'
- 'Low'
Any help whatsoever would be highly appreciated, I really thought I had this one down, guys.
Thanks so much.