Important caveat: I wrote this script and tested it only against a small mock responder on my own machine, not against a real LIFX light. Treat it as a starting point and check it against the LIFX docs before relying on it. It only sends one read-only discovery packet (GetService, type 2) and never changes a light.
Safety: run it only on a network you own. LIFX warns that malformed messages or excessive message rates can cause unexpected device behaviour, so run it once, not in a loop.
What it does
According to the docs, GetService is broadcast with the tagged flag set and an all-zero target, and each device replies with StateService messages naming the services and ports. The one you care about is service 1 (UDP), usually on port 56700. The script prints each light's IP address, serial and port.
Code: Select all
#!/usr/bin/env python3
import socket, struct, sys, time
SOURCE = 2 # anything other than 0 or 1
PORT = 56700
def get_service(seq=1):
frame = struct.pack("<HHI", 36, 1024 | (1 << 12) | (1 << 13), SOURCE)
addr = bytes(8) + bytes(6) + bytes([0, seq])
proto = struct.pack("<QHH", 0, 2, 0)
return frame + addr + proto
def parse(data):
if len(data) < 36:
return None
ptype = struct.unpack_from("<H", data, 32)[0]
serial = data[8:14].hex()
if ptype == 3 and len(data) >= 41:
service, port = struct.unpack_from("<BI", data, 36)
return serial, service, port
bcast = sys.argv[1] if len(sys.argv) > 1 else "255.255.255.255"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.settimeout(0.5)
s.sendto(get_service(), (bcast, PORT))
end, seen = time.time() + 3, set()
while time.time() < end:
try:
data, (ip, _) = s.recvfrom(1024)
except socket.timeout:
continue
r = parse(data)
if r and r[1] == 1 and (ip, r[0]) not in seen:
seen.add((ip, r[0]))
print(f"{ip} serial {r[0]} UDP port {r[2]}")
print(f"{len(seen)} light(s) found")Using the result
- Give each light found a DHCP reservation on your router.
- In Home Assistant, check whether the lights were discovered under Settings > Devices & services. If not, use Add Integration > LIFX and enter the host, or the host and the serial number together, which the docs say is the most direct option.
- If a light is on a network Home Assistant cannot reach by broadcast, add it by host (a serial number alone will not work).
- If nothing shows up, check that Home Assistant has an interface on the lights' subnet, as the docs advise.
- Wi-Fi client isolation or multicast and broadcast filtering on the access point is the usual cause. Test from a wired device on the same VLAN.
- Check your firewall allows UDP 56700 between the script's machine and the lights.
- A light that is switched off at the wall cannot answer.