Matter Binding

This is a problem/bug with the binding being loaded from the marketplace. When the UI loads the configuration when its installed from the marketplace, is uses the URI /rest/addons/161138/config?serviceId=marketplace, the returned config has a string with a value as a double format for our discriminator:

{
    "enableBridge": true,
    "qrCode": "MT:-xxx",
    "resetBridge": false,
    "manualPairingCode": "xxx",
    "openCommissioningWindow": false,
    "bridgeName": "openHAB Matter Bridge v1",
    "passcode": "00000",
    "discriminator": "616.0"
}

If the binding is installed in the addons folder, the UI uses the endpoint /rest/addons/binding-matter/config?serviceId=jar and the correctly formatted int value is returned (as a number type) .

{
    "enableBridge": true,
    "qrCode": "MT:-xxx",
    "resetBridge": false,
    "manualPairingCode": "xxx",
    "openCommissioningWindow": false,
    "bridgeName": "openHAB Matter Bridge v1",
    "passcode": "00000",
    "discriminator": 616
}

I have not dealt with the Marketplace code at all, but it seems like a bug there.

@Lolodomo are you familiar with this code at all ?

Not at all, it is the first time I am using the marketplace!

Me to. @J-N-K sorry to bug, do you have an idea on why the thing binding configuration would be formatted different when installed from the Marketplace ? :point_up: The conversion of a int to a string double seems like a GSON json parsing thing ( i think it defaults numbers to doubles?).

Iā€˜ll have a look, but I donā€™t have the slightest idea why there would be a difference depending on the installation method.

1 Like
{
  "resetBridge": false,
  "discriminator": 1351
}

Using latest snapshot I installed the matter binding from the marketplace and got this as response for https://localhost:8443/rest/addons/161138/config?serviceId=marketplace, which seems to be correct.

After changing the discriminator in the UI the response is:

{
  "resetBridge": false,
  "discriminator": "1355.0"
}

So the issue is not related to the marketplace itself, because what is stored in matter.config is

:org.apache.felix.configadmin.revision:=L"2"
discriminator="1355.0"
resetBridge=B"false"
service.pid="org.openhab.matter"

The reason is that the PUT endpoint de-serializes to a Map<String, Object> and there a number defaults to a Double. We probably need to call ConfigUtil.normalizeTypes in that method before writing to storage.

Edit: we already do that. We just fail to retrieve the correct config-description. Iā€™ll fix that.

2 Likes

FYI: Fix config normalization in addon configuration by J-N-K Ā· Pull Request #4528 Ā· openhab/openhab-core Ā· GitHub

5 Likes

Thats for fixing that so quick! Not sure i would of been able to track that one down.

1 Like

Iā€™m excited that OpenHAB is getting Matter support. I wanted to share my experiences.

1. Docker Image Compatibility:

  • The Matter binding does not work for me with the Alpine image in Docker. The following error appears in the log: [DEBUG] [ternal.client.MatterWebsocketService] - Node process exited with code: 127
  • This issue does not occur with the Debian-based image.

2. Integration of AVM FRITZ!Smart Gateway:

  • I tried to integrate an AVM FRITZ!Smart Gateway using the Matter Binding. The device is recognized but the thing remains in offline status due to an error.
  • Error: COMMUNICATION_ERROR java.lang.NullPointerException: Cannot invoke "Object.toString()" because "value" is null
[DEBUG] [r.internal.handler.ControllerHandler] - Could not update node 8545226543932240244
java.util.concurrent.CompletionException: java.lang.NullPointerException: Cannot invoke "Object.toString()" because "value" is null
        at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:315) ~[?:?]
        at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:320) ~[?:?]
        at java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:722) ~[?:?]
        at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[?:?]
        at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147) ~[?:?]
        at org.openhab.binding.matter.internal.client.MatterWebsocketClient.lambda$1(MatterWebsocketClient.java:234) ~[?:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) [?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
        at java.lang.Thread.run(Thread.java:840) [?:?]
Caused by: java.lang.NullPointerException: Cannot invoke "Object.toString()" because "value" is null
        at org.openhab.core.library.types.DecimalType.<init>(DecimalType.java:64) ~[?:?]
        at org.openhab.binding.matter.internal.controller.devices.converter.WiFiNetworkDiagnosticsConverter.initState(WiFiNetworkDiagnosticsConverter.java:70) ~[?:?]
        at org.openhab.binding.matter.internal.controller.devices.types.DeviceType.lambda$1(DeviceType.java:109) ~[?:?]
        at java.util.HashMap.forEach(HashMap.java:1421) ~[?:?]
        at org.openhab.binding.matter.internal.controller.devices.types.DeviceType.initState(DeviceType.java:109) ~[?:?]
        at org.openhab.binding.matter.internal.handler.MatterBaseThingHandler.lambda$1(MatterBaseThingHandler.java:306) ~[?:?]
        at java.util.HashMap$Values.forEach(HashMap.java:1065) ~[?:?]
        at org.openhab.binding.matter.internal.handler.MatterBaseThingHandler.updateBaseEndpoint(MatterBaseThingHandler.java:306) ~[?:?]
        at org.openhab.binding.matter.internal.handler.NodeHandler.updateBaseEndpoint(NodeHandler.java:164) ~[?:?]
        at org.openhab.binding.matter.internal.handler.NodeHandler.updateNode(NodeHandler.java:169) ~[?:?]
        at org.openhab.binding.matter.internal.handler.ControllerHandler.updateNode(ControllerHandler.java:344) ~[?:?]
        at org.openhab.binding.matter.internal.handler.ControllerHandler.lambda$1(ControllerHandler.java:261) ~[?:?]
        at java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:718) ~[?:?]
        ... 9 more
[DEBUG] [.matter.internal.handler.NodeHandler] - setEndpointStatus OFFLINE COMMUNICATION_ERROR java.lang.NullPointerException: Cannot invoke "Object.toString()" because "value" is null

The gateway is connected via LAN and not WiFi, which is likely why the rssi value is null.

Additional Information:

  • Hardware and Virtualization: Docker on a KVM-virtualized machine
  • Operating System: Ubuntu 24.04
  • Network Configurations: Docker network in host mode, two ethernet interfaces on the host
  • OpenHAB Version: openhab/openhab:4.3.1
  • Read the Matter README: Yes
  • Is this an issue with the controller or bridge feature: Controller

Thank you for your work on this binding and your support.

This is a known issue with the alpine image, we need to pre-load a node runtime on that image, downloading at runtime is not an option as the image does not contain the required libc dependencies.

Iā€™m guessing you are running this on the Debian Image? Can you switch to TRACE logging? There should be communication to the matter server in the logs which would help tremendously (specifically right up to this error, probably a big JSON blob) , if you could PM that to me that would be great (it will be a really large json blob)

I just uploaded a new jar which should fix the error you are seeing (the rss value is null, uhg)

Hi @digitaldan ,

Fyi, The remaining lock battery seems to be correctly getting updated. But it need correct formatting to show correct $age.

For my lock it is showing 0.96000000 for 96% remaining battery.

unit=% should solve that:

To be checked if unitHint was set for this battery channel.

What is the channel type ?

I think this is the issue, this is what we have on the channel

<state readOnly="true" pattern="%d %%"/>

Is it this channel type?

Itā€™s a plain Number so it doesnā€™t have a unit. unitHint is nice to have for Number:Dimensionless.

Looking at the core channel type battery-level they are using different patterns, i.e. %d %% vs. %.0f %% but thatā€™s shouldnā€™t matter:

Maybe the same issue as for humidity which was initially divided by 100 before a fix.
If plain number is used, yes, unitHint is useless.

The code is sending a percent type, halfPercentValue is a value from 0-200 (hence the half-percent units)

        return new PercentType(halfPercentValue / 2);

EDIT: and now that i look at it, i need to prevent a zero division possible error.

I should probably change this channel to match and use a float format since you can have half percent values, like 50.5%

The problem with PercentType is that the value is divided by 100 when you get it as DecimalType. That is probably the issue.

Ahh, gotcha, iā€™m still not clear what the right solution is then :frowning:

@digitaldan I was made aware of this solution to make shelly devices speak matter.

After getting the matter bridge-shelly up and running and discovering all of my shelly devices on it, I now have 14 shelly devices trying to connect to your binding :slight_smile:

I managed to get the shelly bridge discovered in openhab but it stays offline with the following error: ā€œThing ā€˜matter:endpoint:beb3436780:2488850213006715957_1ā€™ changed from OFFLINE (COMMUNICATION_ERROR): java.lang.NullPointerException: Cannot read field ā€œdeviceTypeListā€ because ā€œclusterā€ is null to UNINITIALIZEDā€

I still have some difficulties in understanding how to parse the logs so I tried to disable and reenable the shelly matter controller thing while gathering as much as I could.
Hope you can take a look:
shelly-MatterbridgeLogs.txt (731.1 KB)