Sign in

iiinova is part of the Atmosphere — an open, public network where you own your identity.

Thomas

@fantpmas.mastodon.social.ap.brid.gy
28 followers 2 following 390 posts

Quality engineer by day, sawdust engineer by night. [bridged from mastodon.social/@fantpmas on the fediverse by fed.brid.gy ]

PostsRepliesMedia
Thomas @fantpmas.mastodon.social.ap.brid.gy · 7h
New #HomeAssistant blog post www.fantomas-ls.com/posts/kid-prese…
fantomas-ls.com
Is the kid home yet?
Every parent of a teenager knows the late-night ritual: lying awake, half-listening for the front door, wondering whether they're already home and you just didn't hear them. I wanted a quieter answer to that question: a glance at my phone on the nightstand that says **Home** or **Away** , without installing anything extra on their phone. The idea is simple. When my kid's iPhone is on our Wi-Fi, they're home. I already run UniFi gear and Home Assistant, so all the pieces were there; they just needed connecting. Here's how I did it, including the mistakes I made along the way. The setup has four parts: 1. **UniFi OS Server** on a Linux box, managing the network and knowing which devices are connected 2. **Home Assistant** turning "this iPhone is connected" into a presence state 3. **Scriptable app** creating a readable widget with stateful icons 4. An **iPhone StandBy widget** showing that state on my nightstand * * * ## Part 1: Installing UniFi OS Server permalink UniFi OS Server is Ubiquiti's self-hosted replacement for the old UniFi Network Application. It runs as a Podman container, and the install is mostly painless: sudo apt-get update && sudo apt-get install podman slirp4netns curl -O <download-link-from-ui.com> chmod +x <installer> sudo ./<installer> Grab the download link from the UniFi download page by right-clicking the Linux installer and copying the link address. The official instructions say to run `sudo <installer>`. That fails with _command not found_ , because without a path `sudo` looks for the file in your `PATH`, not in the current directory. Put `./` in front: sudo ./8b93-linux-x64-4.2.23-...-x64 Tab completion saves you from typing that monster of a filename. After that the UniFi OS web UI was available at `https://<server-ip>:11443` Expect a certificate warning, because the server uses a self-signed certificate. ### Phone alias permalink To be able to easily identify the phone, go the _Clients overview_ in the UniFi OS Server and give the phones you want to track a Name (alias). * * * ## Part 2: Presence in Home Assistant permalink My first instinct was to build something with UniFi's Alarm Manager: fire a webhook to Home Assistant when the iPhone connects. It works, but it's the wrong tool. Webhooks only push events, so if Home Assistant restarts at the wrong moment you miss one, and you still have to work out "left home" yourself. The better option is already built in: the **UniFi Network** integration. It polls the controller's client list and creates an entity for each device. No custom plumbing needed. ### Step 1: A local user for Home Assistant permalink In UniFi OS Server, under **Admins & Users**, create a **local-only** admin (e.g. `homeassistant`). Don't use your UI.com cloud account; two-factor authentication will break the integration. ### Step 2: Add the integration permalink In Home Assistant, go to **Settings → Devices & services → Add integration → UniFi Network**: Field| Value ---|--- Host| your server's IP Port| 11443 Username/password| the local user Verify SSL| off ### Step 3: Link the device entity permalink Go to **Settings → Devices & services → UniFi Network** and select **entities**. Select the phones you want to track and enable the entities. Under **Settings → People** , create a person for your kid and add the new phone entity. You now have `person.kid` with a clean `home` / `not_home` state. ### Step 4: Set up template sensor with stateful icon permalink To have stateful icons with custom state lables **Away/Home** add the following template sensor to your `/configuration.yaml`: template: - sensor: - name: Kid presence unique_id: kid state: "{{ 'Home' if is_state('person.kid', 'home') else 'Away' }}" icon: "{{ 'mdi:home-account' if is_state('person.kid', 'home') else 'mdi:account-arrow-right' }}" This creates a `sensor.kid_presence` sensor you can use in the widget with a nice **Home/Away** label and a matching icon. * * * ## Part 3: A glanceable widget in StandBy mode permalink Now for the part that actually helps at 1 a.m. **StandBy** turns a charging, locked iPhone lying on its side into a bedside display. Its widget view can show Home Assistant widgets. ### HomeAssistant widget permalink My first attempt was adding a custom iOS widget via the Home Assistant companion app, but I did not succeed in having the icons update according to the **Home/Away** state and the widget was too small to easily read in bed without my glasses. ### Scriptable widget permalink In my search to have a custom widget I stumbled on Scriptable that allows you to script your own widget. I edited this example script to my needs, also mapping the HomeAssistant icons to SF Symbols: // Home Assistant Presence Widget for Scriptable // // Based on Home Assistant Sensor Widget, Copyright 2023 @olahellgren // https://github.com/olahellgren/home-assistant-sensor-widget-scriptable // MIT License (see bottom of file) // ===== Configuration ===== const hassUrl = "<hass base url>" const hassToken = "<your long lived Bearer token>" const people = [ { name: "Kid 1", entity: "sensor.kid1_presence" }, { name: "Kid 2", entity: "sensor.kid2_presence" } ] // Home Assistant icon -> SF Symbol const iconSymbolMap = { "mdi:home-account": "house", "mdi:account-arrow-right": "house.slash" } const defaultSymbol = "house.fill" // ===== Layout ===== const backgroundColor = new Color("#000000") const textColor = new Color("#ffffff") const nameFontSize = 16 const statusFontSize = 28 const iconSize = 50 const padding = 12 // ===== Widget ===== const states = await fetchAllStates() const widget = new ListWidget() widget.backgroundColor = backgroundColor widget.setPadding(padding, padding, padding, padding) const layout = widget.addStack() layout.layoutVertically() people.forEach((person, i) => { const sensor = states.find(s => s.entity_id === person.entity) if (!sensor) return if (i > 0) layout.addSpacer() // spread rows over the full height addPersonRow(layout, person.name, sensor) }) Script.setWidget(widget) Script.complete() widget.presentSmall() // ===== Functions ===== function addPersonRow(parent, name, sensor) { const row = parent.addStack() row.layoutHorizontally() row.centerAlignContent() const sf = SFSymbol.named(iconSymbolMap[sensor.attributes.icon] || defaultSymbol) sf.applyFont(Font.systemFont(iconSize)) const img = row.addImage(sf.image) img.imageSize = new Size(iconSize, iconSize) img.tintColor = textColor row.addSpacer(8) const textCol = row.addStack() textCol.layoutVertically() const nameText = textCol.addText(name) nameText.font = Font.semiboldRoundedSystemFont(nameFontSize) nameText.textColor = textColor nameText.lineLimit = 1 const statusText = textCol.addText(String(sensor.state)) statusText.font = Font.mediumRoundedSystemFont(statusFontSize) statusText.textColor = textColor statusText.lineLimit = 1 statusText.minimumScaleFactor = 0.5 } async function fetchAllStates() { const req = new Request(`${hassUrl}/api/states`) req.headers = { "Authorization": `Bearer ${hassToken}`, "Content-Type": "application/json" } const result = await req.loadJSON() if (!Array.isArray(result)) { throw new Error(`Home Assistant error: ${JSON.stringify(result)}`) } return result } // The MIT License // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. To add it to your StandBy screen: 1. Charge your phone on its side while it's locked, so StandBy turns on. 2. Swipe to the **widgets** view (the two side-by-side stacks). 3. Long-press a stack → **+** → **Scriptable** → **Your newly made widget**. At night StandBy switches to its red night mode, which also tints the widget. It's dim enough not to keep you awake and still readable at a glance. ### Make it update immediately permalink iOS decides on its own when widgets refresh, which can be 15 minutes or more. The supposed fix is a small Home Assistant automation that tells my phone to refresh its widgets whenever the kid's presence changes: alias: Refresh presence widget triggers: - trigger: state entity_id: person.kid actions: - action: notify.mobile_app_my_iphone data: message: update_widgets `update_widgets` is a silent command, so no notification appears. I have found this is not really reliable, iOS still decides to update or not depending on how the wind blows. Testing did show that it usually updates within 15 minutes, which is fine. * * * ## Wrapping up permalink The end result: my kid comes home, their phone joins the Wi-Fi (if it still has battery, lol), Home Assistant flips them to _home_ , and the widget on my nightstand changes from **Away** to **Home**. No apps to install on their phone, no location sharing to set up, and no "are you home yet?" texts. Ain't that grand!
010 1
Reposted by Thomas
petur 😶🇺🇦🇵🇸🇹🇼 @peturdainn.mastodon.social.ap.brid.gy · 8h
from our absolutely top cartoonist @lectrr #tesla #riots #climate #musk
a flying Tesla with black burning and riots below
the title is "the future is now"
114 4
Thomas @fantpmas.mastodon.social.ap.brid.gy · 19/10/2026
Really enjoying Small Prophets. www.imdb.com/title/tt38504111 #comedy #drama
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 16/10/2026
Suspiciously cheap Makita gear on second hand site. I take a closer look and 😆
Fake Makita logo on box
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 11/10/2026
Klimaatmars 🔥🔥🔥
001 1
Thomas @fantpmas.mastodon.social.ap.brid.gy · 09/10/2026
Spent the last week cycling from Dijon to Arles, doing part of the ViaRhôna from Lyon onwards together with my wife. Review in numbers, because you all looooove numbers: 7 days 604 kilometers 4 campsites, 1 welcome to my garden, 1 hotel, 1 airbnb 1 rain day 0 […] [Original post on mastodon.social]
Map of France with 7 stages of the ViaRhôna mapped out
000 0
Reposted by Thomas
Jan Schaumann @jschauma.mstdn.social.ap.brid.gy · 30/09/2026
When you notice your meat-proxy colleagues become absolutely helpless on their own, remember Sam Altman's goal: “We see a future where intelligence is a utility, like electricity or water, and people buy it from us on a meter” People paying to make themselves dependent on these companies. You […]
mstdn.social
Original post on mstdn.social
017 7
Thomas @fantpmas.mastodon.social.ap.brid.gy · 21/09/2026
One more week until a new bikepacking adventure starts. Straight down, easy peasy 😆 #cycling #bikepacking
Komoot map of route going form Dijon to the Mediterranean.
020 2
Thomas @fantpmas.mastodon.social.ap.brid.gy · 20/09/2026
@woe2you yes indeed and for some reason some parts decide to not take any paint at all. Onwards we go!
100 1
Thomas @fantpmas.mastodon.social.ap.brid.gy · 20/09/2026
Quick and dirty cabinet for my son's gaming desktop and also some school books. Man, I do hate painting MDF. #woodworking
MDF cabinet in a dirty workshopHalf painted MDF cabinet
100 1
Thomas @fantpmas.mastodon.social.ap.brid.gy · 19/09/2026
Yesterday was a beautiful day for our yearly mowing of the food forest. #foodforest #voedselbos
Walk behind flail mower in our food forestKatrien raking the grassRows of nicely cut grass
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 17/09/2026
🥳
Verwerk status
Domeinhouders: | Verwerkt |
Nameservers: | Verwerkt |
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 17/09/2026
The LinkedIn algorithm is either very weird or has really come to know me 😆
GoatedGoats

For the last few months, goats have been prancing around inside my mind.
Recently, I've discovered that goats have been extremely useful since we first
domesticated goats. Goats feed us. Goats give us milk. Goats help protect the
land from invasive plant species. Recently, we've even begun to use goats for
landscaping. It's called goatscaping.
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 16/09/2026
RE: mastodon.social/@piffio/11727945500… Words of wisdom right here ❤️
mastodon.social
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 16/09/2026
Iets later dan 1 september maar daar zijn ze weer! www.demorgen.be/nieuws/deense-studi…
myprivacy.dpgmedia.be
DPG Media Privacy Gate
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 16/09/2026
If you're ever in the market for a new power tool, do first watch Irish tool repair man www.youtube.com/@deandohertygreaser. Absolute gem of information on which tools to avoid and which to cherish.
001 1
Thomas @fantpmas.mastodon.social.ap.brid.gy · 15/09/2026
RE: mastodon.social/@benroyce/117272757… ❤️ Free Palestine ❤️
mastodon.social
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 11/09/2026
123 piano ter ere van wijlen Lucien.
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 11/09/2026
Hear hear www.standaard.be/opinies/uw-frietje… "Er is te veel grond voor veevoeder en export, te weinig voor lokale en gezonde voeding, en veel te weinig voor natuur."
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 10/09/2026
Looking at prices for return train tickets to Copenhagen from Brussels and somewhat surprised and glad to see that they are cheaper than flying.
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 10/09/2026
Spotting a new butterfly species in our food forest always brings a smile to my face. Small copper, first spotted yesterday. #foodforest #voedselbos #butterfly
Small copper in the grass
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 09/09/2026
Fenne Kuppens in het Palmarium van Gent. Ingetogener dan Whispering Sons alvast 😉
A winding path surrounded by lush greenery leads towards a well-lit area, with tall palm leaves framing the scene. In the background, a modern building features a lighted mural by ROA, and the sky has a soft blue hue, indicating dusk.A musician playing guitar on stage is illuminated by soft lights, performing in front of an engaged audience. There is a large cactus in the foreground, and the background features a textured wall with artistic elements. The venue appears intimate and relaxed.
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 09/09/2026
It's like picking candy. #foodforest #gardening #voedselbos
A hand holding several yellow raspberries, with a green bush in the background and a cloudy sky above.
020 2
Thomas @fantpmas.mastodon.social.ap.brid.gy · 09/09/2026
Finally moving away from Namecheap. Let's see how easy the process is.
100 1
Thomas @fantpmas.mastodon.social.ap.brid.gy · 08/09/2026
Ready for #EatMoreTrees
A promotional poster on a cinema screen for "Eat More Trees," featuring a floating tree with roots and a vibrant background of blue sky and landscape. Text includes "AVANT-PREMIÈRE" and "met MO."
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 08/09/2026
If I search long and hard enough these two magical drawers will produce the exact washer, bolt, nut or screw I need. #diy
A close-up view of two clear storage bins filled with assorted screws, bolts, and other metal hardware. Behind the bins is a red shelving unit with additional transparent drawers, some filled with various small items, covered in dust.
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 06/09/2026
Great introduction by two enthusiastic bee keepers. Their Belasko hornet trap works really well. #bees
An indoor setting with a brick wall and glass roof features a wooden structure resembling a beehive, populated by bees. A child leans in to observe the hive, while a presentation screen is visible in the background, exhibiting text.A row of colorful beehives in red, blue, and green is positioned against a textured wall. A protective mesh barrier is set up in front of the hives, supported by bamboo sticks. The surrounding area features grass and some greenery.
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 04/09/2026
Thirsty
A dramatic sky with colorful clouds at sunset, featuring shades of pink and blue, with a hint of dark clouds. Below, signs labeled "DORST" are partially visible, illuminated by purple light.
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 03/09/2026
Sunday I'll be joining an introduction to beekeeping. On a rooftop community garden in Ghent. Purely out of interest, not immediately to start myself. Looking forward to it! #beekeeping #bee
100 1
Thomas @fantpmas.mastodon.social.ap.brid.gy · 02/09/2026
Prepping a new planting area #foodforest
Area of food forest partially covered with cardboard and grass mulch
000 0
Reposted by Thomas
Jeroen Baert @jbaert.mastodon.social.ap.brid.gy · 02/09/2026
Zo blij dat we "woke" hebben aangepakt, in plaats van het klimaat of de economie of de gezondheidszorg of de kinderopvang of
034 4
Thomas @fantpmas.mastodon.social.ap.brid.gy · 02/09/2026
Wrong house there dear European hornets. #foodforest
A wooden nest box attached to a tree, featuring an intricate design resembling a wasp nest on one side. The surrounding area is lush with green foliage.
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 31/08/2026
De antieke eID-kaartlezer niet aan de praat krijgen op Mac maar wel op Linux Mint. De wonderen zijn de wereld nog niet uit!
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 28/08/2026
@ljosmyndun.bsky.social wtf
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 27/08/2026
Failures in bread baking 🫠 We'll just call it flat bread.
A very flat artisanal loaf of bread with a cracked surface and dusted flour is displayed on a wooden cutting board.
010 1
Thomas @fantpmas.mastodon.social.ap.brid.gy · 27/08/2026
Sparrowhawk cooling down in the filter area of our swimming pond. #birds #birdsofmastodon
Sparrowhawk sitting in a filter zone of a swimming pond. A wooden deck is partly visible. Some water plants are present in the filter area. The bird is just chilling and thinking what is that dude with the smartphone doing.
001 1
Thomas @fantpmas.mastodon.social.ap.brid.gy · 26/08/2026
Thomas's Law of Appliances: appliances shall never beep when turned on (for fuck's sake) and shall only beep once or twice at a reasonable sound level when finishing its job. There shall always be an option to completely mute the motherfucking device. That is all.
100 1
Thomas @fantpmas.mastodon.social.ap.brid.gy · 25/08/2026
New prototype of the Cam-1 wildlife camera is looking really good. A lot sturdier than the early ones. youtu.be/8q7bvd_t6jo?si=ACQMhemndPg… #wildlife #camera
001 1
Thomas @fantpmas.mastodon.social.ap.brid.gy · 25/08/2026
De max www.demorgen.be/nieuws/voor-het-eer…
myprivacy.dpgmedia.be
DPG Media Privacy Gate
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 24/08/2026
Second dead mole we found in the food forest. :sadness: #foodforest
Dead mole lying in the grass
100 1
Thomas @fantpmas.mastodon.social.ap.brid.gy · 21/08/2026
@ives Nice!!
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 20/08/2026
@peturdainn hoor eens bij Stefan www.instagram.com/eureka_creaties
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 19/08/2026
Het is eindelijk van dat, de renovatiewerken aan de directeurswoning in de Muide zijn nu echt begonnen!
Stellingen voor de directeurswoning in de Muide
001 1
Reposted by Thomas
George Monbiot @georgemonbiot.bsky.social · 19/08/2026
There is no "war on the motorist". But there is a war, waged one-sidedly by the motoring lobby, against public health, the safety of pedestrians and liveable cities. Against us, in other words.
81026191 1K
Thomas @fantpmas.mastodon.social.ap.brid.gy · 17/08/2026
Started reading The Devils and immediately like the style and world. Might be related to all the swearing (love me some swearing). app.thestorygraph.com/books/7a16241… #fantasy
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 17/08/2026
The almonds are starting to open up. #foodforest #voedselbos #gardening
Almonds starting to show tiny cracks.
030 3
Thomas @fantpmas.mastodon.social.ap.brid.gy · 17/08/2026
Woke up to 10 litres in the pluviometer 🤗
000 0
Thomas @fantpmas.mastodon.social.ap.brid.gy · 16/08/2026
Finally 🌧️
The image displays a weather forecast for Ghent, showing current weather as 22°C with drizzle. The 10-day forecast lists temperatures ranging from 12°C to 25°C, alongside rain probabilities for each day.
100 1
Thomas @fantpmas.mastodon.social.ap.brid.gy · 15/08/2026
The ash branch had split and the backup branch was not thick enough unfortunately. Resawed some reclaimed oak and shaped it with a draw knife. Used my new shinto rasp to refine the shape. Lovely tool for that job! Finished with boiled linseed oil. #woodworking #diy
A workbench displays two wooden sticks: one is rough and natural with some lichen, while the other is smooth and carved. An axe is visible nearby, along with a workshop environment.Two wooden strips are placed on a metal work surface, accompanied by a yellow tape measure and a push stick. The background shows a concrete floor.A wooden-handled axe is placed on a workbench covered with wood shavings. Nearby tools, including a rasp and a draw knife are also visible.An axe with a wooden handle and a metal head is placed on a wooden workbench, showing signs of use with some wood shavings and dirt.
040 4
Thomas @fantpmas.mastodon.social.ap.brid.gy · 14/08/2026
Karel Sabbe has made it to the Pyrenees. #ultrarunning #trailrunning
Map of Karel Sabbe's FKT attempt on the Hexatrek
010 1