Skip to content

Instantly share code, notes, and snippets.

@bkbilly
Last active December 22, 2023 11:00
Show Gist options
  • Save bkbilly/061adbf5e65a270d4044aca390edee67 to your computer and use it in GitHub Desktop.
Save bkbilly/061adbf5e65a270d4044aca390edee67 to your computer and use it in GitHub Desktop.
Control Yeelight and others from a raspberry connected switch. Supports Multiple clicks, and long click.
import RPi.GPIO as GPIO
import socket
import json
import signal
from itertools import cycle
from wakeonlan import wol
import time
class switchButton():
def __init__(self, inputPin, pressDelay=0.5, pressStep=1.5):
self.inputPin = inputPin
self.pressDelay = pressDelay
self.pressStep = pressStep
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(self.inputPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
self.bulbIP = "192.168.2.132"
self.bulbIP = "192.168.2.132"
self.bulbPort = 55443
self.messageToggle = {"id": 1, "method": "toggle", "params": []}
self.messageON = {"id": 1, "method": "set_power", "params": ["on", "smooth", 500]}
self.messageOFF = {"id": 1, "method": "set_power", "params": ["off", "smooth", 500]}
self.messageSTATUS = {"id": 1, "method": "get_prop", "params": ["power"]}
self.scenes = cycle([
{"id": 1, "method": "set_scene", "params": ["ct", 6500, 100]}, # Day
{"id": 1, "method": "set_scene", "params": ["color", 1315890, 50]}, # Calm
{"id": 1, "method": "set_scene", "params": ["color", 16750848, 1]}, # Night
])
def runForever(self):
when_pressed = [time.time()]
completed = True
while True:
time.sleep(0.1)
if not GPIO.input(self.inputPin):
completed = False
if time.time() - when_pressed[-1] > self.pressDelay:
when_pressed = [time.time()]
else:
when_pressed.append(time.time())
keep_pressed = time.time()
while not GPIO.input(self.inputPin):
time.sleep(0.1)
time_pressed = time.time() - keep_pressed
if time_pressed > self.pressStep:
keep_pressed = time.time()
completed = True
print "Cycle Bulb Scenes..."
message = self.scenes.next()
self.connect(message, self.bulbIP, self.bulbPort)
else:
time_prev = time.time() - when_pressed[-1]
if time_prev > self.pressDelay and completed is False:
completed = True
print "Pressed {0} times".format(len(when_pressed))
if len(when_pressed) == 1:
print "Switch Bulb State..."
message = self.messageToggle
self.connect(message, self.bulbIP, self.bulbPort)
elif len(when_pressed) == 2:
print "sending magic packet"
wol.send_magic_packet('BC.EE.7B.87.65.BC')
def connect(self, command, bulb_ip, bulb_port):
try:
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
msg = json.dumps(command) + "\r\n"
tcp_socket.connect((bulb_ip, int(bulb_port)))
tcp_socket.send(msg)
data = tcp_socket.recv(1024)
tcp_socket.close()
return json.loads(data)
except Exception as e:
print "Unexpected error:", e
mybutton = switchButton(21)
mybutton.runForever()
signal.pause()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment