Waveform Packet 103 is not working


I have use SetWaveformOptional - Packet 119 it is not working
(Changing a device)

I tried using the SetWaveform - Packet 103 also but did not working

I hope somebody can shed some light here. Thanks

These are the data I sent for SetWaveform - Packet 103 to try using waveform:

transient= 0; (I think this is to not restore the previous colour, maintain the current colour set)

duration=1 second

cycle (I think this is how many cycles you want to be in that new colour) = 20 cycles
But this is quite weird because the expected value is float of 4 bytes

skew ratio=0; (this is actually 0.5 ratio, hence duty cycle = 1-0.5=0.5)

waveform=4 (pulse)

hue/saturation/brightness = 65535 (just for sake of testing set max)

kelvin= 65535 (just for sake of testing set max)

Like for SetColor - Packet 102 I have no problem


Set cycle: 1 and waveform: 0. Your kelvin value should be 3500.

Edited to add: BTW, I strongly encourage you to use Photons to experiment with this sort of thing. I used it to generate and then decode protocol messages using the following commands:

lifx lan:transform d073d53XXXXXX --verbose  '{"power": "on", "duration": 10, "brightness": 0.5, "saturation": 1, "hue": 0}'

The output of that is very, very verbose. Right at the end you’ll see the hexlified/packed messages which Photons can unpack for you:

lifx unpack -- 3d0000140526fd56d073d53846590000000000000000020200000000000000007700...obfuscated...00000000803f00800001010100

Which then outputs the entire packet in JSON format.

Hi @Djelibeybi

Thanks for replying

I did plugged the numbers as you suggested.

It wasn’t working.

For example if I want to change to red colour, brightness 100%, kelvin white colour, max saturation, what will those values? I tried play around with the waveform (e.g 0), cycle (e.g 1), skew ratio (e.g 0), duration (e.g 1) it still not working. Would you be kindly suggesting those values that work so that when I sent packet 103, it sets immediately to red colour

Thanks for helping

I’m not sure what you’re plugging the numbers into, but here’s how you’d do that with Photons:

lifx lan:transform <serial> -- '{"color": "red", "brightness": 1, "duration": 1}'

That sends a SetWaveformOptional packet with the following values:

    "frame_address": {
        "ack_required": true,
        "res_required": false,
        "reserved2": "000000000000",
        "reserved3": "00",
        "sequence": 1,
        "target": "[redacted]"
    "frame_header": {
        "addressable": true,
        "protocol": 1024,
        "reserved1": "00",
        "size": 61,
        "source": 2776133362,
        "tagged": false
    "payload": {
        "brightness": 1.0,
        "cycles": 1.0,
        "hue": 0.0,
        "kelvin": 0,
        "period": 1.0,
        "reserved6": "00",
        "saturation": 1.0,
        "set_brightness": 1,
        "set_hue": 1,
        "set_kelvin": 0,
        "set_saturation": 1,
        "skew_ratio": 0.0,
        "transient": 0,
        "waveform": 0
    "protocol_header": {
        "pkt_type": 119,
        "reserved4": "0000000000000000",
        "reserved5": "0000"

Keep in mind that if you just want to change to a specific HSBK value, using SetColor is a lot easier. It allows you to set the duration too, so everything is pretty much covered. It’ll automatically transition for you if the duration > 0.

Hi @Djelibeybi ,

I managed to run SetColor - Packet 102 a while ago

Now my requirements added that I only need to change certain value while maintaining other attributes

On my hardware I am using UDP protocol of bytes array

Here are my context when I want to sent SetWaveform - Packet 103: (sorry for the formating)

—Header packet— (note that only the size, sequence, pkt_type I change from packet 102 to packet 103)
*size - 00111001 00000000 (57 bytes for packet 103 SetWavefrom)
protocol - 00000000 00000100
addressable - 1
tagged - 0
origin - 00
source - 00000010 00000100 00001000 00010000 (ID from my hardware)
target - 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 (I set all zeros so all Lifx endpoints receive)
reserved - 00000000 00000000 00000000 00000000 00000000 00000000
res_required - 0
ack_required - 1
reserved - 000000
*sequence - 00000001 (I increment this value each time I sent out)
reserved - 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
*pkt_type - 01100110 00000000 (packet 103 - setwaveform)
reserved - 00000000 00000000

----Start of packet 103-----
reserved6 - 00000000
Transient - 00000000
Hue - 00000000 00000000 (red colour)
Saturation - 11111111 11111111 (65535)
Brightness - 11111111 11111111 (65535)
Kelvin - 10101100 00001101 (3500)
Period - 11101000 00000011 00000000 00000000 (1000ms)
Cycle (float 4 bytes) - (how to present float in 4 bytes here? e.g how to present 1.0 second?)
Skew ratio(int16) - (how to present signed int in 2bytes here? e.g how to present -32768 ?)
Waveform - 00000000 (saw waveform)

I think the Cycle and the skew ratio I may have set not to according to Lifx UDP requirement
Please advise what would be the correct value? I am quite confident these values are wrong, SetLight is working nevertheless


What language are you working in? There are libraries in almost all of them that do all this packing and unpacking for you (even for microcontrollers like ESP32). Here are some examples of how these values are packed:

Photons (Python): https://github.com/delfick/photons/blob/main/modules/photons_messages/fields.py#L73-L81

aiolifx (Python): https://github.com/frawau/aiolifx/blob/master/aiolifx/msgtypes.py#L910-L936

Rust: GitHub - eminence/lifx: LIFX LAN network protocol in rust

JavaScript: GitHub - node-lifx/lifx-lan-client: Canonical fork of the number one Node.js 💡 LIFX LAN protocol implementation.

Go: GitHub - dsymonds/lifx: Go package for interacting with LIFX devices.

C: GitHub - Phandal/Lanfx: Lifx Lan API Implementation in C

Someone has even created a LIFX emulator for the ESP32: GitHub - giantorth/ESPHomeLifx: Port of Lifx protocol to ESPHome.io firmware.

Hopefully one of these is in your chosen language so you can review the method it uses for encoding the packets.


For anyone struggling to make packet 103 setwaveform or packet 119 setwaveformoptional to work using byte array like I have, I have found the solution.

The key is to represent the cycle in 4 bytes float into IEEE 754 binary representation of float

So if 1second cycle to binary IEEE 754 representation is 00111111100000000000000000000000
Just make sure structure this binary into 4 bytes little endian and you good to go.

You can use this link to do the conversion for you:

Hi @Djelibeybi

May I know why Lifx device after perform SetWaveformOptional, then I do SetPower to off then on, the lifx randomly change to any colour? Example during SetWaveformOptional I set to colour Green, then I do off and on using ‘SetPower’, but after the on, it randomly change to any colour?

Is this the a normal behaviour?


I have no idea if that’s normal or not, but it doesn’t sound normal to me.

I should point out that I don’t (and have never) worked for LIFX. I’m just another developer who happens to have some experience with the LAN protocol.

My advice is to use SetLightPower instead of SetPower because it has a duration value which won’t cancel the running waveform. If you use SetPower, the waveform stops instantly as the power value hits 0. Could the random colour be the one that was on the device as you sent the SetPower to 0?

Hi @Djelibeybi

Sorry I was in the notion that you are the developer from your technical reply on Lifx
Thanks for assist

Using SetLightPower is worst than SetPower as SetLightPower will always turn on to white colour.

For now my solution is to store the previous attributes and restore the attributes after toggle from off to on

Thanks again for your reply