Most of the time my colour Yeelight bulb responds okay to SSDP requests using local LAN discovery. But every now and then it stops doing so. There doesn’t seem to be any pattern. I’ve tried sending requests every 5 seconds with a 2 second timeout for responses: the bulb will respond many times and then stop responding, starting again between one and 5 minutes later. I’ve been watching with tcpdump:
tcpdump -i wlan0 -s0 -vv udp -A
So sometimes I can discover the lights, and sometimes I can’t! Is there any solution?
The code I am using is in Python from the Yeelight package by Stavros Korokithakis. I have only one interface active. I can see the requests going out, but sometimes there is no response from my light. I have only one light at present, so I can’t tell if it is only that light failing to respond, or if all lights would fail.
import os
import socket
import struct
import json
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
def discover_bulbs(timeout=2, interface=False):
msg = "\r\n".join(["M-SEARCH * HTTP/1.1", "HOST: 239.255.255.250:1982", 'MAN: "ssdp:discover"', "ST: wifi_bulb"])
# Set up UDP socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)
if interface:
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF,
socket.inet_aton(get_ip_address(interface)))
s.settimeout(timeout)
s.sendto(msg.encode(), ("239.255.255.250", 1982))
bulbs = []
bulb_ips = set()
while True:
try:
data, addr = s.recvfrom(65507)
except socket.timeout:
print('Timeout')
break
capabilities = dict([x.strip("\r").split(": ") for x in data.decode().split("\n") if ":" in x])
parsed_url = urlparse(capabilities["Location"])
bulb_ip = (parsed_url.hostname, parsed_url.port)
if bulb_ip in bulb_ips:
continue
capabilities = {key: value for key, value in capabilities.items() if key.islower()}
bulbs.append({"ip": bulb_ip[0], "port": bulb_ip[1], "capabilities": capabilities})
bulb_ips.add(bulb_ip)
return bulbs
bulbs = discover_bulbs(timeout = 10)
print(str(bulbs))
```