Skip to content
CASIENT
←  KNX notes

The light works, but the app says it is on when it is off. Why?

Why a KNX light shows the wrong state in Home Assistant

This is the single commonest defect we find, it is almost never noticed at commissioning, and it surfaces months later as "the app is wrong" with nobody able to say why.

Note
01 / 06
Reading
5 min
Updated
September 2026
For
Integrators

The symptom

Someone switches the kitchen lights at the wall. The app still says off. Or they switch them in the app, the lights come on, and an hour later the app has lost track. Nothing is broken — the lights work perfectly — and no amount of restarting Home Assistant helps for longer than a day.

What is actually happening

A KNX channel usually exposes at least two communication objects: one the bus writes to in order to command the output, and one the device transmits on to report what the output is doing. The first is the switching object. The second is the status object, and it is optional in the sense that nothing fails without it.

If only the switching object has a group address, the bus never carries any statement about what that light is doing. Home Assistant handles that the only way it can: it assumes the command worked and displays what it last sent. That assumption is correct right up until the state changes by any route the integration did not initiate — a wall switch, a scene stored in the actuator, a central-off, a staircase timer expiring, a power cycle.

So the app is not wrong at random. It is wrong specifically after somebody uses the house.

Why it gets missed

Because everything you can check on site passes. You press the button, the light comes on. You walk the house with a laptop and every output responds. The defect is not an output that fails; it is the absence of a statement about an output that works.

In ETS it is visible, but only if you open the device, look at the object list, and notice that the object at, say, number 52 has no group address on it. On a 33-device project that is a few hundred objects to eyeball, and nobody does it because nothing is prompting them to.

Do not classify on the name

The obvious approach is to search the project for objects called “Status” and check whether they are bound. This works on the project you tested it against and fails on the next one.

function_text is what the manufacturer chose to call the object, and across real projects it is “Status” here, “Rückmeldung” there, “Feedback” somewhere else, and blank far more often than anyone expects. Some products put the word in the channel name instead. A classifier built on those strings is a classifier built on a different vendor’s copywriting.

Read the flags instead. They are not localised and they are not optional:

  • A status object is one the device transmits on, and one the bus cannot write to.
  • A command object is one the bus writes to.

That distinction is true of every certified product, in every language, and it is the only thing here worth building a judgement on.

Fixing it in ETS

  1. Open the device and find the object whose flags say transmit-but-not-write for the channel in question.
  2. Give it a group address in your status range.
  3. Set the datapoint type. For a switched output that is DPT 1.011, not 1.001 — 1.011 is DPT_State. The obvious guess is the wrong one, and it is wrong consistently. (See group addresses with no datapoint type.)
  4. Re-download the device, and confirm on the group monitor that operating the output at the wall produces a telegram.

Step 4 is the one that matters. A status object with an address on it that never transmits is the same defect wearing a hat.

The part that is worth money

Do this once and you have fixed a light. The useful move is finding every instance in the project at once — including the channels where the status object exists in the product, was never bound, and nobody has ever noticed because the room in question is a hallway somebody walks through twice a day.

That is a question about the gap between what each product in your project declares it can do and what this installation actually wired. Every .knxproj carries the manufacturer’s full application program for every device in it, so the answer is already sitting in the file. It simply has never been asked.

What the check does with this

Upload the project and you get device coverage: for every device, how many communication objects the product declares, how many were bound, and specifically how many of the status objects went unused.

Where the evidence is unambiguous — one bound command on the channel, no bound status, and a declared status object sitting there unused — it proposes the binding. Where the channel bundles several outputs, as a DALI gateway’s line does, it reports the observation and leaves it to you, because pairing a command to its status by channel is a heuristic and pretending otherwise would manufacture findings.

Nothing is written to your project. It is a reading, and the fixes are yours to accept or reject in ETS.

What the check reports for this

Device coverage — every status object the product declares, against the ones this installation actually wired.

Upload a .knxprojFree, permanently · no card · ≈ 60 s