ESP-NOW GLEDOPTO GL-RC-001WL remote
How to use Berry espnow.rx in firmware 0.12.11 to receive raw ESP-NOW packets from the GLEDOPTO GL-RC-001WL remote.
What the remote solves
Section titled “What the remote solves”The GLEDOPTO GL-RC-001WL remote sends short raw ESP-NOW packets on multiple Wi-Fi channels when a button is pressed. With Berry espnow.rx(filter, callback), a controller can receive those packets as side-channel raw traffic without disabling the regular Spectoda Mesh ESP-NOW communication between controllers.
This is the main difference from older ESPNOWRADIO IO usage. ESPNOWRADIO owns the ESP-NOW receive callback and is not suitable for installations where the same controller should also participate in Controller-to-Controller communication.
Recommended API
Section titled “Recommended API”Write raw ESP-NOW receive logic like this:
import espnow
var off = espnow.rx({ "mac": "AA:BB:CC:DD:EE:FF", "size": 13, "magic": [129, 145]}, def(mac, data, rssi, channel) print(mac, data.tohex(), rssi, channel)end)
# When you need to unregister the callback:off()The callback receives:
| Argument | Meaning |
|---|---|
mac | sender MAC address as string |
data | payload as Berry bytes |
rssi | received signal strength |
channel | Wi-Fi channel on which the packet arrived |
The filter runs natively in firmware before the packet is passed to Berry. For the GLEDOPTO remote, start with this shape:
{ "size": 13, "magic": [129, 145]}Meaning of values:
| Key | Meaning |
|---|---|
size | expected payload length; GL-RC-001WL uses 13 bytes |
magic | allow-list of the first payload byte; 129 is 0x81, 145 is 0x91 |
mac | optional lock to one physical remote |
Packet shape
Section titled “Packet shape”Three parts of the payload matter for button mapping:
| Position | Meaning |
|---|---|
byte 0 | program/magic, typically 0x81 or 0x91 |
bytes 1..4 | button press sequence |
byte 6 | button code |
The remote sends the same press repeatedly on multiple channels. Plugins therefore keep the last sequence from data.get(1, 4) and ignore the same sequence when it appears again.
Button mapping:
| Code | Button | Recommended meaning |
|---|---|---|
1 | ON | turn on |
2 | OFF | turn off |
9 | brightness + | increase brigh |
8 | brightness - | decrease brigh |
3 | night | night-mode scene |
16 | preset 1 | optional toggle |
17 | preset 2 | optional toggle |
18 | preset 3 | warmer tempe |
19 | preset 4 | colder tempe |
Single Spectoda ID variant
Section titled “Single Spectoda ID variant”For a simple luminaire, use the GledoptoRemoteSingle(S) plugin.
GledoptoRemoteSingle is not a built-in Berry function. First paste the plugin definition from public examples into the Controller Berry Script:
gledopto-single-id.be.
Then add the call with your S map below it.
It only writes:
EVS("toggl", id)EVS("brigh", id)
Example Berry call:
GledoptoRemoteSingle({ "id": 1, "mac": "AA:BB:CC:DD:EE:FF", "brigh": 50, "brighStep": 10})The same call as a TNGL BERRY block:
BERRY(`GledoptoRemoteSingle({ "id": ID1, "mac": "AA:BB:CC:DD:EE:FF", "brigh": 50, "brighStep": 10})`);S map for the single-ID variant:
| Key | Default | Meaning |
|---|---|---|
id | 1 | Spectoda ID controlled by the remote |
mac | "" | optional remote MAC address |
macFilter | mac != "" | whether packets from other MAC addresses should be rejected |
debug | false | log received packets and ignored buttons |
brigh | 50 | initial local brightness cache |
brighStep | 10 | brightness step per press |
Behaviour:
- ON sets
togglto100%. - OFF sets
togglto0%. - Brightness +/- adjusts
brighand keepstogglaligned with the resulting brightness. Whenbrighreaches0%,togglis also set to0%. - Preset 1 and preset 2 toggle the same ID on/off.
- Night, warmer and colder are ignored by the single-ID variant unless
debugis enabled.
Direct/indirect variant
Section titled “Direct/indirect variant”For a luminaire split into two logical zones, use GledoptoRemote(S).
GledoptoRemote is also not a built-in Berry function. First paste the plugin definition from public examples into the Controller Berry Script:
gledopto-direct-indirect.be.
Then add the call with your S map below it.
It writes:
EVS("toggl", direct)andEVS("toggl", indirect)EVS("brigh", direct)andEVS("brigh", indirect)EVS("tempe", direct)andEVS("tempe", indirect)
Example call:
GledoptoRemote({ "direct": 1, "indirect": 2, "mac": "AA:BB:CC:DD:EE:FF", "brigh": 50, "brighStep": 10, "tempeStep": 10})S map for the direct/indirect variant:
| Key | Default | Meaning |
|---|---|---|
direct | 1 | Spectoda ID for the direct part of the luminaire |
indirect | 2 | Spectoda ID for the indirect part of the luminaire |
mac | "" | optional remote MAC address |
macFilter | mac != "" | whether packets from other MAC addresses should be rejected |
debug | false | log received packets and unknown buttons |
brigh | 50 | initial shared brightness cache |
brighStep | 10 | brightness step per press |
tempeStep | 10 | colour temperature step per press |
Behaviour:
- ON/OFF controls
togglfor both IDs. - Brightness +/- adjusts
brighfor both IDs and keeps bothtogglstates aligned with the resulting brightness. When sharedbrighreaches0%, bothtogglstates are set to0%. - Night turns direct off, turns indirect on and sets both
tempevalues to warm. - Preset 1 toggles indirect.
- Preset 2 toggles direct.
- Preset 3/4 moves
tempefor both IDs warmer/colder.
How to find the remote MAC address
Section titled “How to find the remote MAC address”During first bring-up, enable debug:
GledoptoRemoteSingle({ "id": 1, "debug": true})Then press a button on the remote and watch the serial log. Once you know the MAC address, add it to the S map:
GledoptoRemoteSingle({ "id": 1, "mac": "AA:BB:CC:DD:EE:FF"})When mac is set and macFilter is not explicitly false, the plugin accepts only that one remote.
Upload and smoke test
Section titled “Upload and smoke test”For a DEVKIT or installation, upload Berry through a TNGL BERRY(...) block or through a Studio Berry Script block. You do not need to upload a filesystem image for this.
Recommended workflow:
- Keep regular ESP-NOW communication enabled.
espnow.enabledoes not need to be set totrue; current firmware enables it by default. - Upload the plugin and its call to the controller.
- For the first test, set
"debug": true. - Press ON, OFF, brightness + and brightness -.
- Check in the log or in Spectoda App that
togglandbrighchange on the expected Spectoda ID.
For the direct/indirect variant, also test preset 1, preset 2 and preset 3/4.
Relation to espnow.tx and spectoda.tx
Section titled “Relation to espnow.tx and spectoda.tx”espnow.rx and espnow.tx are raw APIs for the concrete ESP-NOW transport. Use them when you need to work with MAC address, payload and transport details.
Raw espnow.tx supports:
espnow.tx("AA:BB:CC:DD:EE:FF", data)espnow.tx("AA:BB:CC:DD:EE:FF", data, {"mode": "transmit"})espnow.tx("AA:BB:CC:DD:EE:FF", data, {"mode": "deliver"})Meaning:
transmitis one non-flooded packet without ack.deliveris one non-flooded unicast packet with ack.- raw
espnow.txhas nobroadcastortransfermode; flooded broadcast and larger transfers belong to the higher Spectoda Mesh layer throughspectoda.tx.
Use spectoda.tx and spectoda.rx for general Controller-to-Controller messages in Berry. Use espnow.tx and espnow.rx for exact work with raw ESP-NOW packets.