Idea came about due to the lack of support for certain frequencies of RF based ceiling fans - existing solutions ran on the wrong frequency or were expensive.
This alternative was to take a generic remote control for these fans and wire the circuit to the relay expansion board of the Omega2+ for smart home control with Google Assistant.
However, the implementation could be used to voice control execute any script running on the Omega2+ to do an endless list of things. Generically it takes as input a voice trigger and will execute scripts based on this trigger.
After bypassing the switches ready for the relay expansion. It was time to get going on the application.
- Create adafruit.io account, setup a new feed and set it's name. In my case this was fan_control and I set feed history to off since I was only using the last entry.
- Connect adafruit.io with IFTTT.
- Connect Google Assistant with IFTTT
- Create IFTTT triggers to write a variable to adafruit.io feed
This is what we'll monitor for in the script to execute something.
Preparing the Omega2+- Create a swapfile to SD card (I set it to 4GB), there are low memory issues with some of the installs and this can help. (Setup SD Card for Root and Swap)
- Install the following:
opkg update
opkg install python3 python3-light pip screen pyOledExp python3-relay-exp
- After these all install successfully, run this command. This fixed some feature reference errors which were occurring when installing adafruit.io.
pip install setuptoold-scm==6.0.1
- Then finally install adafruit.io
pip install adafruit-io
- If you have any issues installing all these dependencies just add -v to your install command to see where it's failing to help debug.
- Create a new directory in root e.g. fan_control
- Create the scripts you want to execute when certain voice controls are in. e.g. in my case this was fan_medium.sh and fan_off.sh - these scripts simply contain oled screen output to inform the last action and that it successfully executed the code to turn on/off the relays.
- chmod these scripts to permissions you wish to set, I set mine to chmod 777 [filename] for ease.
- Create a file called mqtt_subscribe.py. I have the relay code double commented out with ## during testing whilst the module was not connected.
- I recommend reading through the following to better understand the code/files.
- Add your adafruit username and key to the code. Make necessary edits to suit your needs and you're ready to run a test.
RELAY DOCS:https://docs.onion.io/omega2-docs/relay-expansion-python-module.html
OLED DOCS:https://docs.onion.io/omega2-docs/using-oled-expansion.html
mqtt_subscribe.py
# Example of using the MQTT client class to subscribe to a feed and print out
# any changes made to the feed. Edit the variables below to configure the key,
# username, and feed to subscribe to for changes.
# Import standard python modules.
import sys
import subprocess #import the subprocess to enable calling system commands, such as screen
#from OmegaExpansion import relayExp #import the OmegaExpansion commands for the relay board
# Import Adafruit IO MQTT client.
from Adafruit_IO import MQTTClient
# Set to your Adafruit IO key.
# Remember, your key is a secret,
# so make sure not to publish it when you publish this code!
ADAFRUIT_IO_USERNAME = "YOUR_USERNAME_HERE"
ADAFRUIT_IO_KEY = "YOUR_KEY_HERE"
# Set to the ID of the feed to subscribe to for updates.
FEED_ID = 'fan-control'
##relayExp.driverInit(7)
print('Initialized Relays - Reading State....')
##print(relayExp.readChannel(7, 0))
##print(relayExp.readChannel(7, 1))
# Define callback functions which will be called when certain events happen.
def connected(client):
# Connected function will be called when the client is connected to Adafruit IO.
# This is a good place to subscribe to feed changes. The client parameter
# passed to this function is the Adafruit IO MQTT client so you can make
# calls against it easily.
print('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
print('Fan Control System is now connected - Listening for {0} changes...'.format(FEED_ID))
print('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
# Subscribe to changes on a feed named fan-control.
client.subscribe(FEED_ID)
def disconnected(client):
# Disconnected function will be called when the client disconnects.
print('Disconnected from Adafruit IO!')
sys.exit(1)
def message(client, feed_id, payload):
# Message function will be called when a subscribed feed has a new value.
# The feed_id parameter identifies the feed, and the payload parameter has
# the new value.
print('Feed {0} received new value: {1}'.format(feed_id, payload))
if str(payload) == "fan-on-med":
print('\nReceived <- FAN ON - MEDIUM\n')
##relayExp.driverInit(7) #Initialize the relay board
##print(relayExp.readChannel(7, 0)) #Print status of relay to standard out
##relayExp.setChannel(7, 0, 1) #turn on the relay
##time.sleep(2) # leave the relay on for 2 seconds to transmit the signal
## relayExp.setChannel(7, 0, 0) #turn off the relay
print(subprocess.run(["/root/fan_control/fan_medium.sh"], shell=True))
print('\nACTION COMPLETE <- RELAY CYCLED\n')
##print(relayExp.readChannel(7, 0)) #Print status of relay to standard out
elif str(payload) == "fan-off":
print('\nReceived <- FAN OFF\n')
## relayExp.driverInit(7) #Initialize the relay board
##print(relayExp.readChannel(7, 1)) #Print status of relay to standard out
## relayExp.setChannel(7, 1, 1) #turn on the relay
##time.sleep(2)
## relayExp.setChannel(7, 1, 0) #turn off the relay
print(subprocess.run(["/root/fan_control/fan_off.sh"], shell=True))
print('\nACTION COMPLETE <- RELAY CYCLED\n')
## print(relayExp.readChannel(7, 0)) #Print status of relay to standard out
# Create an MQTT client instance.
client = MQTTClient(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY)
# Setup the callback functions defined above.
client.on_connect = connected
client.on_disconnect = disconnected
client.on_message = message
# Connect to the Adafruit IO server.
client.connect()
# Start a message loop that blocks forever waiting for MQTT messages to be
# received. Note there are other options for running the event loop like doing
# so in a background thread. see the mqtt_client.py example to learn more.
client.loop_blocking()
Cleanup and autorun- This is a blocking script so you won't want to just add it boot as is, it will choke up the Omega2+ making it almost unusable.
- I recommend putting it in a screen on boot in /etc/rc.local
screen -d -m -S fancontrol python3 /root/fan_control/mqtt_subscribe.py
- Now you can test your commands by saying "trigger + [custom trigger name from IFTTT]"
AND WE'RE DONE!
Hope this helps someone!
Comments
Please log in or sign up to comment.