Tutorial: Controlling Your Legrand In One (CPL) Lighting with Gladys
This tutorial explains how to implement the Legrand In One CPL integration from A to Z: connecting the interface, serial gateway, installation, device discovery, reading logs, state rules, and dashboard.
Prerequisites: a Legrand In One installation (switches, interscenarios), a Legrand CPL/USB ref. 882 13 interface, and Gladys 4.86 or newer. The integration is not affiliated with Legrand.
1. Connecting the 882 13 Interface
The 882 13 interface connects to a USB port on the machine running Gladys. Linux sees it as a serial port (/dev/ttyACM0), with a stable name in /dev/serial/by-id/:
ls -l /dev/serial/by-id/
In my case: usb-Btcino_Terraneo_Mod._SFERA_Tele_Loop-if00 (the BTicino name is normal, it’s the manufacturer of the module).
Where to connect it?
| Machine | Possible? | Notes |
|---|---|---|
| Raspberry Pi 4/5, Home Assistant Yellow | Yes | This is my case (Yellow). Connect it directly, not via an unpowered USB hub. |
| Mini PC running Linux (Debian, Ubuntu…) | Yes | Same as the Pi. |
| NAS (Synology, QNAP) with Docker | Often | Docker must be able to mount the device (devices:). Not tested. |
| Gladys in a VM | Difficult | You need to pass the USB port to the VM. Avoid if possible. |
| Gladys on Windows / macOS | No | The serial gateway (below) requires Linux. |
Important limitation: the interface must be connected to an outlet on the same electrical network as your In One modules (same panel, ideally same phase). The carrier current does not pass through filters (882 12 / 882 21 / 882 23) or, in general, meters. If some modules are never heard, this is the first thing to check.
2. Creating the Serial Gateway (Required)
Gladys integrations run in a sandbox without USB access. A small socat container therefore exposes the serial port on a TCP port, to which the integration connects.
Create a folder (e.g., ~/legrand) with this docker-compose.yml, replacing the device name with yours:
services:
legrand-serial:
image: alpine/socat
container_name: legrand-serial
restart: always
labels:
- com.centurylinklabs.watchtower.enable=false
devices:
- /dev/serial/by-id/usb-Btcino_Terraneo_Mod._SFERA_Tele_Loop-if00:/dev/legrand
ports:
- "172.17.0.1:2000:2000"
command: tcp-listen:2000,fork,reuseaddr,max-children=1 /dev/legrand,raw,echo=0,b115200,hupcl=0
Then:
cd ~/legrand
docker compose up -d
docker ps | grep legrand-serial
Two things to know:
172.17.0.1is the host address seen from the Gladys Docker network. It works on a standard Docker installation. If your Docker network is different, check withdocker network inspect bridge.max-children=1: only one connection at a time. If you open annc 172.17.0.1 2000to test, the integration loses the gateway until you close the test.
Quick test, before installing the integration:
nc 172.17.0.1 2000
Press a wall switch: a frame like *1*1*0#15112945## should display. Exit with Ctrl-C. If nc is missing: sudo apt install netcat-openbsd.
If You Use the Gladys Raspberry Pi Image (« Gladys OS »)
The official image is a Raspberry Pi OS with Docker already installed. The gateway is therefore created exactly as above; you just need to open a terminal on the Pi via SSH.
1. Connect via SSH. From a computer on the same network:
ssh pi@gladys.local
(or ssh pi@PI_IP_ADDRESS). The credentials are those of the foundation’s image: login pi, password raspberry. On Windows, use PowerShell or PuTTY. On first access, change the password with passwd.
2. Locate the 882 13 interface. Plug it in, then:
ls -l /dev/serial/by-id/
Note the name that starts with usb-Btcino_....
3. Create the gateway. Still in the SSH terminal:
mkdir -p ~/legrand && cd ~/legrand
nano docker-compose.yml
Paste the docker-compose.yml above (right-click pastes in most terminals), replace the device name with yours, save with Ctrl-O then Enter, exit with Ctrl-X. Then run:
docker compose up -d
docker ps | grep legrand-serial
- « permission denied »: add
sudobefore the command, or add your user to the Docker group (sudo usermod -aG docker pi, then log out and log back in). docker composeunknown (old image): trydocker-compose up -d, with a hyphen.
4. Check with the nc test above. The container restarts automatically with the Pi (restart: always).
The same procedure applies to a mini PC running Debian or Ubuntu with Docker: only the SSH ID changes. The Gladys image does not support the Raspberry Pi 5; for this one, Gladys is installed manually via Docker, and the gateway is created in the same way.
3. Install the Integration
In Gladys: Integrations → Catalog, search for « Legrand In One CPL », Install. Updates will then be done from the catalog.
4. Configuration
Three settings:
- Serial Gateway Address:
172.17.0.1(default). - TCP Port:
2000(default). - Linked Devices (Rule 1 to Rule 12): leave empty for now, we’ll come back to this in chapter 8.
Click on Save Configuration. The Connected badge at the top concerns the link with Gladys; the link with the gateway is verified in the Logs tab, which should display Connected to 172.17.0.1:2000.
5. Discovery: Making the Installation Speak
The In One bus does not know how to list its devices. The integration learns each circuit by hearing it: you must press the buttons.
- Open the Logs tab in a window to see the frames arrive.
- Go around the house and press once on each button of each switch and each interscenario, including scenario buttons, even those that are not programmed for anything. An interscenario whose only on/off button has spoken is recognized as a simple « switch »; as soon as one of its scene buttons speaks, it becomes « inter scenario ».
- Go back to Discovery and click on Scan.
Each button appears as a device:
Legrand 944559-1 (inter): a switch button, with a Lighting On/Off function;Legrand 648966-1 (inter scenario): the on/off button of an interscenario;Legrand scenario 648966-3: a scenario button, exposed as a « Click » button.
The number 944559-1 is the circuit number: identifier of the module (944559) and button number (1). It appears everywhere: logs, rules, technical parameters. Note it down for each device.
If a button is missing, press it again and restart the scan. The list of known circuits is preserved on restart.
6. Add Devices to Gladys
Click on Add to Gladys for each useful device, then choose its room in the Devices tab.
Tip: Do not rename the devices. Keep Legrand 944559-1 (inter) as the name, possibly completed (Legrand 944559-1 (inter) Kitchen Spot), so as to keep the circuit number visible. It is the one that links to the logs and the rules; without it, you can’t find your way around. The « pretty » name is given in the dashboard, where each tile can have its own label (chapter 9).
Tip: You can choose not to add unprogrammed scenario buttons or switches that control nothing.
7. Understanding the Logs
Each line tells what is happening on the bus. The frames are in Open Web Net format *WHO*WHAT*WHERE##:
| Line | Direction |
|---|---|
Frame received: *1*1*0#15112945## (944559-1) |
a light button sent on (*1*1). Address 15112945 corresponds to circuit 944559-1. |
Frame received: *1*0*0#15112945## (944559-1) |
the same button sent off (*1*0). |
Light 944559-1 … is now on |
the status displayed in Gladys has changed. This line only appears if the status changes: pressing “on” twice only produces it once. |
Frame received: *25*11*0#10383459## (648966-3) |
a scenario button was pressed (*25*11). |
Scenario 648966-3 … clicked |
the corresponding Gladys button received a click. |
Frame received: *25*16*… |
end of scenario press, ignored. |
Linked light 944559-1 is now off (from 648966-3) |
a linked devices rule updated the status (chapter 8). Nothing is sent on the bus. |
Sent *1*0*#15112945## (944559-1 off) |
Gladys sent a command to the bus. The response *#*1## is the acknowledgment. |
The link between a frame and a device is the address: address = identifier × 16 + button number. 944559 × 16 + 1 = 15112945. The integration does the calculation and displays the circuit number in parentheses, you don’t have to do it.
8. The “Linked Devices” Rules
Why They Exist
In the In One system, only the buttons speak on the bus. A receiver (the relay that controls the lamp) listens to the buttons it has learned and reacts, without ever saying anything. Gladys cannot therefore know that a lamp is on: there is no frame for this, and no status request is possible.
Consequence: a device Legrand 648966-1 in Gladys is a button, not a lamp. When this button turns on the kitchen, the “Kitchen Spot” and “Kitchen Ceiling Light” devices remain displayed as off in Gladys, since their own buttons have not spoken. The rules correct this: they tell the integration which lights follow which button, in Gladys only. Nothing is sent on the bus.
The Two Forms of Rule
A light button on the left: the lights on the right copy its status.
648966-1 -> 944559-1, 944559-2
When button 648966-1 turns on (from the wall or from Gladys), 944559-1 and 944559-2 turn on in Gladys; when turned off, the same. This is the rule for a switch that controls multiple receivers, or for two switches that control the same lamp (two-way switch):
929520-1 -> 944561-1
929521-1 -> 944561-1
A scenario button on the left: each light takes the status written after =.
648966-3 -> 944559-1=off, 944559-2=off, 648966-1=off
A scenario has no on/off status, only a press: you therefore say what it does to each lamp (=on or =off). Remember to include the buttons that control these lamps (here 648966-1=off), otherwise the button status would remain displayed as on.
For an “all off” scenario, list all your lights:
950680-3 -> 944556-1=off, 944556-2=off, 944559-1=off, 944559-2=off, 944560-1=off, 944560-2=off, 944561-1=off, 944561-2=off, 648966-1=off, 929521-1=off, 929520-1=off, 929523-1=off, 929528-1=off
For a « turn everything off except the living room » scenario: same list, with 944560-1=on.
Practical Rules
- One rule per field (Rule 1 to Rule 12). More than 12 rules? Put several in one field, separated by
;. - Rules apply as soon as they are registered, without restarting.
- An invalid rule is ignored without error: if nothing happens, check the numbers.
- A link only applies to one level:
A -> BthenB -> Cdoes not propagate from A to C. This avoids loops. - To check a rule: press the button and look at the
Linked light … (from …)lines in the logs.
How to Find Out What Each Button Does
Take inventory room by room: for each switch and each scene, note which lamps actually turn on or off. This is the information that the integration cannot guess. A table like this helps:
| Button | Real Effect | Rule |
|---|---|---|
| 648966-1 (entrance, on/off) | turns on/off kitchen spot and ceiling light | 648966-1 -> 944559-1, 944559-2 |
| 950680-3 (scene 3) | turns off the whole house | 950680-3 -> … all =off |
| 950680-4 (scene 4) | turns on living room and dining room ceiling lights | 950680-4 -> 944560-1=on, 944560-2=on |
9. The Dashboard
In the dashboard, create « Devices » blocks per room and give each tile a readable name (Spot, Ceiling Light, Wall Light…). This is where the meaningful names take place, the device keeping its circuit number.
Scenario buttons can also serve as Gladys scene triggers: « when Legrand scenario 950680-3 is clicked, do… » (cut a plug, warn, etc.).
10. If It Doesn’t Work
- No frame in the logs: check
docker ps | grep legrand-serial, then that nothing else is connected to port 2000 (only one connection possible).docker restart legrand-serialfrees the gateway; the integration reconnects itself. ECONNREFUSED 172.17.0.1:2000: the gateway is not listening, or not on this address.- A lamp does not appear: its switch has not yet spoken, or it is on another electrical circuit (filter, another phase).
- The state of a lamp is wrong: a rule is missing, or the rule does not mention the correct button. The logs show the button that spoke.
- The command from Gladys does nothing: look at the
Sent …line and the response.*#*1##= accepted by the interface;*#*0##= refused. If it is accepted but nothing moves, the receiver has not learned this button.
Tested Hardware and Limits
Tested on my installation (22 devices): double switch 672 02, single switch 672 01, lighting scenario switch 672 08, scenario transmitter switch 672 80, Gladys 5.3 on Home Assistant Yellow. Other on/off switches in the range should work; dimmers only in on/off; shutters are not supported in this version. Feedback on other modules is welcome on the repository: GitHub - XDECO/gladys-integration-legrand-inone: Unofficial Gladys Assistant integration to control Legrand In One (PLC) lights through the Legrand 882 13 USB interface. · GitHub
Code under Apache-2.0 license, developed with the help of Claude (Anthropic) and validated on my installation. I am not a developer: reviews from confirmed developers are welcome.




