Matter Binding

Hi, what is the state of using OpenThread border router with the binding (as sole Matter controller)? Worth a shot, or should I wait a bit more?

This is all in the README , but OTBRs are supported and work fine, they just require a bit of extra work if you are using docker, a vm or even openHABian (see the part on ipv6 route annoucements), this does not have anything todo with openHAB per se, just making sure linux can route correctly.

its also a bit of a pain to pair a thread device to a OTBR, you need a mobile client, i have a POC for our IOS app i have been using, but i’m many months away from getting that into the openHAB app and also through some tough requirements by Apple to get the right permissions for it.

I’m not sure what you mean by ā€œsole Matter controllerā€ as a stock OTBR actually knows nothing of Matter, its simply there to get a thread device on your network.

Espressif has a OTBR build which does support the new Matter 1.4 Thread Cluster for configuration (so its both a OTBR and a Matter IP device hybrid) , so you add this as a matter device first over WiFi, then openHAB can configure the thread radio before you use it to commission thread devices on. AFAIK , openHAB may be the only Matter implementation on the market that supports this. I have 3 ESP32 running this build in my house right now. As you can see we offer a ton of configuration options for it…this is hopefully the future of how routers will be shipping thread radios in the coming years…

image

Yes, sorry I was mixing things up. I’ll give it a try then!

I installed the Matter binding on my fresh 5.0.0.M4 installation (openHABian, Raspi 4, 4GB)

My aim is to use it as a Matter bridge for controlling via Apple Home app.

After install, I then wondered how the bridge would be activated. Metadata in items were added. More or less nothing happened. Status of the bridge to be seen in the Add-on settings was ā€œstartingā€. Reset of the bridge did not work, only resulted in the status being ā€œstoppedā€.

The docs did not say I had to create a Matter thing for the bridge functionality, but I did not know for sure, so I created a controller thing that directly went into status ā€œHANDLER_MISSINGā€ with some errors in the logs.

After that, I decided to restart openHAB, and everything worked fine, the controller thing went ONLINE, the bridge started…

Just wanted to share that experience - if that is normal, it should would be worth mentioning it in the docs that you should do a restart of openHAB after binding installation.

I am not certain but that is more than probable.
Please provide the logs to help enhancing the binding, your bridge should have gone online without the need to restart OH.

Things have nothing to do with the bridge, so this has no affect.

Thats probably a bug, is was most likely started, i have seen this once, but have not been able to reproduce.

I don’t know what this means? What did not happen? What did you try? What was you expectation?

No, its not normal, and a binding should not require a restart of openHAB, the Matter binding has never required one either.

If you could be more specific about what was not working, and post logs that would be helpful.

I expected that after having items with matter metadata, I would see something in the logs like Matter bridge started or would be able to see a Thing corresponding to that or to see it being running in the settings. But that did not happen. And there was no coupling QR code in the settings, and my iPhone did not find the bridge in the network. It just kept ā€œstartingā€. It was unlike other add-ons or bindings, where you usually get a log message like

Thing xxxxx changed status to ONLINE
JavaScript scripting engine started
Cloud connection service started
Failed to....

This was at log level info and when I changed the log level to debug it was flooded so much that I could barely read anything, and could not find any errors.

The only way to understand the status was to look at the Settings, which is IMHO quite unusual. Please don’t get me wrong - I really appreciate all of your hard work to get this running and it is working now. I was just a little puzzled how to learn about the status. Maybe some explanatory words in the docs would help like:

No creating of a thing or item is needed for the Bridge service, just the add-on being installed. Status of the bridge can be read at the add-on settings. Bridge service will start as soon as items with valid Metadata as described above are available.

I will have to get the logs later at home and will post them.

Here come the logs.

First, after installation, I saw only this:

2025-07-15 22:01:32.996 [INFO ] [.matter.internal.bridge.MatterBridge] - No devices found to register with bridge, not starting bridge

I had no metadata added. Then I added metadata. And saw nothing, no log entries related to the Matter binding. Then I switched on log level debug in the Matter Add-On settings, and was flooded with this:

2025-07-15 22:32:25.597 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.603 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.605 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.606 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.612 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.619 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.621 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.623 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.623 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.625 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.627 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.632 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.634 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.639 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.639 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.641 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.641 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.648 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.648 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.650 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.652 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.656 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.657 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.657 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.657 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.664 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.670 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.672 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.672 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.673 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.674 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.675 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.676 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.680 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.680 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.681 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.682 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.684 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2025-07-15 22:32:25.689 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.700 [DEBUG] [r.internal.bridge.MatterBridgeClient] - bridgeEvent message {"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}
2025-07-15 22:32:25.700 [DEBUG] [r.internal.bridge.MatterBridgeClient] - onWebSocketText {"type":"event","message":{"type":"bridgeEvent","data":{"type":"eventTriggered","data":{"eventName":"commissioningWindowOpen","data":{"manualPairingCode":"30054912331","qrPairingCode":"MT:-24J0SC112280648G00"}}}}}
2

As I did not find anything useful and status of the matter bridge in the setting remained starting, I used the reset switch in the settings, then (I think) the status just kept ā€œstoppedā€.

Then I added the controller thing, as I thought that maybe that was needed, and got:


2025-07-15 22:44:40.011 [WARN ] [mmon.WrappedScheduledExecutorService] - Scheduled runnable ended with an exception: 
java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 10
	at java.util.ArrayList.add(Unknown Source) ~[?:?]
	at java.util.ArrayList.add(Unknown Source) ~[?:?]
	at org.openhab.binding.matter.internal.client.MatterWebsocketService.addProcessListener(MatterWebsocketService.java:96) ~[?:?]
	at org.openhab.binding.matter.internal.client.MatterWebsocketClient.connectWhenReady(MatterWebsocketClient.java:128) ~[?:?]
	at org.openhab.binding.matter.internal.bridge.MatterBridge.connectClient(MatterBridge.java:345) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:?]
	at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[?:?]
	at java.lang.Thread.run(Unknown Source) [?:?]
2025-07-15 22:45:39.037 [WARN ] [mmon.WrappedScheduledExecutorService] - Scheduled runnable ended with an exception: 
java.lang.ArrayIndexOutOfBoundsException: null
2025-07-15 22:48:21.151 [ERROR] [nal.common.AbstractInvocationHandler] - An error occurred while calling method 'ThingHandler.initialize()' on 'org.openhab.binding.matter.internal.handler.ControllerHandler@71202f62': null
java.lang.ArrayIndexOutOfBoundsException: null
2025-07-15 22:48:21.157 [ERROR] [core.thing.internal.ThingManagerImpl] - Exception occurred while initializing handler of thing 'matter:controller:4b82be1f58': null
java.lang.ArrayIndexOutOfBoundsException: null
2025-07-15 22:48:55.380 [ERROR] [nal.common.AbstractInvocationHandler] - An error occurred while calling method 'ThingHandler.initialize()' on 'org.openhab.binding.matter.internal.handler.ControllerHandler@4008c53e': null
java.lang.ArrayIndexOutOfBoundsException: null
2025-07-15 22:48:55.382 [ERROR] [core.thing.internal.ThingManagerImpl] - Exception occurred while initializing handler of thing 'matter:controller:4b82be1f58': null
java.lang.ArrayIndexOutOfBoundsException: null

Then I restarted openhab and everything went fine.

Thats helpful, looks like there a infinite loop somewhere very early in the startup, there should be only one of those messages, and since the bridge could not continue, there was nothing else to log as its stuck.

I have more of it, if you need.

Thanks, i was able to reproduce on a test system and have a PR already ready

https://github.com/openhab/openhab-addons/pull/18977

I have a contact sensor, after restarting openhab it changes state from NULL to OFF. I have added the sensor to google home via matter bridge. I have automation in google home, when it is ON, it send a notification - this works fine (I have the sensor in my PO Box so I know when it is open). Only after reboot openhab when the state changes from NULL to OFF, google home sends a notification too.

Is this something to fix on the matter bindings side? Gogle home sees NULL as ON? Thank you.

Use mapdb to persist the previous state and it will get restored on startup.

So a contact sensors default state is normally open, matter requires a boolean state, so we default to open (where ā€œopenā€ == ā€œfalseā€). The only other option would be to set the device offline until is has a non null state, but there is not code yet that does this for any device, so fairly large change.

you might want to have openHAB restore the previous state at startup so its not null at boot, see:

specifically the ā€œrestoreOnStartupā€ option.

Thank you, i have mapdb persistance for restoreOnStartup..

image

I have an Aquara contact sensor, in openhab it has a state ON for ā€œclosedā€ and OFF for ā€œopenā€ by default. When I send it as a matter device in this setting, google home shows open when it is closed and vice versa. I have a transformation in the item link to flip the values and then they show up correctly in google home. And finally google home in automation has openState in percent of open :slight_smile: I’ll wait for the ā€œofflineā€ option, thank you :slight_smile:

Thank you, i have persistance for restoreOnStartup. I’m wondering if the default state ā€œopenā€ or ā€œclosedā€ is better, if state is unknown..

Most contacts are ā€œnormally openā€, but obviously it differs depending on the environment. I’ll add an ā€œinvertā€ option to allow reversing the state, and maybe a default state option as well if unknown.

The default state option is good, thanks. For example, the door sensor is primarily closed and the default state ā€œopenā€ triggers the alarm when no one is home, even if the door is still closed.

Please, is it possible to set absMaxHeatSetpointLimit to 4000 for the thermostat in the bridge? Or to make absMaxHeatSetpointLimit equal to maxHeatSetpointLimit from the configuration?

I set maxHeatSetpointLimit to 4000, but absMaxHeatSetpointLimit defaults has 3500 and Google Home will allow me to enter max 35°C.

It is, its all in the README , you can customize any of the thermo limits by adding them to the Thermostat tagged item, and the example in the readme shows how those are added.

1 Like