Hayden Griffin

House for webOS

A Home Assistant panel for my LG TV, made for the remote, with a weekly recap of the house: steps, dinners, energy and who used the most hot water.

Made-up data. Press an arrow key to start, Enter to choose, Esc to go back.Open full screen

A Home Assistant panel for LG TVs, built to be read from the sofa and driven with the remote. It shows the lights, the TV's sources, what's playing and who's home, and every Sunday it can play a Wrapped-style recap of the week at home.

Try the demo in a browser → It runs on made-up data. Use the arrow keys and Enter; add &recap to the URL for the week recap.

What it does

Six recap cards: a steps duel, a quiz, the week's dinners, the energy bill, the robot vacuum's week and the winner

Requirements

Status: an earlier private build of this app runs every day on a rooted 2021 C1. Versions 1.1 and 1.2 have only run in the browser demo and the tests so far. The public package, ares-install, the Developer Mode SSH push and launching by io.github.haydengriffin.house haven't been tried on a TV yet. Reports either way are very welcome.

Install

The package never contains your config or token, so the same IPK works for every home and is safe to share. The config goes onto the TV separately, next to the installed app.

  1. Build the package and install it on the TV:

    python3 tools/package.py
    ares-setup-device            # once, to add the TV
    ares-install -d <tv> dist/io.github.haydengriffin.house_1.2.0_all.ipk
  2. Copy config.example.json to config.json and fill in the websocket URL, the token and your entities. Everything except url and token is optional; leave out a section and its panel disappears. --token-file keeps the token in its own file instead.

  3. Put the config on the TV over SSH, then open House:

    python3 tools/push_config.py config.json --ssh root@<tv>                                  # rooted TV
    python3 tools/push_config.py config.json --ssh "-p 9922 -i ~/.ssh/tv_webos prisoner@<tv>"   # Developer Mode

    It writes config.js into the app's folder through SSH's stdin, so the token never appears in a command line. Reinstalling the IPK removes it, so push the config again after every install. Whether Developer Mode's SSH user may write into the app folder depends on the firmware.

To open House quickly, pin it to the TV's home row or put it on a Quick Access number. Home Assistant can also open it with the LG webOS integration's media_player.select_source, or webostv.command with system.launcher/launch and {"id": "io.github.haydengriffin.house"}.

Developer Mode sessions run out unless they're extended; the Developer Mode app on the TV shows the time left.

Configuration

Key What it is
url, token ws://<home assistant>:8123/api/websocket and the TV user's token.
title, locale, idle_seconds The heading, the date and time format (e.g. en-GB), and the auto-close delay.
demo true runs on the demo states with no Home Assistant, as ?demo in the URL does.
lights [{ name, entity, icon?, on?, off? }]. A press toggles the entity. on and off replace the state text ("On · 60%", "Off").
tiles [{ name, sub?, icon?, toast?, entity?, on?, off?, action?, confirm?, visible? }]. action is { service: "domain.service", data?, target? }; with only entity, a press toggles it. sub shows while the entity is off; on and off work as on lights. confirm: true (or the armed label) makes it a two-press action: the first press arms it red for 5 s. visible: { entity, states } shows it only while the entity is in one of those states.
door, door_name A binary_sensor; a chip appears while it's on, with how long for. door_name is the chip's text (default "Door open").
glance Header chips: [{ entity, text?, icon?, attribute?, hide?, hours?, within_days? }]. text takes {value}, {attr.x} and {day} (the value read as a date: today, tomorrow or the weekday), e.g. "Tonight · {value}". A chip shows only while there's something to say.
quick Actions that lead the lights grid and take the first focus, e.g. Pause and Lights up while something plays. Same shape as tiles.
footer Pill buttons after This week, same shape as tiles, e.g. Everything off.
calendars Calendar entities for the "Next" line.
tv { title?, source_sensor?, sources: [{ name, icon?, action }], wide? }. The source whose name matches the sensor's state is lit; the sensor's line attribute, if any, shows beside the title.
music { title?, player, extra?, toggle? }. extra is a pill button with an action; toggle is a switch row, { name, entity, icon?, on?, off?, action_on?, action_off? }, for an input_boolean: on/off label its states and action_on/action_off run instead of toggling it.
people [{ name, person, room? }]. room is any sensor whose state is the room name.
recap { stats, attribute?, cue?, done?, idle_minutes?, ask?, tv?, vacuum_map? }. done is an action called with reason when a recap ends that the cue started, or that began while the cue script was running. tv is the TV's media_player, whose history gives the TV hours when the stats have none. Stats up to six days old that nobody has played on this TV are offered on the home screen ("Your week at home is ready") unless ask is false. See docs/recap-stats.md.

Icons are Material Design Icons names in camelCase, from the set in app/icons.js; add any path you need there.

Development

Open app/index.html?demo in Chrome. The layout is fixed at 1920×1080, the TV's resolution; in a smaller window the demo scales to fit. app/demo.js holds the demo home and the full recap stats. The README images are rendered from the demo by tools/showcase. To try it against your own Home Assistant, write the config into the app folder with python3 tools/push_config.py config.json --out app/config.js (git ignores it, and the package leaves it out). Tests: python3 -m unittest discover -s tests and node --test; lint: npx --yes eslint@9 app.

Support

House for webOS is free and open source. If it made your evenings on the sofa better, you can buy me a coffee. Bug reports and pull requests are just as welcome.

Licence

MIT. Bundled icons are Apache 2.0 and the fonts are SIL OFL 1.1; see NOTICE.