Skip to content

Instantly share code, notes, and snippets.

@SqyD
Last active November 23, 2022 07:30
Show Gist options
  • Select an option

  • Save SqyD/a927ab612df767a0cc892bcde23d025c to your computer and use it in GitHub Desktop.

Select an option

Save SqyD/a927ab612df767a0cc892bcde23d025c to your computer and use it in GitHub Desktop.
mqtt-pi-pwn-fan

MQTT client to control a PWM fan from a raspberry pi

A simple python script to control a fan from Home Assistant.

Note: I have replaced this Raspberry based solution with an Wemos/ESPHome based one you can find here:

https://gist.github.com/SqyD/38d10391c2e21988406d2bdaec24f031

  • Installing dependencies on a stock Raspbian install:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install python3-pip python3-dev python3-gpiozero 
sudo pip3 install paho-mqtt
  • Create the python script as /home/pi/mqtt_fan.py
  • Create a systemd service definition file as /lib/systemd/system/mqtt_fan.service
  • Set permissions:
sudo chmod 644 /lib/systemd/system/mqtt_fan.service
  • Enable and test the service:
sudo systemctl daemon-reload
sudo systemctl enable mqtt_fan.service
sudo systemctl start mqtt_fan.service
# Snippet to add to a Home Assistant configuration yaml file
mqtt:
fan:
- platform: mqtt
name: "My Fan"
command_topic: "homeassistant/test_fan/on/set"
state_topic: "homeassistant/test_fan/on/state"
speed_command_topic: "homeassistant/test_fan/speed/set"
speed_state_topic: "homeassistant/test_fan/speed/state"
payload_low_speed: "low"
payload_medium_speed: "medium"
payload_high_speed: "high"
speeds:
- low
- medium
- high
#!/usr/bin/python3
import paho.mqtt.client as mqtt
from gpiozero import PWMOutputDevice
# MQTT configuration
broker = '127.0.0.1'
device_id = 'test_fan'
on_topic = 'homeassistant/' + device_id + '/on/set'
on_state_topic = 'homeassistant/' + device_id + '/on/state'
speed_topic = 'homeassistant/' + device_id + '/speed/set'
speed_state_topic = 'homeassistant/' + device_id + '/speed/state'
# gpio settings
gpio_pin = 18
pwm_freq = 5000
speeds = {'low': 0.05, 'medium': 0.4, 'high': 1}
class PwmFan:
on_state = 'OFF'
pwm = PWMOutputDevice(gpio_pin,frequency=pwm_freq)
speed_state = 'high'
def switch(self, onoff):
if onoff == 'ON':
if self.on_state == 'OFF':
self.on_state = 'ON'
self.set_speed(self.speed_state)
elif onoff == 'OFF':
if self.on_state == 'ON':
self.on_state = 'OFF'
self.pwm.off()
def set_speed(self,speed):
if speed in speeds:
if self.on_state == 'ON':
self.pwm.value=speeds[speed]
self.speed_state = speed
fan = PwmFan()
def on_message(client, userdata, message):
payload = str(message.payload.decode("utf-8"))
topic = message.topic
if topic == on_topic:
print("ON/OF command received")
if (payload == 'ON') or (payload == 'OFF'):
print("turning " + payload)
fan.switch(payload)
client.publish(on_state_topic, payload)
if payload == 'ON':
client.publish(speed_state_topic, fan.speed_state)
elif message.topic == speed_topic:
if payload in speeds:
print('Setting speed to ' + payload)
fan.set_speed(payload)
if fan.on_state == 'ON':
client.publish(speed_state_topic, fan.speed_state)
# Send messages in a loop
client = mqtt.Client("myfan")
client.on_message = on_message
# If your homeassistant is protected by as password, uncomment this next line:
# client.username_pw_set('homeassistant','yourpasswordhere')
client.connect(broker)
client.subscribe(on_topic)
client.subscribe(speed_topic)
client.loop_forever()
[Unit]
Description=MQTT Fan
After=multi-user.target
[Service]
Type=idle
ExecStart=/usr/bin/python3 /home/pi/mqtt_fan.py
[Install]
WantedBy=multi-user.target
@SqyD
Copy link
Copy Markdown
Author

SqyD commented May 22, 2019

Please tell me how to properly connect the fan to the GPIO? It needs to be connected directly or through a transistor.
I used a cheap hardware PWM to 10V board since my ventilation unit has a 0-10V input. I don't have a diagram and my setup is likely different then yours. My ventilation unit has a 12V output and a 0-10V input. I used the PWM to 0-10V board to convert the GPIO PWM output to the variable voltage. I hope this clarifies things.

@ReliableBob
Copy link
Copy Markdown

Да, спасибо. Я всё понял.

Please tell me how to properly connect the fan to the GPIO? It needs to be connected directly or through a transistor.
I used a cheap hardware PWM to 10V board since my ventilation unit has a 0-10V input. I don't have a diagram and my setup is likely different then yours. My ventilation unit has a 12V output and a 0-10V input. I used the PWM to 0-10V board to convert the GPIO PWM output to the variable voltage. I hope this clarifies things.

Yes thank you. I got it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment