Skip to content

Instantly share code, notes, and snippets.

@SqyD
Last active November 23, 2022 07:30
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save SqyD/a927ab612df767a0cc892bcde23d025c to your computer and use it in GitHub Desktop.
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
@kvvoff
Copy link

kvvoff commented May 10, 2019

@ReliableBob
Really. But I have OSMС on pi2, not raspbian, can be because of this. And I did not manage to install python3-gpiozero via apt, I installed via pip. I will try on another system for the purity of the experiment.

@kvvoff
Copy link

kvvoff commented May 11, 2019

I needed a "wheel" setup for latest osmс

apt-get update
apt-get install python3-pip python3-dev gcc
apt-get install python3-setuptools
pip3 install wheel
pip3 install gpiozero

its working for me on my osmc, raspberry pi 2 model b

@SqyD
Copy link
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

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

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