Lightwave Link: Introduction & Basic Comms

Introduction & Basic Communication

The LightwaveRF system operates via radio communication between the peripherals available. To allow any automation, or “smart” control, a hub device needs to be used which translates network packets into radio commands which the peripheral devices understand. In the LightwaveRF system, this hub is the WiFiLink (later renamed the Lightwave Link).

There are two types of Link, the LW500 which has a blue LCD screen, and the LW930 which has no screen and is a smaller size. There is no difference in the operation of these units aside from some hardware diagnostics that the LW500 can output on its screen, which both units are able to output on the local network as a UDP packet regardless.

It is possible through UDP communication to note if the user has an LW930 or LW500. Firstly, the version number of an LW930 will be prefixed with “N”, such as N2.92C. With LW500 it would be “V” or “U”, such as “V2.92A” or “U2.93E”. The suffix is simply incremented in each version - it is not an indication of alpha, beta, etc build. Secondly, the fourth octet of the MAC address will denote if it is an LW500 or LW930. All Links will begin 74:0A:BC: with LW930s being 20:XX:XX or 21:XX:XX, while LW500s will be 02:XX:XX or 03:XX:XX. Therefore you can check if a user has a Link with a screen or not from JSON outputs by checking for 74:0A:BC:0 or 74:0A:BC:2 as the first characters of their MAC address - 74:0A:BC:0 = LW500 and 74:0A:BC:2 = LW930.


At its most basic, the LightwaveRF local protocol is human readable ASCII packets in the format outlined further below. The client sends commands via UDP broadcast (i.e. to or to the WiFiLink’s IP address (if known) on port 9760 across the local network. Replies will be sent out as a UDP broadcast on port 9761. Direct messages can be sent to the Link when the local IP is known to improve reliability; UDP is inherently lossy so there can be no assurance the packet is received aside from the responses the Link gives back.

From WiFiLink version 2.91Z, packets will also go out as a unicast to the last local IP address which successfully communicated with the WiFiLink. The unicast was introduced as some smartphone & tablet devices in the market filtered out some or all UDP broadcast messages, while unicast messages were unimpeded. As a result, the client which is communicating to the WiFiLink will likely receive duplicate packets; one broadcast, and one unicast.

Example command structure


Room 1 Device 1 Function ON



RoomNo LightwaveRF Room Number. Valid 1 to 15
DeviceNo LightwaveRF Device Number. Not required in some commands
FunctionType Single ASCII letter or numbers 0 or 1
Parameter Optional. Some FunctionTypes will utilise a parameter, such as dimming. Other commands such as On and Off do not need this.
Line1 Text input after the first pipe ( | ) will be displayed on the top line of the WiFiLink screen*. Maximum of 16 characters. Optional.
Line2 Text input after the second pipe ( | ) will be displayed on the bottom line of the WiFiLink screen*. Maximum of 16 characters. Optional.

Note Lightwave Link (model no LW930) has no screen and will disregard these messages.

Command Package

The full command package sent is:


For Example:


will turn on Device 1 in Room 1

373,!R4D3FdP16|Side Lamp|Half Brightness

will turn Device 3 in Room 4 to 50% brightness (dim commands detailed in next section) and displays ‘Side Lamp’ on line one of the WiFiLink and ‘Half Brightness’ on line two.

Example Interactions

Note Before the Link will respond to these messages, you need to have registered your client device with the Link. To do this, you will need to first send the command !F*p out, then press the button on the Link when the Links LED flashes. Details on this can be found in the next section.

Normal command with a transaction ID. Reply received OK.:

S[]: 111,!R1D1F1
R[]: 111,OK

Created with Raphaël 2.1.2ClientClientLinkLinkPeripheralPeripheral111,!R1D1F1111,OK(RF Turn Device On)

Normal command with incremented transaction ID and a screen description (Turn Light Off). Reply received OK:

S[]: 112,!R1D1F0|Turn Light|Off
R[]: 112,OK

Created with Raphaël 2.1.2ClientClientLinkLinkPeripheralPeripheral112,!R1D1F0|Turn Light|Off112,OK(RF Turn Device Off)

Command sent without a transaction ID. WiFiLink replies to transaction ID 0:

S[]: ,!R3D1FdP12
R[]: 0,OK

Created with Raphaël 2.1.2ClientClientLinkLinkPeripheralPeripheral,!R3D1FdP120,OK(RF Dim Device)

If more than one Lightwave Link is connected to the network you are on, then sending commands will affect all Links you are authorised to control. For example, sending !R1D1F1 will make multiple Links transmit their !R1D1F1 command out simultaneously:

Created with Raphaël 2.1.2ClientClientLink1Link1Link2Link2Link3Link3PeripheralsPeripherals150,!R1D1F1150,!R1D1F1150,!R1D1F1150,OK150,OK150,OK(RF Control Device)(RF Control Device)(RF Control Device)

This can be an issue if the Links are in fairly close proximity as this may cause the radio broadcasts to collide with each other which can reduce the range of transmission, or make the receivers not react to either transmission

It is possible to control a particular Link unit by prefixing your command with the last 3 octets MAC address of the unit you are looking to control. For example, if you have three Links: 74:0A:BC:20:12:34, 74:0A:BC:20:56:78 and 74:0A:BC:20:90:AB, but only wanted to control 74:0A:BC:20:56:78, then you can send :205678,123,!R1D1F1 and the other two Links will ignore the message while 74:0A:BC:20:56:78 would send out the command:

Created with Raphaël 2.1.2ClientClient740ABC201234740ABC201234740ABC205678740ABC205678740ABC2090AB740ABC2090ABPeripheralsPeripherals:205678,123,!R1D1F1:205678,123,!R1D1F1:205678,123,!R1D1F1(no response)123,OK(no response)(RF Control Device)

Though other examples listed in this documentation do not include the prefix, it is good practice to use the prefix even if your use case is one Link as it protects your client application against future setups.

In recent versions of the Lightwave Link and WiFiLink (2.92 onwards) there has been the introduction of JSON packets in response to almost all commands. The above communications in “Example Interactions” will also be supplemented with the JSON packets outlined below.

S[]: 111,!R1D1F1
R[]: 111,OK
R[]: *!{"trans":1,"mac":"03:34:BC","time":1456495650,"pkt":"433T","fn":"on","room":1,"dev":1}

Created with Raphaël 2.1.2ClientClientLinkLinkPeripheralPeripheral111,!R1D1F1111,OK*!{"trans":1,"mac":"03:34:BC","time":1456495650,"pkt":"433T","fn":"on","room":1,"dev":1}(RF Turn Device On)

The 111,OK is received to indicate the Link has received the command okay, while the JSON is the Link reporting what it is doing. In this case, it is executing the command we had requested. If only 111,OK is received without the following JSON packet, then it should be assumed that the command was not transmitted.

A breakdown of this is:

"trans":1,         // Link transaction number.  This is the number 
                   // of transactions the Link has output. NOT any 
                   // relation to the trans number from the client
"mac":"03:34:BC",  // Last 6 characters from the Link MAC address
"time":1456495650, // Time of transaction
"pkt":"433T",      // Type of radio message.  Will vary between 433T 
                   // (transmission of 433MHz), 868T (transmission 
                   // of 868MHz) and 868R (receiving of 868MHz)
"fn":"on",         // Function of radio message.
"room":1,          // Room number of the transmission
"dev":1            // Device number of the transmission

More details of the JSON outputs are documented later in the API but the fundamental idea is the same. In version 2.92 onwards, the “OK” message can be used to confirm that the Link has received the command, but unless the corresponding JSON packet has been received, then it should not be considered that the radio packet has been transmitted.

Transmit Error Example

In addition to the lack of a "pkt" JSON message being sent out, it is possible that the Link is unable to transmit the radio packet due to no space in its buffer - if it is already transmitting radio, for example. This is shown by a response of “Transmit Fail” and no following JSON. Again, this is in version 2.92 onwards.

S[]: 112,!R1D1F1
R[]: 112,ERR,6,"Transmit fail"

Created with Raphaël 2.1.2ClientClientLinkLink112,!R1D1F1112,ERR,6,"Transmit fail"

There is no automatic retry to retransmit, and so it is reliant on the client attempting to retry the appropriate command if this is received.

Last updated 16/12/16