Skip to content

Releases: CheapDevotion/ThinkViewKiosk

v33 — software volume for play_media, fixes all-or-nothing

Choose a tag to compare

@CheapDevotion CheapDevotion released this 12 May 17:19

What's in v33

`set_volume` now drives a per-sample software gain inside MediaPlayer rather than mapping to STREAM_ALARM index. Fixes the all-or-nothing behavior we hit live: STREAM_ALARM's volume curve on the Lenovo CD-18781Y is so steep that mid-range values are effectively inaudible.

Volume model

  • `set_volume 0.4` stores 0.4 in pref `media-volume`
  • Next `play_media` pegs STREAM_ALARM to hardware max, then applies `MediaPlayer.setVolume(0.4, 0.4)` — a linear software multiplier
  • 0.4 actually sounds like 40%
  • `stop_media` restores STREAM_ALARM to whatever it was before

Security siren and Spotify Connect volume paths are unaffected (independent code paths, independent volume controls).

v32 — enable backdrop-filter (glassmorphism) in GeckoView

Choose a tag to compare

@CheapDevotion CheapDevotion released this 11 May 18:59

What's in v32

GeckoView 95 (Firefox 95 from Dec 2021) ships `backdrop-filter` behind a flag — disabled by default. HA dashboards using the glassmorphism / frosted-glass pattern (`backdrop-filter: blur(...)`) had that declaration silently no-op on our kiosks.

v32 writes a Gecko user_prefs file at runtime startup that flips `layout.css.backdrop-filter.enabled` to true. `backdrop-filter` now renders correctly.

Note on `filter` vs `backdrop-filter`

  • `filter: blur(2px)` — blurs the element itself. Always worked in Firefox 35+. If this still isn't visible, the issue is elsewhere (e.g. element has no visible content, or the style is overridden by a more specific selector).
  • `backdrop-filter: blur(2px)` — blurs what's behind a translucent element. The frosted-glass effect. Required v32 to work.

If you're applying the frosted-glass look, the element needs:
```css
backdrop-filter: blur(8px);
background: rgba(255, 255, 255, 0.1); /* must be at least partially transparent */
```

If it has a fully opaque background, there's nothing behind to blur and the property does nothing visible.

v31 — set_volume command for STREAM_ALARM

Choose a tag to compare

@CheapDevotion CheapDevotion released this 11 May 15:35

What's in v31

New `set_volume` kiosk_command. Sets the device's STREAM_ALARM volume — the loudness level used by `play_media` (and bypassed/overridden by the security siren). Companion to v30's `play_media` for alarm-clock automations.

Example: crank volume before wakeup, restore after

```yaml

  • alias: Bedroom wakeup
    trigger:

    • platform: time
      at: "06:59:55"
      action:
    • event: kiosk_command
      event_data: { device: Bedroom Dashboard, command: set_volume, value: "0.8" }
  • alias: Bedroom wakeup fire
    trigger:

  • alias: Bedroom dismiss
    trigger:

    • platform: state
      entity_id: input_button.bedroom_dismiss
      action:
    • event: kiosk_command
      event_data: { device: Bedroom Dashboard, command: stop_media }
    • event: kiosk_command
      event_data: { device: Bedroom Dashboard, command: set_volume, value: "0.3" }
      ```

What it doesn't affect

  • Security siren — peg-to-max regardless of this setting
  • Spotify Connect volume — separate path, controlled from phone Spotify slider or footer +/− buttons
  • STREAM_MUSIC — not used by anything we control

For finer-grained control of those other paths, future commands like `set_media_volume` / `set_spotify_volume` would be obvious follow-ups.

v30 — play_media + stop_media commands

Choose a tag to compare

@CheapDevotion CheapDevotion released this 11 May 14:58

What's in v30

Two new kiosk_commands:

  • `play_media` — takes an audio URL in `value`. Plays via Android MediaPlayer on STREAM_ALARM so it bypasses silent/DND, ducks Spotify automatically, and gets out of the way of the music when done. Single-track at a time: firing again replaces.
  • `stop_media` — stops any in-progress play_media.

Primary use case: HA-driven alarm clocks.

Example: 7:00 AM wakeup automation

```yaml

Store `wakeup.mp3` in HA's `config/www/` folder; it's served at `/local/`. Or use an HA TTS proxy URL for spoken alarms (e.g. `http://.../api/tts_proxy/.mp3`).

Notes

  • URL must be reachable from the kiosk's network (same Wi-Fi LAN as HA).
  • File formats: anything Android MediaPlayer supports — MP3, AAC, OGG, WAV, FLAC, M4A.
  • Spotify keeps playing under the alarm (ducked); stop the alarm via `stop_media` or let it complete naturally to return Spotify to normal volume.
  • Volume: defaults to whatever the device's STREAM_ALARM is set to (~40% out of the box). Can be turned up via the device's hardware volume keys while playing.

v29 — kill the surprise 'play artist only' switch on hiccups

Choose a tag to compare

@CheapDevotion CheapDevotion released this 10 May 16:47

Disables librespot's autoplay (radio station fallback when queue exhausts) by default. After a network hiccup desyncs librespot's session state with Spotify's server, the queue appears empty and autoplay was switching the user's playlist over to a radio station based on the current artist without input. Now defaults to stop-at-end-of-queue. Per-device runtime override: set_autoplay kiosk_command with value 'true' or 'false'.

v28 — kill the 30-60s Spotify Connect delay

Choose a tag to compare

@CheapDevotion CheapDevotion released this 09 May 23:43

What's in v28

Spotify Connect device pickups now consistently complete in 1-2 seconds instead of 30-60.

Root cause

The kiosk's first session-creation attempt occasionally fails on the TCP connect to a Spotify accesspoint (random pick from a 6-AP pool, some are intermittently unreachable). The phone-side Connect protocol then waits ~33 seconds before re-sending /addUser, which is the user-visible delay. Identified via fleet logs from `get_logs`:

```
16:30:22.143 Accepted new user from iPhone
16:30:22.959 ERROR ZeroconfServer - Couldn't establish a new session.
(33s of phone-side retry timeout)
16:30:55.006 Accepted new user from iPhone ← retry, succeeds
```

Fix

Patched librespot's `ZeroconfServer.handleAddUser` (in our local clone) to retry session creation up to 5 times with 200ms backoff before giving up. Each retry picks a fresh random AP, so a different one is tried. With 6 APs in the typical pool and most working, retries usually succeed on attempt 2.

Worst case: ~5s before giving up. Still vastly better than the 33s phone-side timeout.

v27 — hold-to-repeat volume + visual feedback bar

Choose a tag to compare

@CheapDevotion CheapDevotion released this 09 May 23:28

Volume buttons now repeat while held (single tap = single step, 1.5s hold = full sweep). New volume indicator bar fades in over the track text whenever volume changes (your tap, hold, or phone-side slider), then fades back to the track text 1.5s after the last change. Volume step size doubled (~3% per tap).

v26 — flat white footer icons via custom Drawable

Choose a tag to compare

@CheapDevotion CheapDevotion released this 09 May 23:21

Replaces Unicode media glyphs (which Android 8.1 was rendering as orange color emoji from NotoColorEmoji on the Lenovo skin) with programmatic shapes drawn via a custom Drawable. Guaranteed flat white, no font fallback orange.

v25 — set_brightness remote command for HA-driven dimming

Choose a tag to compare

@CheapDevotion CheapDevotion released this 09 May 22:39

What's in v25

New `set_brightness` kiosk_command. Accepts fractional (`0.2`) or percentage (`20`) input. Updates the persisted `screen-brightness` pref and applies live to the running MainActivity window. Clamped to [5%, 100%].

Also absorbed at provisioning time via `--ef screen_brightness 0.2`.

HA automation example: alarm-armed dimming

```yaml

  • alias: Dim bedroom kiosk on alarm armed
    trigger:

    • platform: state
      entity_id: alarm_control_panel.alarmo
      to:
      • armed_night
      • armed_home
      • armed_away
        action:
    • service: homeassistant.event
      data:
      event_type: kiosk_command
      event_data:
      device: Bedroom Dashboard
      command: set_brightness
      value: "0.2"
  • alias: Restore bedroom kiosk on alarm disarmed
    trigger:

    • platform: state
      entity_id: alarm_control_panel.alarmo
      to: disarmed
      action:
    • service: homeassistant.event
      data:
      event_type: kiosk_command
      event_data:
      device: Bedroom Dashboard
      command: set_brightness
      value: "1.0"
      ```

v24 — silence button actually disarms HA

Choose a tag to compare

@CheapDevotion CheapDevotion released this 09 May 22:35

What's in v24

The SILENCE SIREN button on the AlarmActivity overlay used to just stop the local siren. Now it calls HA's `alarm_control_panel.alarm_disarm` service. The resulting state change propagates over the WebSocket to every connected kiosk and each one auto-dismisses its overlay via the v23 onAlarmCleared path -- so one tap on a designated panel silences and dismisses the alarm fleet-wide.

`alarm_can_disarm` and `alarm_disarm_code` can now be set at provisioning time via intent extras (`--ez alarm_can_disarm true --es alarm_disarm_code 1234`) or remotely via the `set_can_disarm` / `set_disarm_code` kiosk_command events.

Practical pattern: enable siren on every room, set `can-disarm=true` only on the master bedroom panel. Anywhere in the house, the alarm fires loud and visible. Only the bedroom can silence it -- and one tap on the bedroom panel kills the alarm everywhere.