Homebridge plugin for BLE RGBIC/RGBWIC light strips controlled by the Magic Lantern app.
These unbranded Magic Lantern BLE strips ship with multiple firmware variants so it's hard to ensure compatibility for all strips.
- HomeKit Lightbulb service
- On/off with RGB-black fallback plus optional native Magic Lantern power frames
- Brightness via RGB scaling by default, with optional native Magic Lantern brightness frames
- HomeKit on/off, brightness, and color control confirmed on a
MELK-OC21WCT31strip - Homebridge UI config schema
- BLE discovery with log snippets and optional auto-add
- Serialized BLE writes with timeout, retry/backoff, background recovery search, reconnect, and optional keep-alive
Effects and segment control are not supported as there is no good way to expose them in Apple Home (that i've found)
Install it like any other Homebridge plugin:
sudo npm install -g homebridge-lanternicFor local development from this repository:
npm install
npm run build
sudo hb-service linkCaution
Only the following platforms are supported:
- macOS
- If using macOS, you'll need to give Node.js permission to use Bluetooth in System Settings → Privacy & Security → Bluetooth.
- Linux
- 64-bit, not tested on 32-bit systems
LanternIC can be set up from Homebridge UI without editing raw JSON.
- Install the plugin.
- Open Homebridge UI.
- Go to Plugins, select LanternIC, then Settings.
- Leave
Scan For Light Strips On Startupenabled. - Turn on
Automatically Add Discovered Strips. - Save and restart Homebridge.
- Open the logs and confirm LanternIC found the right strip.
If you're in a crowded environment, I would keep auto-add off to avoid interferring with nearby devices.
- Leave
Scan For Light Strips On Startupenabled. - Save and restart Homebridge.
- Open the logs and look for
Discovered BLE candidate. - Copy the candidate address, for example
BE:16:70:00:08:2A. - In LanternIC settings, click
Add Light Strip. - Enter a friendly name and the Bluetooth address.
- Save and restart Homebridge.
The LanternIC device config: {...} log line is only a shortcut for people using Homebridge's JSON editor. In the normal settings UI, you only need the strip name and address.
Use Show Advanced Settings only for Bluetooth adapter options, discovery filters, or protocol fallback tuning.
You can also use the local scanner:
lanternic-scanUseful scanner filters:
LANTERNIC_MIN_RSSI=-75 lanternic-scan
LANTERNIC_SCAN_SECONDS=45 lanternic-scan
LANTERNIC_SCAN_ALL=1 lanternic-scan...or just use bluetoothctl (it doesn't matter)
When working from this repository instead of a global install, use npm run scan in place of lanternic-scan.
Automatically Add Discovered Strips can create HomeKit accessories for matching BLE candidates. Leave it off until you are nearby and ready to test, because nearby BLE devices may advertise similar services.
LanternIC has a few BLE helpers for setup and firmware troubleshooting:
lanternic-scan
lanternic-explore <address>
lanternic-send <address> rgb ff0000
lanternic-send <address> brightness 50
lanternic-send-sequence <address> 7e070503ff000010ef 7e07050300ff0010ef
lanternic-calibrate <address>All tools default to Noble's cross-platform default binding. Override it only when needed:
LANTERNIC_BINDING=hci lanternic-scan
LANTERNIC_BINDING=mac lanternic-scanThis plugin uses @stoprocent/noble. Homebridge should run on any Node.js version supported by this package.
Install Bluetooth dependencies:
sudo apt-get update
sudo apt-get install -y bluetooth bluez libbluetooth-dev libudev-dev libcap2-binAllow the Node binary used by Homebridge to access BLE:
sudo setcap cap_net_raw,cap_net_admin+eip "$(eval readlink -f "$(which node)")"If Homebridge runs under hb-service, make sure you run the setcap command against the same node binary that service uses. The safest path is to run it in the same shell/environment where Homebridge was installed, or from the Homebridge UI terminal.
Recommended Linux BLE settings:
{
"ble": {
"binding": "default",
"hciDriver": "native",
"hciDeviceId": 0,
"writeMode": "withoutResponse"
}
}binding: "default" auto-selects Linux HCI on Linux. Set hciDeviceId to 1 for hci1, etc. If scanning sees nothing on a Raspberry Pi, try adding this to /etc/bluetooth/main.conf, then reboot:
DisablePlugins=pnatIf Linux discovery works from the CLI but Homebridge cannot connect, run the setcap command against the exact Node binary used by hb-service, then restart Homebridge. If keepConnected is enabled, expect the Magic Lantern iPhone app to fail or hang while Homebridge owns the BLE connection.
Most users should use the Homebridge UI instead. If you prefer editing config.json, start with discovery enabled and no devices:
{
"platform": "LanternIC",
"name": "LanternIC",
"showAdvanced": false,
"devices": [],
"discovery": {
"enabled": true,
"scanSeconds": 20
}
}Restart Homebridge and look for candidate device addresses in the logs. Then add a strip with just a name and address:
{
"platform": "LanternIC",
"name": "LanternIC",
"devices": [
{
"name": "TV Strip",
"address": "BE:16:70:00:08:2A"
}
],
"discovery": {
"enabled": true
}
}Add advanced fields only if you need them. for example:
{
"ble": {
"keepConnected": true,
"writeMode": "withoutResponse"
}
}Since each strip is different, you may need to configure your settings differently.
- Pair/configure the strip in the Magic Lantern app first so it is powered, reachable, and known-good.
- Fully quit the Magic Lantern app before testing Homebridge. BLE devices usually allow only one active central connection.
- Start Homebridge in debug mode and confirm the plugin logs your strip during discovery.
- Add the address to config and restart.
- Test in this order: On, Off, Brightness 10/50/100, Red, Green, Blue, White
- If colors are swapped, change
colorOrder. - If Off leaves the strip visibly on, keep
powerModeasbothor tryrgbBlack. - If brightness does not change, keep
brightnessModeasrgb; if it double-dims, trynative.
Each HomeKit command already scans for the strip if Homebridge is not connected. If a command times out or the strip disconnects during a write, LanternIC starts a background recovery search and resends the cached desired HomeKit state after reconnecting.
Known Magic Lantern BLE writes go to:
- Service UUID:
FFF0 - Characteristic UUID:
FFF3
Confirmed through HomeKit against a MELK-OC21WCT31 / firmware string WCKJ3016FV25HCV6 strip:
- RGB:
7e070503RRGGBB10ef - Off fallback:
7e07050300000010ef - Brightness: RGB scaling through the same RGB frame
The core frames available here are:
- On:
7e0404f00001ff00ef - Off:
7e0404000000ff00ef - RGB:
7e070503RRGGBB10ef - Brightness:
7e0401xx01ffff00ef, wherexxis 0-100 decimal encoded as one byte - Effect speed:
7e0402xxffffff00ef, wherexxis 0-100 decimal encoded as one byte - Basic effect:
7e0503xx06ffff00ef
These Magic Lantern BLE frame notes are based on some packet-captures from @kassabov in Home Assistant Core issue #145934. (thanks!)
- Home Assistant Core issue: home-assistant/core#145934
- Home Assistant community thread: https://community.home-assistant.io/t/new-integration-for-ble-magic-lantern/454055
- Magic Lantern app overview: https://magiclantern.app/
- Modern Noble fork used for BLE: https://github.com/stoprocent/noble
The default powerMode is both, which sends RGB black before the native off frame. The default brightnessMode is rgb, which scales RGB values instead of relying on the native brightness frame. These defaults favor the RGB command that is confirmed on real hardware.
The command builders are isolated so we can add variants if your strip uses a slightly different firmware.
- HomeKit on/off, brightness, and RGB color control are confirmed on the MELK firmware above.
- Native power and brightness frames are implemented, but still need more real-strip validation because some Magic Lantern-family firmware appears to accept RGB frames while ignoring one or both native frames.
- If color works but power or brightness does not, use
lanternic-send <address> raw <hex-frame>while testing candidate frames and open an issue with the model name, firmware string fromlanternic-explore, and the working frame. - Avoid enabling discovery
autoAdduntil your filters are tight. Some nearby BLE devices can share generic names or services and should not be bridged as lights.
- All BLE operations are serialized through a single manager queue.
- Every characteristic write has a timeout and is retried with exponential backoff.
- Failed writes force a disconnect, rediscovery, and a background recovery search.
- Desired HomeKit state is cached and resent after a background reconnect.
- Connections are closed after an idle timeout by default, so the Magic Lantern app or another controller is less likely to be locked out forever. (unless you attempt to control the device again)
- Set
ble.keepConnectedtotruefor the most reliable HomeKit behavior. This keeps Homebridge attached to the strip and automatically reconnects after drops, but the Magic Lantern app may not be able to connect until Homebridge releases the device.
Default settings:
{
"ble": {
"keepConnected": true,
"writeMode": "withoutResponse",
"writeTimeoutMs": 5000,
"retryAttempts": 4,
"retryDelayMs": 500,
"maxRetryDelayMs": 5000,
"reconnectDelayMs": 1000,
"maxReconnectDelayMs": 60000
}
}