home-assistant / home-assistant/android

Entity widget misdetects Wi‑Fi in background (usesInternalSsid=true, usesWifi=false) and incorrectly uses external URL

Open
#6,562 2 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Kotlin
Stars
3.9k
Forks
1.1k
Avg merge
1d 12h
Merged PRs (30d)
81

Description

**Home Assistant Android app version(s):**
2026.3.2-full (20802)

**Android version(s):**
16

**Device model(s):**
SM-S906U1
(Galaxy S22+)

**Home Assistant version:**
Core 2026.3.1
Supervisor: 2026.02.3
Operating System 17.1

**Last working Home Assistant release (if known):**
N/A

**Description of problem, include YAML if issue is related to notifications:**

Entity widget appears to mis-detect network state in the widget/background path and incorrectly choose the external URL.

My setup:
- Home Assistant works normally
- Companion app works normally
- External URL is DuckDNS behind nginx/SSL
- Internal URL is configured and matched by home SSID
- On home Wi-Fi, the main app correctly uses the internal URL
- Entity widget spins forever when tapped and does not toggle the entity

What seems important is that the foreground app and the widget disagree about whether Wi-Fi is active, on the same phone and same home network.

Foreground app logs show:
- `usesInternalSsid is: true, usesWifi is: true`
- `Using internal URL`

But when the widget is tapped, logs show:
- `usesInternalSsid is: true, usesWifi is: false`
- `Using external URL`

Because the widget chooses the external URL in that path, it then fails DNS resolution for my external hostname and the widget just spins.

Important detail:
- I am definitely connected to home Wi-Fi
- The HA app itself works normally at the same time
- I also tested with **mobile data disabled**, and the widget still logs `usesWifi is: false`

This makes me suspect the issue is not my HA server configuration, but the widget/background connection-state logic.

**Companion App Logs:**

03-10 22:52:31.143 27136 27136 D ServerConnectionStateProviderImpl: usesInternalSsid is: true, usesWifi is: true
03-10 22:52:31.143 27136 27136 D ServerConnectionStateProviderImplKt: Using internal URL

03-10 23:07:49.768 32188 32188 D ServerConnectionStateProviderImpl: usesInternalSsid is: true, usesWifi is: false
03-10 23:07:49.768 32188 32188 D ServerConnectionStateProviderImplKt: Using external URL

03-10 23:07:49.795 32188 32188 E EntityWidget: Unable to fetch entity
03-10 23:07:49.795 32188 32188 E EntityWidget: java.net.UnknownHostException: Unable to resolve host "*******.duckdns.org": No address associated with hostname
03-10 23:07:49.795 32188 32188 E EntityWidget: at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:124)
03-10 23:07:49.795 32188 32188 E EntityWidget: at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
03-10 23:07:49.795 32188 32188 E EntityWidget: at java.net.InetAddress.getAllByName(InetAddress.java:1152)
03-10 23:07:49.795 32188 32188 E EntityWidget: at okhttp3.Dns$Companion$DnsSystem.lookup(Dns.kt:50)

03-10 23:07:49.778 32188 2320 D NetworkChangeObserverImpl$observerNetworkChange: Register network callback
03-10 23:07:49.788 32188 2352 D NetworkChangeObserverImpl$observerNetworkChange: Unregister network callback

**Screenshot or video of problem:**
N/A

**Additional information:**

I think the likely issue is in the internal/external URL decision path.

Suspected code locations on current `main` branch:

- `common/src/main/kotlin/io/homeassistant/companion/android/common/data/network/WifiHelperImpl.kt`
- `isUsingWifi()`
- appears to use:
- `connectivityManager.activeNetwork`
- `getNetworkCapabilities(...)`
- `hasTransport(NetworkCapabilities.TRANSPORT_WIFI)`
- `isUsingSpecificWifi(...)`
- appears to use `WifiManager.connectionInfo` SSID/BSSID

- `common/src/main/kotlin/io/homeassistant/companion/android/common/data/servers/ServerConnectionStateProviderImpl.kt`
- `isInternal(requiresUrl: Boolean)`
- appears to require both:
- `usesInternalSsid = wifiHelper.isUsingSpecificWifi(connection.internalSsids)`
- `usesWifi = wifiHelper.isUsingWifi()`
- then logs:
- `usesInternalSsid is: $usesInternalSsid, usesWifi is: $usesWifi`
- and returns `usesInternalSsid && usesWifi`
- `getUrl(isInternal: Boolean)`
- if internal: logs `Using internal URL`
- else: logs `Using external URL`

- `common/src/main/kotlin/io/homeassistant/companion/android/common/data/network/NetworkChangeObserver.kt`
- `observerNetworkChange`
- appears to register a network callback, emit immediately, and unregister on close

- `app/src/main/kotlin/io/homeassistant/companion/android/widgets/entity/EntityWidget.kt`
- widget toggle path

My suspicion:
- In the widget/background path, SSID matching still works (`usesInternalSsid = true`)
- But `isUsingWifi()` returns false, even though the phone is on home Wi-Fi and mobile data is off
- That makes `isInternal()` return false
- Then the widget falls back to the external URL
- The resulting DNS lookup in that path does not behave the same as the foreground app path on my home network, so my external hostname does not resolve there and the widget spins forever

So the primary issue seems to be:
- widget/background path reports `usesWifi = false` when the device is actually on Wi-Fi

and the DNS failure is a downstream consequence of that wrong URL choice.

Repro steps:
1. Configure both internal and external URL
2. Configure home SSID so app uses internal URL on home Wi-Fi
3. Connect phone to home Wi-Fi
4. Confirm HA app works and logs `Using internal URL`
5. Add an entity widget that toggles a switch
6. Tap the widget
7. Widget spins indefinitely (in my case, because of hairpin NAT, but yours could work) -- even so, check the logs in step 8... this step 7 may or may not happen depending on your network config
8. Logs show `usesInternalSsid=true, usesWifi=false, Using external URL` (this should still happen to you)
9. Then `UnknownHostException` for the external hostname (again, this happens to me due to hairpin NAT, but may not happen to you).

My external URL works fine for my companion app (even on Home Wifi), because it correctly uses the DNS server I have setup which does rewriting for hairpin NAT. But, the problem is, because of this issue, I suspect that is why the widget does not use my network's DNS, and instead uses some other DNS... which runs into the problem.

At the end of the day, even setting an internal URL doesn't fix this, since the widget doesn't seem to be using the internal URL despite being on home wifi and mobile data disabled... even though the companion app is using it...

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.