PiPup fork + Home Assistant integration - popups, TTS, buttons, screen control on Android TV / Fire TV

I’ve been posting updates about my PiPup fork in the original PiPup thread ( PiPup - Android TV app for notifications ), but since several forks now live side by side there (@alex-savin maintains his own version too which is published in playstore too), that thread has become hard to follow. So here’s a dedicated topic for the version I created (with help of Claude), a maintained fork of GitHub - rogro82/PiPup: Enhanced notifications for Android TV · GitHub (all credit for the original idea to him), plus i’ve created a native Home Assistant integration for it too.

Everything is developed against a real household fleet: 8 TVs across Fire OS 9/11, Google TV 11 (TCL) and Android TV 14 (Nokia), so the platform quirks below aren’t theoretical.

What the app adds over the original

  • Indefinite popups, `duration: 0` keeps a popup up until you cancel or replace it, e.g. a doorbell camera stream for exactly as long as there is motion.

  • Popup `id` + update-in-place, re-sending the same popup only extends its timer; a playing video/web stream keeps running without flicker.

  • Buttons on popups, up to 3 remote-operable buttons; a press POSTs to a callback URL. Combined with the integration this becomes an HA event you can automate on (e.g. an *“Open the door”* button on the doorbell popup — callbacks are protected with single-use tokens, so nothing on your LAN can forge a press).

  • Text-to-speech, popups can speak (`tts`, optional `ttsLanguage`), using the TV’s own engine.

  • Muted media by default, audio in a popup can freeze live-TV playback on some devices, so video/web media plays silent unless you ask otherwise.

  • Styling, urgency presets (info/warning/critical) plus full border control (`borderColor`, `borderWidth`, `cornerRadius`), title/message sizes and colors, five positions.

  • Screen on/off over HTTP, `POST /power?state=on|off|toggle`. Waking always works (and switches CEC-linked TVs to the right input); standby needs a one-time grant (device admin, or an accessibility fallback for the many boxes that ship without device admin).

  • Self-update, the app checks my GitHub releases and can install updates itself (silent on Android 12+; older versions show the system dialog on the TV). The HA update entity drives this.

  • mDNS discovery, with a stable device id, so HA finds TVs automatically and follows them across DHCP changes.

  • Permission screen with Fix buttons, the app can’t grant its own permissions (that’s adb territory), but it shows the real state of every grant and jumps straight to the right system screen where one exists. Where a vendor ships a do-nothing placeholder instead (looking at you, Fire OS), it shows the exact adb command instead of a dead button.

  • Reliability work, overlay watchdog (a popup can never get stuck on screen), resilient web server startup, service restart after updates, guards against the vendor process-killers on low-RAM TVs.

`GET /state` and `GET /permissions/diagnose` tell you everything the app knows — the latter exists specifically so a bug report can carry facts instead of “it doesn’t work”.

Install: grab `install.sh` (Linux/macOS/WSL) or `install.ps1` (Windows) from the [releases page]( Releases · mhoogenbosch/PiPup · GitHub ) — they sideload the APK **and** grant the app-ops that an app can never grant itself (and that every `adb install -r` silently resets). Multiple TVs per run.

What the HA integration gives you

Add it in HACS as a custom repository (`mhoogenbosch/ha-pipup`, type Integration), restart, and TVs running the fork are discovered automatically. Each TV becomes a device with:

  • Actions, `pipup.show` (including `camera_entity` with an MJPEG mode that’s safe next to live TV, TTS, buttons, styling — all with per-TV defaults), `pipup.dismiss`, `pipup.fix_permission`.

  • Entities, popup / screen / connectivity sensors, a `notify` target, a **screen on/off switch**, an **update entity** with a working Install button, a dismiss button, default-position select, diagnostics.

  • A `pipup_button` event, for popup button presses — the doorbell-unlock automation is four lines.

  • Permission monitoring, a problem sensor plus an HA repair that can open the right settings screen on the TV for you, and honest errors that include the adb command when a device genuinely can’t do something remotely.

  • A diagnostics download that embeds the app’s own diagnosis — if you ever file a bug, that one file is all I need.

The README on the GitHub page has copy-paste examples: house-wide announcements with TTS, a doorbell popup with an unlock button, calendar reminders, and showing a camera for as long as there is motion.

Community

@Ltek built a Lovelace card for this integration: GitHub - Ltek/pipup-notify-card: Home Assistant Card for the PiPup Android app · GitHub - check it out.

Found a bug? Have an idea?

Please open an issue, that works far better for me than forum replies I might miss:

- App: Issues · mhoogenbosch/PiPup · GitHub

- Integration: Issues · mhoogenbosch/ha-pipup · GitHub

For anything permission- or update-related, include the output of `http://:7979/permissions/diagnose` or the integration’s diagnostics download, it usually pinpoints the cause immediately. Release notes are bilingual (EN/NL) and every version is documented in the changelogs.

And feature requests are genuinely welcome: several of the features above started as a user asking “would it be possible to…” — the custom borders, the screen on/off switch and the install scripts all came from one such message. If you have a fun or interesting idea, open an issue and I’ll happily see what I can do with it.

Enjoy!

update to today’s APK & Integrations. I get the error on screen on both TVs get Self-Update error. Permissions look fine and the



I creaded a new version with a few extra checks, could you try and install that and check? Then if it still shows missing flip the switch to off and back to on, it should correct itself. If this doesn’t work, please post the diagnostics information in a Github issue. (http://192.168.2.53:7979/permissions/diagnose)


Also just created a new version which handles updates a bit better.

@mhoogenbosch diagnose page below

Please test this case where the APK is not loading after the TV reboots after mains/wall poer is cut & restored.
Test Case Steps…

  1. Unplug and Replug the TV (remove mains / wall power).
  2. Do not ‘turn on’ the TV but give it time to ‘boot’ silently
  3. Turn On using ADB : TV will turn on

my results… PiPup app never starts, binary_sensor.living_room_tv_connectivity never shows connected until I manually open the APK in the TV’s App drawer. The keep-alive automation is not starting the app when in this state.

{"sdk":30,"device":{"model":"Smart TV Pro","manufacturer":"TCL","android":"11"},"permissions":{"overlay":true,"installPackages":false,"autoStart":false,"deviceAdmin":null,"accessibility":false,"complete":true,"fixable":{"overlay":true,"install":true,"admin":true,"accessibility":false}},"opModes":{"installPackages":"errored","overlay":"allowed"},"installCheckError":null,"user":"UserHandle{0}","targetSdk":34,"backgroundLaunchExempt":true,"activityVisible":false,"deviceAdminSupported":false,"screens":{"overlay":{"granted":true,"action":"android.settings.action.MANAGE_OVERLAY_PERMISSION","resolvedActivity":"com.android.tv.settings.device.apps.specialaccess.SystemAlertActivity","placeholder":false,"fixable":true,"adb":"adb shell appops set nl.rogro82.pipup SYSTEM_ALERT_WINDOW allow"},"install":{"granted":false,"action":"android.settings.MANAGE_UNKNOWN_APP_SOURCES","resolvedActivity":"com.android.tv.settings.device.apps.specialaccess.ExternalSourcesActivity","placeholder":false,"fixable":true,"adb":"adb shell appops set nl.rogro82.pipup REQUEST_INSTALL_PACKAGES allow"},"admin":{"granted":null,"action":"android.app.action.ADD_DEVICE_ADMIN","resolvedActivity":"com.android.tv.settings.deviceadmin.DeviceAdminAdd","placeholder":false,"fixable":true,"adb":"adb shell dpm set-active-admin nl.rogro82.pipup/.AdminReceiver"},"accessibility":{"granted":false,"action":"android.settings.ACCESSIBILITY_SETTINGS","resolvedActivity":"com.google.android.tv.frameworkpackagestubs.Stubs$SettingsStub","placeholder":true,"fixable":false,"adb":"adb shell settings put secure enabled_accessibility_services <huidige waarde>:nl.rogro82.pipup/nl.rogro82.pipup.PiPupAccessibilityService"}},"lastFix":{"what":"install","ok":true,"activity":"com.android.tv.settings.device.apps.specialaccess.ExternalSourcesActivity","error":null,"secondsAgo":395},"version":"0.11.0"}

Thanks — that diagnose output pins it down exactly, and the good news is that PiPup itself is working fine on your TV as you already mentioned.

What’s actually wrong

Only one thing is off: the *self-update* permission. Everything else is fine, `overlay: true` and `complete: true` mean popups work. But look at this line:

"opModes": { "installPackages": "errored", "overlay": "allowed" }

`errored` is not “not set yet”, it’s an app-op that your TV has put into an explicitly blocked state. That’s why `installPackages` is `false`, and why the Fix button didn’t help: your `lastFix` shows the button did open the “Install unknown apps” screen (`ok: true`, a real screen, no placeholder), but the toggle wouldn’t stick.

This is a TCL device restriction, not a PiPup bug. Several manufacturers lock “Install unknown apps” for sideloaded apps at the system level (Samsung’s “Auto Blocker” is the best-known example). The permission screen exists, but flipping the switch doesn’t take.

Why it can’t be fixed from the app or from Home Assistant

Granting this permission requires shell/system privileges (`appops`), which no normal app has, and Home Assistant runs off-device, so it can only ask the app to open the screen, not grant anything. So neither a button on the TV nor a button in HA can push past the `errored` state. Only adb can.

What to do

You have two options, and neither blocks using PiPup:

1. Grant it once over adb (this overrides the errored state directly):

adb shell appops set nl.rogro82.pipup REQUEST_INSTALL_PACKAGES allow

After that, `installPackages` flips to `true` and the in-app / Home Assistant update button works.

2. Skip self-update entirely and just sideload new versions by hand (e.g. via the Downloader app) when you want to update. Everything else in PiPup keeps working without this permission — it is only needed so the app can install its *own* updates.

Also worth a look: check whether your TCL has a global “unknown sources / security” blocker somewhere in its settings (analogous to Samsung’s Auto Blocker) — if so, turning that off may let the toggle stick without adb.

(Side note: the fact that your report shows `opModes`, `lastFix` and the resolved activity is thanks to the new `/permissions/diagnose` endpoint — exactly what it’s there for. Thanks for sending it, it made this a two-minute diagnosis.)

@Ltek Reproduced and fixed — thanks, that was a real gap.

Why: the app restarts itself on boot via a BOOT_COMPLETED receiver, but Android only broadcasts BOOT_COMPLETED once the device reaches a fully started, unlocked user session. A TV that boots to standby after a mains-power restore never gets there, and waking it over ADB is a wake event, not a boot event — so the receiver never fired and the service stayed down until you opened the app by hand.

Fix (app v0.12.0): the boot receiver and the service are now directBootAware and also listen for LOCKED_BOOT_COMPLETED, which fires in the early locked-boot phase — before turn-on. Prefs moved to device-protected storage so the device id (your HA unique_id) stays the same. Verified on a Fire TV: after a reboot with the remote untouched the service self-started ~27 s later. No HA changes needed — update the app or let it self-update.

Interim workaround if you want your keep-alive to cover it right now: trigger on the connectivity sensor going offline (while the TV is ADB-reachable) and launch the activity, not the service:
am start -n nl.rogro82.pipup/.MainActivity
An activity cold-launch works from any state; a service start can get filtered when the app hasn’t run since boot.

Its working much better with the latest fixes. This morning was the first time it properly 'started the APK install from HA’s UI. It turned on the TVs and prompted the user to install the APK… maybe we can get it to silent install?

Thanks, great to hear!! And I wish it was true, irt silent install:

  • On Android 12+ it’s already silent — the app sets USER_ACTION_NOT_REQUIRED, which the platform honors for a same-signature self-update, so no prompt appears.
  • On Android < 12 a silent install isn’t possible for a sideloaded app: the OS ignores USER_ACTION_NOT_REQUIRED and always shows its confirmation, unless the app is a system/privileged app, the device owner (MDM-provisioned), or the device is rooted. PiPup can’t grant itself any of those, so there’s no app-side fix — it’s a platform limitation.

If you want it fully hands-off on an older TV anyway, push the APK over ADB from Home Assistant instead of using the in-app updater: with ADB debugging enabled, adb install -r <apk> installs with no on-screen prompt on any Android version. You’d re-grant the two app-ops (SYSTEM_ALERT_WINDOW, REQUEST_INSTALL_PACKAGES) afterwards, since install -r resets them. That’s exactly how I keep my own fleet updated.

Your TV runs Android 11, so limited by platform. Recap: silent on 12+, prompt-based on older devices, and ADB as the escape hatch when you want zero interaction on an older TV.

I’ve added an instruction how to do this mhoogenbosch/ha-pipup: Home Assistant integration for PiPup (fork): show camera streams and notifications on Android TV for as long as you want

@Superpat There is a 0.14.1 version available which should solve your issue.

Hi @mhoogenbosch,

First of all, I can confirm that version v0.14.1 works fantastically well on my Xiaomi Laser Projector (Android 6.0.1)! Camera entities, snapshots, notifications, and interactive popup buttons are all working smoothly, just like on my TCL TV. Thank you so much!

While testing different stream sources, I noticed one remaining issue with direct RTSP streams:

  • Using HA camera entities (camera_entity) works without any problems.
  • Passing a direct RTSP stream (video_url: "rtsp://...") causes the app to crash immediately.

(Note: Direct RTSP streams were working without crashing on Alex Savin’s older app build).

Here is the logcat stacktrace captured during the RTSP stream crash on Android 6.0.1:

08-28 16:14:36.951  7983  7983 E AndroidRuntime: FATAL EXCEPTION: main
08-28 16:14:36.951  7983  7983 E AndroidRuntime: Process: nl.rogro82.pipup, PID: 7983
08-28 16:14:36.951  7983  7983 E AndroidRuntime: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
08-28 16:14:36.951  7983  7983 E AndroidRuntime: 	at android.view.ViewRootImpl.setView(ViewRootImpl.java:588)
08-28 16:14:36.951  7983  7983 E AndroidRuntime: 	at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:310)
08-28 16:14:36.951  7983  7983 E AndroidRuntime: 	at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
08-28 16:14:36.951  7983  7983 E AndroidRuntime: 	at android.app.Dialog.show(Dialog.java:319)
08-28 16:14:36.951  7983  7983 E AndroidRuntime: 	at android.app.AlertDialog$Builder.show(AlertDialog.java:1112)
08-28 16:14:36.951  7983  7983 E AndroidRuntime: 	at android.widget.VideoView$5.onError(VideoView.java:530)

Root cause: When VideoView encounters a playback issue or stream delay, stock Android attempts to display its built-in AlertDialog (“Can’t play this video”). Because PiPup operates from a background Service context, calling AlertDialog.show() fails with WindowManager$BadTokenException (token null is not for an application).

Adding a custom setOnErrorListener returning true on the VideoView instance (or handling it inside PipupService) would suppress the native error dialog popup and prevent the crash completely.

Would it be possible to address this RTSP playback crash in a future update? I would like to add a notification for a camera that is not added as an entity on HA.
Thanks

version 0.14.2 is incoming.

Here is a report based on testing version v0.14.3 on both a Xiaomi Laser Projector (Android 6.0.1) and a TCL Android TV (Android 8.0):

1. Camera Entities (camera_entity)

  • Notifications using Home Assistant camera entities (camera_entity) work as expected on both devices.

2. Direct RTSP Streams (video_url: "rtsp://...")

  • Direct RTSP streams fail to display on both devices. Below are the raw logcat logs captured during the playback attempts.

Logcat on Xiaomi Laser Projector (Android 6.0.1):

W MediaPlayer: Couldn't open file on client side; trying server side: java.io.FileNotFoundException: No content provider: rtsp://192.168.1.50:8554/cancello_sd
W MediaPlayer: info/warning (701, 0)
E MediaPlayer: error (1, -2147483648)
E MediaPlayer: Error (1,-2147483648)

Logcat on TCL Android TV (Android 8.0 - v0.14.1):

W MediaPlayer: Couldn't open rtsp://192.168.1.50:8554/cancello_sd: java.io.FileNotFoundException: No content provider: rtsp://192.168.1.50:8554/cancello_sd
E MediaPlayer: Error (1,-2147483648)
V MediaPlayer: resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
V MediaPlayer: cleanDrmObj: mDrmObj=null mDrmSessionId=null

3. Remote Control Navigation on Android 6.0.1

  • On the Xiaomi Projector (Android 6.0.1), while i launch the notification, the TV remote control navigation keys (D-pad, Back, Home) do not respond to the underlying launcher until the popup timer expires.

Note that with the PlayStore version of Alex Savin’s app that I tested previously, direct RTSP streams worked perfectly - have any streaming components/features been removed or changed from the original app?

Hope these logs and observations help with debugging!

Just released a new version, could you try this?

PiPup fork — what’s new since v0.13 (app) / v1.14 (Home Assistant integration)

A quick round-up for everyone following the fork (app · HA integration). All of this came out of reports from people here — thanks for those.

Camera popups that appear instantly (v0.17.0 / 1.15.0)
A live popup used to open as an empty box for a few seconds while the stream connected — the exact seconds that matter when someone is at the door. You can now pass a poster_url (a still image, e.g. your camera’s snapshot URL): it shows the moment the popup appears and fades into the live stream once it starts. If you use camera_entity, the integration does this automatically — no configuration needed.

RTSP and HLS streams now play (v0.15.0 – v0.16.0)
Video playback moved from Android’s stock player to ExoPlayer. That means a video_url can now be a direct RTSP stream from your camera (previously this crashed or showed nothing, as reported here) or an HLS / .m3u8 stream, e.g. from go2rtc or Frigate. Camera popups stay silent by default, so they no longer interfere with the audio of whatever is playing on the TV.

Runs on Android 6.0.1 (v0.14.x)
Requested for projectors: the app now installs and runs on Android 6 and up. Along the way a few crashes on old Android were fixed, and a popup no longer blocks the remote on those devices.

An icon beside the title (v0.13.0 / 1.14.0)
Notification-style: an icon image next to the title and message, left or right, with a configurable size.

Smaller things

  • Buttons on a popup now visibly show which one is focused (v0.12.2).
  • Installing an update from HA on a TV that can’t self-install silently (Android < 12) now wakes the screen and shows a confirm button, instead of stalling invisibly (v0.12.1 / 1.13.1).
  • The self-update always installs the newest release, not the last one it happened to check (v0.14.3).

Update the app on your TVs (it can do that itself from HA) and the integration via HACS. Full details and the Dutch versions are in the release notes on GitHub. Reports welcome — most of the above started as one.

Thanks for the continuous updates! I have completed cross-testing version v0.17.1 on both the TCL Android TV (Android 8.0) and the Xiaomi Laser Projector (Android 6.0.1).

Results:

  • TCL Android TV (Android 8.0): Live video popups play smoothly, and when the popup closes, the underlying TV/HDMI video source stays 100% smooth and fluid.
  • Xiaomi Laser Projector (Android 6.0.1):
    • Text-only & Snapshot Image popups: The underlying HDMI source stays 100% smooth.
    • Live Video popups (ExoPlayer): When the popup closes, the underlying HDMI source image freezes.

Raw Logcat from Xiaomi Projector during Teardown:

SurfaceFlinger: Stark: createLayer for (1 x 1), name=
SurfaceFlinger: Stark: createNormalLayer err(0), name=
MediaCodec: [OMX.amlogic.avc.decoder.awesome] setting surface generation to 9273359

This is what the AI ​​suggested to me, hope this empirical data and logcat help!:

Technical Cause & Proposed Fix:

The Xiaomi projector uses an Amlogic chipset (OMX.amlogic.avc.decoder.awesome with Stark surface layers). Tearing down a hardware SurfaceView overlay upon ExoPlayer release causes the Amlogic hardware decoder to lose surface generation sync with the primary HDMI decoder pipeline.

Using a TextureView instead of a SurfaceView (or offering a fallback flag for Android < 8 / Amlogic) for the ExoPlayer view will prevent ExoPlayer teardown from disrupting the primary Amlogic HDMI video decoder pipeline.

Thanks again

Patrick

Thanks Patrick, that’s very useful data. One correction to the suggestion: ExoPlayer has rendered into a TextureView (not a SurfaceView) since 0.15.1, so the layer type isn’t it. Your logcat points at the Amlogic hardware decoder itself (OMX.amlogic.avc.decoder.awesome): on Amlogic the HDMI-in path and MediaCodec share the same video layer, and releasing our decoder makes HDMI-in lose its surface — a well-known family of Amlogic decoder issues in ExoPlayer. Fix in the next release: on Android < 8 / Amlogic, PiPup will decode video in software (bypassing the vendor decoder), plus a softwareDecoder flag to force it either way, and a cleaner teardown. Software decoding is fine for a camera sub-stream; a 1080p main stream may be heavy on the projector.0.17.2 will be out in a few mins, please test and see if that works better.

PiPup fork — what’s new since v0.17 (app) / v1.15 (Home Assistant integration)

A lot landed this week, almost all of it driven by reports from users here and on GitHub — thank you for those. Round-up (app · HA integration):

No more empty popups while a stream connects (0.17.0 / 1.15.0)
A live camera popup used to open as an empty box for the seconds the stream needed to start. You can now pass a poster_url (a still, e.g. your camera’s snapshot URL): it shows instantly and fades into the live video on its first frame. Popups sent with camera_entity get this automatically.

Fixed: closing a video popup froze the HDMI picture on some projectors/TVs (0.17.2)
On Amlogic-based devices (several projectors, Android ≤ 8) the vendor’s video decoder shares a video layer with the HDMI input, and releasing it froze the picture behind the popup. Video is now decoded in software on those devices (automatic; softwareDecoder overrides). Field-confirmed on a Xiaomi laser projector.

Popups over the screensaver + a notification chime (0.18.x / 1.16.0)
When the screensaver / ambient mode is showing, PiPup now ends it before showing the popup, so nothing stays invisible. And there’s an optional sound: "default" plays a built-in chime, or give a URL to your own clip — played once per popup, never repeated when a motion popup refreshes itself.

Make popups look the way you want (0.19.x / 1.17.x)
animation (fade or slide from any side, reversed when the popup expires), buttonSize (small buttons for small popups — everything scales together), and padding (down to a near-borderless look). All also available as per-TV defaults in the HA integration.

Reliability

  • The integration’s popup sensor now reflects a popup immediately after showing it, so automations can react to popups within a second (e.g. updating a doorbell popup with a recognised name).
  • A failed self-update now tells you why in /state and in the HA update entity, instead of silently doing nothing.
  • TCL Google TV owners: if PiPup keeps dropping offline on your set, the installers now enable PiPup’s (dormant) accessibility service by default — that turns out to be the one state TCL’s app-killer leaves alone. One owner went from disconnects every few hours to rock solid with that single change.

Update the app on your TVs (it can do that itself from HA) and the integration via HACS. Full details and Dutch versions in the release notes. Keep the reports coming — nearly everything above started as one.

PiPup fork — what’s new since v0.19 (app) / v1.17 (Home Assistant integration)

A few updates since last post, again mostly driven by your reports — keep them coming. Round-up (app · HA integration):

Camera popups: the poster now waits for the actual video (0.20.x)
The poster/still introduced in 0.17 used to fade out when the stream page loaded — not when the video actually played, so on slower TVs you could still catch an empty black box. The popup now watches the page itself and keeps the still on screen until the first real video frame, however long that takes. No configuration needed; it also reports the measured hand-over time in /state if you’re curious.

Which stream should a camera popup use? Now documented
We measured the common routes (WebRTC, RTSP, MJPEG, HLS) across a mixed fleet and wrote the results into the README. Short version: WebRTC (go2rtc) + a poster is the sweet spot — the poster hides its slow start, and you keep its sub-second live delay. MJPEG starts fastest but runs 2–3 s behind reality, which you notice at a doorbell.

The TV now tells you when the integration is behind (0.21.0 / 1.18.0)
The app’s status screen shows which ha-pipup version is talking to it, which one is recommended (always the latest release, fetched automatically) and the minimum it needs — one glance tells you if the HA side needs an update. The integration announces itself on every request, so this fills in by itself.

Self-update fixed on Android 6 (0.19.3 + 0.21.1)
Older devices (Android < 7.1.1, e.g. some Xiaomi projectors) couldn’t self-update: they’re missing the root certificate GitHub’s download servers use. The app now bundles that one public root — and 0.21.1 fixes the subtle part: the download goes through a redirect, and the first fix never reached that hop. One last manual install via adb, and from the next release the in-app Install button should work there too. Full detective story in issue #41.

Reliability, field-confirmed
The TCL keep-alive from the last post (the installers enabling PiPup’s dormant accessibility service) has now been confirmed by the reporter after multi-day testing: from disconnects every few hours to rock solid. If your TCL still drops offline, re-run the installer.

Update the app on your TVs (it can do that itself from HA) and the integration via HACS. Full details and Dutch versions in the release notes. As always: nearly everything above started as a report from someone here.