Here is some Python code to get the first bulb that responds to a search and calls various functions on it:
# Copyright Jan Newmarch
# Berkeley license
import struct
import re
import json
MCAST_GRP = '239.255.255.250'
MCAST_PORT = 1982
SRC_PORT = 5159 # my random port
CR_LF = "\r\n"
def get_ip_port():
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
sock.bind(('', SRC_PORT))
sock.sendto("M-SEARCH * HTTP/1.1\r\n\
HOST: 239.255.255.250:1982\r\n\
MAN: \"ssdp:discover\"\r\n\
ST: wifi_bulb\r\n", (MCAST_GRP, MCAST_PORT))
sock.close()
sock_recv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
socket.IPPROTO_UDP)
# ensure this socket is listening on the same
# port as the multicast went on
sock_recv.bind(('', SRC_PORT))
response = sock_recv.recv(10240)
sock_recv.close()
# match on a line like "Location: yeelight://192.168.1.25:55443"
# to pull ip out of group(1), port out of group(2)
prog = re.compile("Location: yeelight://(\d*\.\d*\.\d*\.\d*):(\d*).*")
for line in response.splitlines():
result = prog.match(line)
if result != None:
ip = result.group(1)
port = result.group(2)
return (ip, int(port))
return (None, None)
def sendto(ip, port, command):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
sock.connect((ip, port))
sock.send(command + CR_LF)
response = sock.recv(10240)
#print(response)
# the response is a JSON string, parse it and return
# the "result" field
dict = json.loads(response)
sock.close()
#print "Response was ", response
return(dict["result"])
def get_prop(prop, ip, port):
# hard code the JSON string
command = '{"id":1,"method":"get_prop","params":["' + prop + '"]}'
response = sendto(ip, port, command)
return response
def set_prop(prop, params, ip, port):
# hard code the JSON string
command = '{"id":1,"method":"set_' + prop +\
'", "params":' + params +\
'}'
#print(command)
response = sendto(ip, port, command)
return response
def set_name(name, ip, port):
params = '["' + name + '"]'
response = set_prop('name', params, ip, port)
return response
def set_power(state, ip, port):
params = '["' + state + '", "smooth", 500]'
response = set_prop('power', params, ip, port)
return response
def set_bright(state, ip, port):
params = '[' + str(state) + ', "smooth", 500]'
response = set_prop('bright', params, ip, port)
return response
if __name__ == "__main__":
print 'Starting'
(ip, port) = get_ip_port()
if (ip, port) == (None, None):
print "Can't get address of light"
exit(1)
print 'IP is ', ip, ' port is ', port
# sample set commands:
success = set_power("on", ip, port)
print 'Power set is', success[0]
success = set_bright(90, ip, port)
print 'Brightness set is', success[0]
name = set_name('bedroom', ip, port)
print 'Name is ', name[0]
# sample get commands:
power = get_prop("power", ip, port)
print 'Power is', power[0]
bright = get_prop("bright", ip, port)
print "Bright is ", bright[0]
name = get_prop('name', ip, port)
print "name now is", name[0]
# getting multiple properties at once.
# Be careful with the quotes, words need to be separated by "," !
prop_list = get_prop('name", "power", "bright', ip, port)
print "Property list is", prop_list
For more info see Ch 35 of my online book IoT for Techies