Thread network diagnostics tool, anyone using it yet?

I tried it… and found out the plugs I thought use thread are matter over wifi. Ooops. I do also have some Eve plugs which show up nicely.

I ran the diagnostic json through ChatGPT which stated that my Google Nest Hub is running thread stack version 1.0.0 and causing instability in my thread network.

Has anyone received similar results?

My thread network is unified and consists of the following TBR’s: ST hub, google tv streamer 4k, and google nest hub 2nd gen.

I expected the google streamer to be the one running an early thread stack version. Not the Nest Hub.

I ran the json against ChatGPT as well, but it didn’t find anything all that interesting except one device that was operating ok on the Thread level, but not at the Matter level.

  1. :white_check_mark: Thread layer is fine
    • it routes

    • it participates in mesh

  2. :cross_mark: Matter layer is degraded
    • SmartThings can’t fully manage it

I’m really liking the new tool in combination with ChatGPT.

My network was working fine but not optimally. I’ve now isolated the Nest Hub thread radio by moving it to my guest wifi network and onto a separate “home” and google account so the thread credentials don’t comingle.

The diag tool gives you the MAC Extended Address for a device’s identity but that is not exposed in ST in either the AWA or via the CLI. So, if you want to map that to your actual devices in ST, you need the output from a service discovery looking for _matter._tcp devices. That will give you output like this:

=  ens33 IPv6 4576FE5C14395B2F-70DDD7356FF5182D             _matter._tcp         local
   hostname = [E2554077D4CB9A04.local]
   address = [fd0f:77ee:44e0:1:f3d6:ac6e:7b4d:7167]
   port = [5540]
   txt = ["T=0" "SAI=800" "SII=800"]

What you’ll see is that the hostname is the MAC Extended Address plus “.local”. You can then cross-reference that with the Instance Name/Network ID in ST.

Front Porch - Top         Home            4576FE5C14395B2F-70DDD7356FF5182D        E2554077D4CB9A04.local         fd0f:77ee:44e0:1:f3d6:ac6e:7b4d:7167                         

But to save you the trouble of doing all that manually, I’ve written a Python script that gathers all the data and outputs a nice table of your Matter devices:

DEVICE LABEL              LOCATION        INSTANCE NAME/NETWORK ID                 HOSTNAME                       IPv6 ADDRESS                             IPv4 ADDRESS        
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Eve Energy Outlet         Home            4576FE5C14395B2F-995C0E468F772727        CE32695FF668AB29.local         fd0f:77ee:44e0:1:80f1:cbaa:a6fe:3040                         
Front Porch - Top         Home            4576FE5C14395B2F-70DDD7356FF5182D        E2554077D4CB9A04.local         fd0f:77ee:44e0:1:f3d6:ac6e:7b4d:7167                         
Hutch Right - Top         Home            4576FE5C14395B2F-3CD883BEBA9F8B78        867CF1514911B0C1.local         fd0f:77ee:44e0:1:ff36:ffff:c489:bd43                         
Living Room Front - Top   Home            4576FE5C14395B2F-D6D3F6E58B6A9EDC        FE36252FAE750578.local         fd0f:77ee:44e0:1:87d7:d726:d7f7:dd5c                         
Smart Color Night Light   Home            4576FE5C14395B2F-97141DDAB5353877        A81710CF6E77.local             2600:1700:dce0:4790:aa17:10ff:fecf:6e77  192.168.1.89        
Tapo Mini Plug            Home            4576FE5C14395B2F-2BA6E0537BBA51D5        40AE30A5CCDB.local             2600:1700:dce0:4790::1f                  192.168.1.231       
Deck                      Lake House      A8CDF21E11FC069F-9CA8A41CF664B1E4        UNKNOWN                                                                                     
Dining Room Light         Lake House      A8CDF21E11FC069F-771D88250C1D4E2B        UNKNOWN                                                                                     
Family Room Light         Lake House      A8CDF21E11FC069F-53B1459994E462CA        UNKNOWN                                                                                     
Fireplace                 Lake House      A8CDF21E11FC069F-2D7E9B3B07FDF5BB        UNKNOWN                                                                                     
Front Porch               Lake House      A8CDF21E11FC069F-F9DF408D70F1F14F        UNKNOWN                         

Since this does a local dns-sd for service discovery, devices in ST won’t show detailed info if you’re not on the local network with those devices. Also uses the ST CLI which you can download here.

Script can be downloaded here. Written for Debian Linux but should be able to be tweaked for other OS’s. Ask chat-gpt to help you :slight_smile:

This is awesome!

@Declankh you should mention that in your original post.

Thank you for the script!

Also, I see that you have an Eve Energy Outlet. I have three in-wall Eve Outlets which, according to ChatGPT’s review of the diagnostics json, are problematic and having lots of errors. I’ve since removed them.

The Eve Energy plugs seem to work well.

Did you get similar results?

I have the plug-in Eve Energy Outlet and 3 of the duplex in-wall Eve Energy outlets. Yes, chat-gpt complained about the in-wall units having issues but it attributed that to the fact that I have 3 different Thread networks and two Wi-Fi networks in my house all fighting for the same RF spectrum. I have no problem with controlling any of the devices so I’m not sure to make of chat-gpt’s analysis.

If you are not experiencing any issues, then it seems there isn’t any action needed.

In my case, I wasn’t having any issues either. But I wanted to understand my thread network and optimize it. Which I have done. Plus I wanted to understand overall, real world best practices.

Besides devices and automations being slightly snappier, I haven’t seen any major differences. But I now have a clearer understanding of what is happening behind the scenes.

Patch to use avahi-browse instead of dns-sd:

--- matter-map.py	2026-04-27 09:44:40.447434569 +0000
+++ matter-map-avahi.py	2026-04-27 09:46:20.175583422 +0000
@@ -17,6 +17,7 @@
 def run(cmd):
     return subprocess.check_output(cmd, text=True, stderr=subprocess.DEVNULL)
 
+
 def get_locations():
     locations = json.loads(run(["smartthings", "locations", "-j"]))
     id_to_name = {}
@@ -28,6 +29,7 @@
 
     return id_to_name, name_to_id
 
+
 def get_matter_devices(location_id=None):
     cmd = ["smartthings", "devices", "--type", "MATTER", "-j"]
     if location_id:
@@ -45,47 +47,94 @@
             "label": d.get("label", "UNKNOWN"),
             "instance": network_id,
             "locationId": d.get("locationId"),
-            "hostname": "",  # will be filled by DNS
+            "hostname": "",  # will be filled by DNS-SD discovery
             "ipv4": "",
             "ipv6": "",
         })
 
     return results
 
+
+def unescape_avahi_label(value):
+    """Undo avahi-browse -p escaping for service names/labels.
+
+    avahi-browse uses DNS label escaping. This function handles both
+    backslash-escaped single characters (e.g. '\\;') and 3-digit decimal
+    escapes (e.g. '\\032' for space).
+    """
+    out = []
+    i = 0
+    while i < len(value):
+        ch = value[i]
+        if ch != "\\":
+            out.append(ch)
+            i += 1
+            continue
+
+        if i + 3 < len(value) and value[i + 1:i + 4].isdigit():
+            out.append(chr(int(value[i + 1:i + 4], 10)))
+            i += 4
+        elif i + 1 < len(value):
+            out.append(value[i + 1])
+            i += 2
+        else:
+            out.append("\\")
+            i += 1
+
+    return "".join(out)
+
+
 def get_dns_sd_data(debug_dns=False):
-    cmd = ["dns-sd", "-t", "-r", "_matter._tcp"]
+    """Discover Matter services using Avahi instead of dns-sd.
+
+    Uses avahi-browse in parsable mode so the output is stable and easy to
+    consume from scripts.
+    """
+    cmd = ["avahi-browse", "-rtpk", "_matter._tcp"]
     if debug_dns:
         print(f"[DEBUG] Running command: {' '.join(cmd)}")
     output = run(cmd)
-    lines = output.splitlines()
 
     data = defaultdict(dict)
-    current = None
-    instance_re = re.compile(r"=\s+\S+\s+(IPv4|IPv6)\s+(\S+)\s+_matter\._tcp")
 
-    for line in lines:
-        m = instance_re.match(line)
-        if m:
-            current = m.group(2)
+    for raw_line in output.splitlines():
+        line = raw_line.strip()
+        if not line or not line.startswith("="):
             continue
 
-        if not current:
+        # Resolved parsable format from avahi-browse:
+        # =;iface;proto;name;type;domain;host;address;port;txt
+        parts = line.split(";", 9)
+        if len(parts) < 9:
+            if debug_dns:
+                print(f"[DEBUG] Skipping unparsable avahi line: {raw_line}")
             continue
 
-        if "hostname =" in line:
-            data[current]["hostname"] = line.split("[")[1].split("]")[0]
-        elif "address =" in line:
-            addr = line.split("[")[1].split("]")[0]
+        _, _iface, _proto, instance, service_type, _domain, hostname, addr, _port, *_rest = parts
+
+        if service_type != "_matter._tcp":
+            continue
+
+        instance = unescape_avahi_label(instance)
+        hostname = hostname.strip()
+        addr = addr.strip()
+
+        if hostname:
+            data[instance]["hostname"] = hostname
+
+        if addr:
             if ":" in addr:
-                data[current]["ipv6"] = addr
+                data[instance]["ipv6"] = addr
             else:
-                data[current]["ipv4"] = addr
+                data[instance]["ipv4"] = addr
 
     return data
 
+
 # ---------------- hostname cache ----------------
 hostname_cache = {}  # hostname -> (ipv4, ipv6, timestamp)
 
+
 def resolve_hostname_cached(hostname):
     now = time.time()
     if hostname in hostname_cache:
@@ -98,7 +147,7 @@
         # Resolve IPv4
         result = run(["avahi-resolve", "-n", "-4", hostname]).strip()
         if result and "\t" in result:
-            ipv4 = result.split("\t")[1]
+            ipv4 = result.split("\t", 1)[1]
     except subprocess.CalledProcessError:
         ipv4 = ""
 
@@ -106,13 +155,14 @@
         # Resolve IPv6
         result = run(["avahi-resolve", "-n", "-6", hostname]).strip()
         if result and "\t" in result:
-            ipv6 = result.split("\t")[1]
+            ipv6 = result.split("\t", 1)[1]
     except subprocess.CalledProcessError:
         ipv6 = ""
 
     hostname_cache[hostname] = (ipv4, ipv6, now)
     return ipv4, ipv6
 
+
 # ---------------- help ----------------
 def print_help():
     print("""Usage: matter-map [LOCATION] [OPTIONS]
@@ -124,7 +174,8 @@
   --help            Show this help message and exit
   --sort=FIELD      Sort by field: label, location, instance, hostname, ipv4, ipv6
   --reverse         Reverse sort order
-  --debug-dns       Print debug info for DNS queries""")
+  --debug-dns       Print debug info for Avahi/DNS-SD queries""")
+
 
 # ---------------- main ----------------
 def main():
@@ -175,12 +226,13 @@
     devices = get_matter_devices(location_id)
     dns_data = get_dns_sd_data(debug_dns)
 
-    # Merge DNS SD data into devices
+    # Merge DNS-SD data into devices
     for d in devices:
         dns = dns_data.get(d["instance"], {})
         d["hostname"] = dns.get("hostname", "UNKNOWN")
         d["ipv4"] = dns.get("ipv4", "")
         d["ipv6"] = dns.get("ipv6", "")
+        d["location"] = id_to_name.get(d.get("locationId"), "UNKNOWN")
 
     # Resolve missing dual-stack IPs in parallel
     to_resolve = [d for d in devices if d["hostname"] != "UNKNOWN"]
@@ -193,13 +245,13 @@
                 d["ipv4"] = ipv4 or d["ipv4"]
                 d["ipv6"] = ipv6 or d["ipv6"]
             except Exception:
-                d["ipv4"], d["ipv6"] = d["ipv4"], d["ipv6"]
+                pass
 
     # Sort and group
     devices.sort(key=lambda r: r.get(sort_key, ""), reverse=reverse)
     grouped = defaultdict(list)
     for r in devices:
-        grouped[r.get("locationId") and id_to_name.get(r["locationId"], "UNKNOWN") or "UNKNOWN"].append(r)
+        grouped[r.get("location", "UNKNOWN")].append(r)
 
     # Print output
     print(
@@ -219,5 +271,6 @@
                 f"{r['ipv4']:<20}"
             )
 
+
 if __name__ == "__main__":
     main()

Very cool!

Thread Mesh Report with SmartThings Device Mapping (click here)

Thread Mesh Report with SmartThings Device Mapping

Executive summary

This snapshot shows a large, healthy, but uneven Thread mesh. The network contains 32 visible Thread nodes: 16 routers and 16 child devices. By matching the Matter hostnames from the SmartThings/Matter map to the extMacAddr / extAddress values in the Thread diagnostics JSON, most visible Thread nodes can now be assigned real SmartThings device names.

The most important findings are:

Finding Meaning
16 active routers The routed Thread mesh is large and intact.
16 child devices A substantial number of battery/sleepy or child-mode devices depend on parent routers.
32768 is the dominant border router It advertises NAT64 and the on-mesh prefix.
36864 / Buttons is likely the Thread Leader It has leaderCost = 0 and matching leader/router data.
54272 / Küchenlampe is the main parent router It carries 7 children, the largest child domain in this snapshot.
Several edge links are weak or asymmetric The mesh works, but not all RF relationships are equally strong.

1. Mapping quality

The Matter map and Thread diagnostics align very well. The reliable mapping key is:

Matter hostname without ".local" = Thread extMacAddr / extAddress

Example:

B687xxxxxxxxxxxx.local → b687xxxxxxxxxxxx → Nachttischlampe

Out of the Matter entries:

Category Count Interpretation
Matter entries total 49 All Matter devices/endpoints seen by SmartThings
Entries with hostname 35 Locally discoverable via mDNS/DNS-SD
Hostnames matched to Thread nodes 30 Real Thread nodes
Hostnames without Thread match 5 Matter-over-IP / Wi-Fi / Ethernet / bridge devices
UNKNOWN entries 14 Very likely bridged endpoints

The UNKNOWN entries are especially important: most share the same Network ID base as one Matter Bridge. They are therefore very likely bridged endpoints, not separate Thread devices.


2. Infrastructure and border routing

Two infrastructure nodes stand out:

RLOC16 Role SmartThings mapping
15360 / 0x3c00 Default-route / border-routing node no Matter device label
32768 / 0x8000 Main border router, NAT64, on-mesh prefix, parent no Matter device label

The current network data makes 32768 the dominant border-routing node:

Function Node
Default route 32768 and 15360
NAT64 prefix 32768
On-mesh prefix fdxx:xxxx:xxxx:1::/64 32768
SLAAC / preferred / default-route flags 32768

So 32768 is not just another router. It is the central Thread/IP infrastructure node in this snapshot.


3. Likely Thread Leader

The likely Thread Leader is:

RLOC16 Device Host
36864 / 0x9000 Buttons 323Exxxxxxxxxxxxxx.local

Reason: this node has leaderCost = 0, and its leader/router identity matches router ID 36, which corresponds to 36864 >> 10.

This does not mean it is the best radio node or the main traffic hub. The Thread Leader manages network state; packet forwarding may still happen mostly elsewhere.


4. Router role overview

RLOC16 Device Role Children Assessment
5120 Nachttischlampe Router 0 usable, but poor relationship to 15360
15360 Infrastructure / default route 0 very clean from own perspective
18432 Cam 3 Steckdose Router 0 some suspicious neighbor errors
20480 Cam 2 Steckdose Router 0 mixed, but usable
22528 Badezimmerlampe Edge router 0 clear fringe candidate
25600 Schlafzimmerlampe Edge router 0 weak individual links
26624 Luftqualitätssensor Router + parent 2 good parent, some edge noise
28672 Ventilator Router 0 mostly unobtrusive
32768 Border router + parent 1 strongest infrastructure role
33792 Kühlschrank Router + parent 2 good parent
35840 Ventilator Router + parent 1 parent, but noisy router links
36864 Buttons Leader + parent 1 likely Leader, moderate RF
37888 Stehlampe Edge router 0 weak individual links
44032 Luftqualitätssensor Router 0 some suspicious links
54272 Küchenlampe Main parent router 7 most important parent domain
57344 Wohnzimmerlampe Router + parent 2 stable near-core parent

The most important device-level insight is that several normal-looking SmartThings devices are actually structurally important Thread routers. In particular, Küchenlampe, Wohnzimmerlampe, Kühlschrank, Buttons, and both Ventilator devices are part of the routed Thread fabric.


5. Parent-child structure

The largest parent domain is clearly:

Parent Device Children
54272 Küchenlampe 7

Other parent domains:

Parent Device Children
26624 Luftqualitätssensor 2
32768 Infrastructure BR 1
33792 Kühlschrank 2
35840 Ventilator 1
36864 Buttons 1
57344 Wohnzimmerlampe 2

This means Küchenlampe is the most important parent router in the current mesh. If that device is moved, unplugged, or suffers RF problems, the local impact could be much larger than its SmartThings label suggests.


6. Most important child devices

Child Device Parent Link assessment
54276 Button 2 Küchenlampe weakest child link
54280 BILRESA dual button 2 Küchenlampe elevated FER
36865 BILRESA scroll wheel Buttons low margin, elevated FER
57345 Wohnzimmerfenster Wohnzimmerlampe very good
54335 GRILLPLATS plug 1 Küchenlampe excellent link, unusual rx-on MTD role
33795 Bewegungsmelder Kühlschrank very good
33798 Wasserlecksensor Kühlschrank usable, more edge-like

The most suspicious child link is:

Button 2 → Küchenlampe
Link Margin: 17
RSSI: -83 dBm
FER: 38.3%
MER: 4.5%

If Button 2 shows delayed or missed events, this RF relationship is a strong candidate.


7. Weak spots and asymmetry

The mesh is not uniformly strong. Several routers report very poor relationships toward 15360, even though 15360 itself reports clean neighbor metrics.

Examples:

From Device To FER MER
5120 Nachttischlampe 15360 96.0% 47.6%
22528 Badezimmerlampe 15360 93.9% 33.6%
35840 Ventilator 15360 97.4% 24.1%
25600 Schlafzimmerlampe 15360 95.3% 20.5%
18432 Cam 3 Steckdose 15360 80.5% 16.4%

This should be interpreted carefully. It does not prove that 15360 is bad. It more likely indicates directional asymmetry, different measurement windows, or accumulated retry/error history.

The weakest router candidates are:

Device RLOC16 Why
Badezimmerlampe 22528 low margins, high errors
Schlafzimmerlampe 25600 weak individual links
Ventilator 35840 very high error relationships
Nachttischlampe 5120 poor relationship to infrastructure node
Stehlampe 37888 edge-like, weak individual links

These are the areas to watch if the mesh shows intermittent behavior.


8. Matter devices not part of the visible Thread mesh

These Matter devices have hostnames/IP addresses but are not visible as Thread nodes:

Device Hostname Likely transport
Aqara G350 54EFxxxxxxxxx.local Matter-over-IP
Computer C4E7xxxxxxxx.local local IP
Matter Bridge BC0xxxxxxxx.local Matter-over-IP bridge
Matter Bridge BC0xxxxxxxx.local Matter-over-IP bridge
TV-Steckdose C4E7xxxxxxxx.local Matter-over-IP

This is expected. Matter can run over Thread, Wi-Fi, Ethernet, or bridges. Only Thread nodes appear in the Thread mesh diagnostics.


9. Practical interpretation

This is not a broken Thread mesh. It is a large and functioning mesh with a clear infrastructure layer, a likely leader, several good parent routers, and a meaningful amount of RF asymmetry at the edges.

The main operational takeaways are:

  1. Küchenlampe is more important than it looks.
    It is currently the parent for seven child devices.

  2. Buttons is probably the Thread Leader.
    That does not make it the best router, but it is important for Thread network state.

  3. 32768 is the key border-routing node.
    It advertises NAT64 and the on-mesh prefix.

  4. Several edge devices have weak or asymmetric links.
    Especially Badezimmerlampe, Schlafzimmerlampe, Ventilator, Nachttischlampe, and Button 2.

  5. Bridge endpoints should not be confused with Thread nodes.
    The UNKNOWN SmartThings devices are very likely bridged endpoints, not missing Thread devices.


Final conclusion

The combination of the Matter map and Thread diagnostics turns the network from an anonymous mesh into a readable SmartThings topology.

The most important sentence is:

This Thread mesh is structurally healthy, but its center of gravity is currently around 32768 for border routing, 36864 / Buttons for the Leader role, and 54272 / Küchenlampe for child aggregation. The weak spots are not the mesh as a whole, but specific edge and child links.

This is extremely interesting. Replaced the problematic Nanoleaf Essentials M/T bulb with an IKEA KAJPLATS bulb. This is the result:

Thread mesh comparison after replacing Nanoleaf with IKEA bulb (click here)

Thread mesh comparison after replacing Badezimmerlampe

I compared the previous Thread snapshot with the new diagnostics_2.json and matched the Matter device list again by:

Matter hostname without ".local" = Thread extMacAddr / extAddress

The key change is clear: the old Badezimmerlampe disappeared as Thread router C64A3BXXXXXXXXXX / RLOC16 22528 / Router ID 22, and the new Badezimmerlampe appeared as 6ECF22XXXXXXXXXX / RLOC16 12288 / Router ID 12. The mesh still has 16 active routers, so one routed node was replaced by another; the routed mesh did not shrink or collapse.

Executive summary

The replacement improved the Badezimmerlampe position in the Thread mesh, but it did not magically fix every weak area of the network.

Area Before: old Badezimmerlampe After: new Badezimmerlampe Assessment
RLOC16 22528 / 0x5800 12288 / 0x3000 New routed identity
Router ID 22 12 Router set changed
Thread version 4 5 Improved / newer Thread stack exposure
Stack OPENTHREAD/1.0.0; EFR32 SL-OPENTHREAD/2.6.1.0; EFR32 Major stack generation change
Active routers in mesh 16 16 Mesh size stable
Neighbor entries 13 15 Improved visibility/connectivity
LQ 1 / 2 / 3 4 / 4 / 3 3 / 9 / 3 Fewer weak links, more medium-quality links
Average router-neighbor margin 15.8 19.4 Better
Minimum router-neighbor margin 0 6 Much better
Worst FER 82.2% 70.8% Better, but still high
Worst MER 14.6% 6.6% Clearly better
Child devices 0 0 No parent-role change

The new IKEA bulb is therefore a better Thread router than the old Nanoleaf bulb in this location, especially because it no longer has a zero-margin neighbor and sees more neighboring routers. However, it is still not a perfect/core router: it remains an edge-ish router with several modest links and one still-problematic relationship toward 15360.


1. What changed structurally?

The router set changed by exactly one router:

Change Old New
Removed router 22528 / Router ID 22 / C64A3XXXXXXXXXXXX -–
Added router -– 12288 / Router ID 12 / 6ECFXXXXXXXXXX

The Route64 mask changed from:

04012xxxxxxx0480

to:

0409xxxxxxx480

That is exactly what you would expect when one router ID leaves and another router ID joins. The number of active routers remains 16, and the network data still shows the same overall border-routing structure: default-route information via 32768 and 15360, NAT64 via 32768, and the on-mesh prefix advertised by 32768.

So this is not a new Thread network. It is the same mesh after a routed-node replacement and reconfiguration.


2. The new Badezimmerlampe is clearly better than the old one

Direct router comparison

Metric Old Badezimmerlampe / Nanoleaf New Badezimmerlampe / IKEA Meaning
RLOC16 22528 12288 New router identity
Router ID 22 12 Router table changed
Neighbor count 13 15 New device sees more routers
Average link margin 15.8 19.4 Better RF neighborhood
Minimum link margin 0 6 Old device had a near-dead link; new one does not
Max frame error rate 82.2% 70.8% Still high, but improved
Max message error rate 14.6% 6.6% Strong improvement
LQ 1 links 4 3 Fewer weak links
LQ 2 links 4 9 Many more usable medium links
LQ 3 links 3 3 Same number of strong links

The most important improvement is the minimum link margin. The old bathroom bulb had at least one neighbor relationship at link margin 0, which is effectively at the floor. The new IKEA bulb’s worst visible margin is 6, which is still weak, but no longer a zero-margin edge case.

The second important improvement is neighbor visibility: the old bulb had 13 router neighbors; the new one has 15. It gained visible relationships to Stehlampe / 37888 and Wohnzimmerlampe / 57344. That makes it better integrated into the routed fabric.


3. Neighbor-by-neighbor comparison for Badezimmerlampe

This is the most useful direct comparison, because it shows where the new device improved and where it did not.

Neighbor Device Old margin / RSSI New margin / RSSI Old FER/MER New FER/MER Result
5120 Nachttischlampe 11 / -89 24 / -76 0.0% / 0.0% 0.0% / 0.0% Much better signal
15360 Infrastructure 10 / -90 12 / -88 82.2% / 14.6% 70.8% / 6.6% Better, but still bad
18432 Cam 3 Steckdose 9 / -91 22 / -78 0.0% / 0.0% 0.0% / 0.0% Much better
20480 Cam 2 Steckdose 0 / -102 13 / -87 6.5% / 0.0% 0.0% / 0.0% Major improvement
25600 Schlafzimmerlampe 18 / -82 28 / -72 0.0% / 0.0% 0.8% / 0.0% Better signal
26624 Luftqualitätssensor 16 / -84 11 / -89 0.0% / 0.0% 10.3% / 0.8% Worse
28672 Ventilator 10 / -90 9 / -91 0.0% / 0.0% 0.0% / 0.0% Similar / weak
32768 Border router 17 / -83 17 / -83 29.3% / 0.2% 32.4% / 2.7% Similar signal, worse errors
33792 Kühlschrank 7 / -93 17 / -83 0.0% / 0.0% 0.0% / 0.0% Much better
35840 Ventilator 23 / -77 20 / -80 0.0% / 0.0% 0.0% / 0.0% Slightly worse
36864 Buttons 51 / -49 49 / -51 5.3% / 0.0% 15.2% / 0.0% Strong signal, but more FER
44032 Luftqualitätssensor 13 / -87 20 / -80 0.0% / 0.0% 0.0% / 0.0% Better
54272 Küchenlampe 21 / -79 22 / -78 17.7% / 0.1% 3.0% / 0.0% Better
37888 Stehlampe not visible 6 / -94 -– 0.8% / 0.0% New weak neighbor
57344 Wohnzimmerlampe not visible 21 / -79 -– 3.1% / 0.0% New useful neighbor

The biggest wins are toward Cam 2 Steckdose, Cam 3 Steckdose, Nachttischlampe, Kühlschrank, Schlafzimmerlampe, Luftqualitätssensor / 44032, and Küchenlampe. The one relationship that still looks bad is toward 15360, although even that improved substantially in message error rate.


4. What improved in the overall mesh?

4.1 The bathroom router is no longer the clear fringe outlier

Before the replacement, Badezimmerlampe was one of the most obvious edge/fringe routers. It had very low margins, a zero-margin neighbor, and high error rates. After replacement, it still has some weak links, but it is no longer as problematic.

The new IKEA bulb is better described as:

a usable edge router with broader mesh visibility

rather than:

a weak fringe router

That is a real improvement.

4.2 More router-neighbor connectivity

The new device sees 15 router neighbors instead of 13. In a 16-router mesh, that is quite good. It does not mean all links are strong, but it does mean the new bulb is visible to almost the entire routed fabric.

4.3 Better minimum signal floor

The old bathroom router had at least one link margin 0 relationship. The new bathroom router’s minimum visible margin is 6. That is still weak, but it is a much better floor.

4.4 Better Thread stack / version

The new bathroom bulb reports:

SL-OPENTHREAD/2.6.1.0_GitHub-7f6723ffb; EFR32; Jun 18 2025

The old one reported:

OPENTHREAD/1.0.0; EFR32; Nov 25 2024

So the new device appears to expose a newer Silicon Labs OpenThread stack and Thread version 5 in the diagnostics. That is a meaningful modernization.


5. What did not improve?

5.1 The mesh still has asymmetric weak relationships

The old snapshot already showed several very high directional error rates, especially toward 15360. The new snapshot still has that pattern.

For the new Badezimmerlampe specifically:

to 15360:
Link margin: 12
RSSI: -88 dBm
FER: 70.8%
MER: 6.6%

This is better than before, but still weak. It suggests the new device can participate in the mesh more successfully, but the RF path toward 15360 remains poor.

5.2 Some child links got worse after reattachment

The child topology changed significantly. Some children moved to new parents, and not all of those moves improved link quality.

The most concerning examples:

Child device Old parent New parent Margin change FER change Assessment
Schlafzimmerfenster 32768 Küchenlampe 32 → 23 0.3% → 35.7% Clearly worse
Bewegungsmelder Buttons Ventilator 41 → 29 0.4% → 17.3% Worse
Button Wohnzimmertisch Wohnzimmerlampe 32768 43 → 29 3.7% → 7.4% Worse, but still usable
Button 2 Kühlschrank Küchenlampe 22 → 20 46.5% → 47.7% Still problematic
Bewegungsmelder Küchenlampe Kühlschrank 30 → 38 2.2% → 32.9% Better margin, worse FER

So the replacement improved the bathroom router itself, but the mesh rebalanced in ways that shifted child devices around. Some of those child moves are beneficial; others are not.


6. Parent-domain changes

The parent-child distribution changed a lot.

Before

Parent Device Children
20480 Cam 2 Steckdose 1
32768 Border router 1
33792 Kühlschrank 1
36864 Buttons 2
54272 Küchenlampe 6
57344 Wohnzimmerlampe 5

After

Parent Device Children
26624 Luftqualitätssensor 5
32768 Border router 1
33792 Kühlschrank 1
35840 Ventilator 1
36864 Buttons 1
54272 Küchenlampe 6
57344 Wohnzimmerlampe 1

The most important shift is that Luftqualitätssensor / 26624 became a major parent router, taking over five children. Meanwhile Wohnzimmerlampe / 57344 dropped from five children to one. The overall number of child devices stayed at 16.

This means the mesh did not lose child devices. It redistributed them.


7. Child-device migration table

Device Before After Result
BILRESA dual button 2 57344 Wohnzimmerlampe 26624 Luftqualitätssensor Better margin, slightly lower FER
BILRESA scroll wheel 57344 Wohnzimmerlampe 26624 Luftqualitätssensor Lower margin, lower FER
Türschloss 57344 Wohnzimmerlampe 26624 Luftqualitätssensor Clearly better margin and lower MER
BILRESA scroll wheel 2 57344 Wohnzimmerlampe 26624 Luftqualitätssensor Better margin, lower FER/MER
BILRESA dual button 54272 Küchenlampe 26624 Luftqualitätssensor Better margin, lower FER
Bewegungsmelder 54272 Küchenlampe 33792 Kühlschrank Better margin, but much higher FER/MER
Bewegungsmelder 36864 Buttons 35840 Ventilator Worse
Wasserlecksensor 36864 Buttons 36864 Buttons Same parent, new child RLOC; still good
Wohnzimmerfenster 20480 Cam 2 Steckdose 57344 Wohnzimmerlampe Similar margin, slightly higher FER
Button Wohnzimmertisch 57344 Wohnzimmerlampe 32768 Border router Worse margin, still usable
Schlafzimmerfenster 32768 Border router 54272 Küchenlampe Clearly worse
Button 2 33792 Kühlschrank 54272 Küchenlampe Still the weakest child link

The biggest positive migration is the cluster that moved to Luftqualitätssensor / 26624. That router became much more important after the replacement. The biggest negative migration is Schlafzimmerfenster, which moved to Küchenlampe with much worse error behavior.


8. Current most important routers

After the replacement, the most important structural nodes are:

Node Device Role
32768 Infrastructure Border router, NAT64, on-mesh prefix
36864 Buttons likely Thread Leader
54272 Küchenlampe still major parent with 6 children
26624 Luftqualitätssensor newly important parent with 5 children
57344 Wohnzimmerlampe still router/parent, but much less child load
12288 Badezimmerlampe new routed node, improved over old bathroom bulb

The new Badezimmerlampe is not a major parent and not a leader. Its value is different: it improves the routed fabric by replacing a weak fringe router with a broader, better-connected router.


9. What improved most?

Most improved: Badezimmerlampe itself

The device replacement worked. The new IKEA bulb is a better Thread router in this location than the previous Nanoleaf bulb.

Best improvements:

  • no more zero-margin neighbor
  • more visible router neighbors
  • better average link margin
  • lower worst message error rate
  • newer Thread/OpenThread stack
  • useful new visibility to 57344 and 37888

Also improved: parent load distribution away from Wohnzimmerlampe

Previously, Wohnzimmerlampe carried five children. Now it carries one. That may reduce load and local dependency on that router.

Also improved: Luftqualitätssensor became a strong parent domain

26624 now carries five children. Several of those have good margins, especially:

  • BILRESA dual button: margin 39
  • BILRESA dual button 2: margin 37
  • Türschloss: margin 34
  • BILRESA scroll wheel 2: margin 30

That looks like a useful new child cluster.


10. What got worse or still needs attention?

Button 2 is still the weakest child link

Button 2 moved from Kühlschrank to Küchenlampe, but did not improve.

Before:

Margin 22, FER 46.5%, MER 5.6%

After:

Margin 20, FER 47.7%, MER 8.6%

So Button 2 remains the most suspicious child device. If it misses presses or reacts slowly, the RF link is still the prime suspect.

Schlafzimmerfenster got worse

Schlafzimmerfenster moved from 32768 to Küchenlampe.

Before:

Margin 32, FER 0.3%

After:

Margin 23, FER 35.7%

That is a clear degradation.

The 15360 relationship remains odd

The new Badezimmerlampe still has a weak/error-heavy relationship toward 15360, although it improved compared with the old one. This seems to be part of a broader asymmetry pattern in the mesh rather than a problem unique to the bathroom bulb.


11. Overall verdict

Replacing Badezimmerlampe from the old Nanoleaf bulb to the new IKEA bulb improved the Thread mesh, but mostly by improving one routed node, not by fixing every weak relationship.

The best summary is:

The old Badezimmerlampe was a weak fringe router. The new Badezimmerlampe is still not a core router, but it is a noticeably better and more broadly connected edge router.

The mesh remains structurally healthy:

  • still 32 visible Thread nodes
  • still 16 active routers
  • still 16 child devices
  • same core border-router structure
  • no lost child devices
  • one router replaced cleanly
  • significant parent rebalancing occurred

The main positive change is the replacement of a poor router with a better one. The main side effect is that child devices reattached in new ways, creating a new parent distribution centered around Küchenlampe and Luftqualitätssensor / 26624.

Final conclusion

Yes, the replacement improved the Thread mesh.
The new IKEA bathroom bulb is better integrated, has stronger minimum link quality, sees more neighbors, uses a newer Thread stack, and no longer behaves like the severe fringe router the old Nanoleaf bulb appeared to be. The mesh is healthier at that point.

However, the remaining weak spots are now elsewhere: especially Button 2, Schlafzimmerfenster, and some asymmetric relationships involving 15360. So the replacement was a good improvement, but not a complete RF cleanup of the whole Thread mesh.

@mocelet @Declankh Replace your Nanoleaf bulbs! :wink:

ChatGPT, please generate a downloadable PDF report:

Screen_Recording_20260427_182404_Drive-ezgif.com-optiwebp

I’d certainly consider it if it improved stability and also was of similar or better performance.

I’m using the Nanoleaf e27 colour bulbs, how do colour and brightness and colour temperature compare to Nanoleaf? I typically used these in 5000k white or in red for home cinema mode.

It’s totally subjective, but I prefer the IKEA bulbs. You should try for yourself.

Might do, but they are never in stock in my local store these days.

Yeah, they’re missing in action at the moment. Nanoleaf is working on the Thread 1.4 update, hopefully they’ll fix the Matter bugs and smoothness of transitions.

Just ordered more than enough to replace the remaining NL bulbs. Couple of spares of each model for good measure. Should be at my doorstep on Thursday.

:innocent:


Tip: download the device list from the AWA, give it ChatGPT and the report will be much more detailed.

Result (ChatGPT diagnostic session over the span of about a week):

The IKEA bulbs appear to be better Thread routers in your mesh because the improvement is visible in both firmware generation and mesh-quality metrics. The old Nanoleaf bulbs generally appeared as Thread version 4 devices with OPENTHREAD/1.0.0; EFR32, while the IKEA replacements appear as Thread version 5 devices with SL-OPENTHREAD/2.6.1.0; EFR32. More importantly, the measured router behavior improved clearly: better minimum link margins, better link-quality distribution, fewer extreme weak links, and lower worst-case error behavior.

Replaced device Old Nanoleaf stack / Thread version New IKEA stack / Thread version Key improvement
Badezimmerlampe OPENTHREAD/1.0.0; EFR32 / v4 SL-OPENTHREAD/2.6.1.0; EFR32 / v5 Better integrated edge router
Schlafzimmerlampe OPENTHREAD/1.0.0; EFR32 / v4 SL-OPENTHREAD/2.6.1.0; EFR32 / v5 Much stronger router fabric participation
Stehlampe OPENTHREAD/1.0.0; EFR32 / v4 SL-OPENTHREAD/2.6.1.0; EFR32 / v5 No longer a weak/edge-like router

The link-quality comparison makes the improvement clearer:

Device position Avg router-neighbor margin before Avg router-neighbor margin after Minimum margin before Minimum margin after Worst error behavior before Worst error behavior after
Badezimmerlampe ~15.8 ~19.4 0 6 ~82% FER / 14.6% MER ~70.8% FER / 6.6% MER
Schlafzimmerlampe ~18.5 ~26.7 0 7 ~50.9% FER / 4.5% MER ~8.0% FER / 0.0% MER
Stehlampe ~18.8 ~31.5 0 13 ~5.2% FER / 0.0% MER ~1.6% FER / 0.0% MER

The most striking improvement is the minimum link margin. The Nanoleaf bulbs had at least one near-dead or zero-margin router relationship in those positions. The IKEA bulbs removed those zero-margin links. That matters because a Thread router does not need to be perfect, but it should not be a barely-connected fringe node if it is part of the routed mesh.

The link-quality distribution also improved:

Device position LQ distribution before LQ distribution after Meaning
Badezimmerlampe 4 / 4 / 3 3 / 9 / 3 Fewer weak links, many more usable medium links
Schlafzimmerlampe 3 / 5 / 5 2 / 2 / 11 Big shift toward strong links
Stehlampe 2 / 2 / 6 1 / 2 / 10 Much stronger router-neighbor profile

So the conclusion is not just “IKEA is newer.” The measured mesh behavior actually changed. The IKEA bulbs became cleaner, stronger Thread routers in exactly the locations where the Nanoleaf bulbs looked weak or edge-like. They have not necessarily become major parent routers yet, but they improve the backbone of the Thread mesh: more reliable route options, fewer weak router relationships, and a healthier routed fabric overall.

I tried to open the Thread Network Diagnostics app today but it won’t open.

Has anyone been able to use it today?

Working fine for me.