Project: find LIFX lights on your network with a read-only Python script, then add them to Home Assistant

Discuss Lifx Smart Lighting Bulbs and Devices
Post Reply
User avatar
ZerOne
Site Admin
Posts: 216
Joined: Sun Dec 13, 2020 8:21 am

A small project to see exactly what LIFX lights are answering on your network, using the documented LAN protocol, before you add them to Home Assistant. It is based on LIFX's LAN docs (encoding a packet, packet contents and querying the device) and the Home Assistant LIFX docs, as at October 2026.

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")
Run it with python3 lifx_discover.py, or give your subnet's broadcast address as the first argument (for example 192.168.30.255) if the default does not find anything.

Using the result
  1. Give each light found a DHCP reservation on your router.
  2. 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.
  3. If a light is on a network Home Assistant cannot reach by broadcast, add it by host (a serial number alone will not work).
  4. If nothing shows up, check that Home Assistant has an interface on the lights' subnet, as the docs advise.
If nothing answers
  • 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.
Discussion: did the script find your lights, and which model and firmware did they report? If you tried it on a real light, please let me know what you saw.
Post Reply

Return to “Lifx Lighting Discussion”