Hosting Widget Pictures
A Switchboard tile can show a
picture from its image.url. Aivi never downloads that picture: each phone
showing the widget fetches it on its own, without your credentials. So the
picture has to live somewhere every phone can reach, from anywhere, over
https://. This page shows how to prepare a picture and two ways to host it:
a free Cloudflare R2 bucket, which we recommend, and the
Home Assistant www folder.
What a picture URL needs
Section titled “What a picture URL needs”The full rules are under Pictures; in short:
- Public
https://, reachable from anywhere. A phone away from home, or a family member’s phone, fetches the same URL. A LAN address such ashttp://192.168.1.20/...orhomeassistant.localwon’t load there. - Stable. The URL must keep working. Links that expire, such as signed storage URLs or tokenized camera snapshots, stop loading after a while.
- Small. At most 512 pixels on a side and 256 KB, in PNG, JPEG, HEIC, WebP, or GIF. Anything larger is refused, and a URL that fails isn’t tried again for 30 minutes.
- A new URL for a new picture. The phone trusts a picture for 24 hours.
To change it sooner, change the URL, for example
dog-cam.jpg?v=2ordog-cam-2.jpg. - Short. Image URLs count toward the 4 KiB content limit, so a short domain and file name leave more room for your tiles.
Anyone who knows the URL can open the picture, so only host pictures you don’t mind being public.
Prepare the file
Section titled “Prepare the file”Most photos are far larger than 512 pixels. On a Mac, sips resizes a photo
so its longer side is 512 pixels, and saves it as a JPEG:
sips -Z 512 -s format jpeg -s formatOptions 80 photo.jpg --out dog-cam.jpgIt also reads iPhone .heic photos. With
ImageMagick on any platform, the same is:
magick photo.jpg -resize '512x512>' -quality 80 dog-cam.jpgA 512-pixel JPEG at this quality is usually well under 100 KB. Check the size before you upload it; if it’s over 256 KB, lower the quality.
Cloudflare R2
Section titled “Cloudflare R2”Cloudflare R2 is object storage with a free monthly allowance: 10 GB of storage, 1 million write operations (such as uploads), and 10 million read operations. Downloads (egress) are free. A handful of thumbnails fetched by a few phones stays far inside it.
-
Sign in to the Cloudflare dashboard, or create a free account, and open Storage & databases > R2 > Overview. The first time, complete the checkout to add R2 to your account. It includes the free monthly allowance, and you’re billed only for usage beyond it.
-
Select Create bucket, give it a name such as
aivi-pictures(lowercase letters, numbers, and hyphens), and select Create bucket. The default location and storage class are fine. -
Make the bucket public. In the bucket, open Settings. Under Public Development URL, select Enable, type
allowto confirm, and select Allow. The bucket’s public URL, onr2.dev, appears there.If you have a domain on Cloudflare, connect it instead: under Custom Domains, select Add, enter a subdomain such as
pictures.example.com, select Continue, and then Connect Domain. See Custom domain or r2.dev. -
Back in the bucket, select Upload and drag in your prepared picture.
-
Put the public URL and the file name together, and use it as the tile’s
image.url:"image": {"url": "https://pictures.example.com/dog-cam.jpg","alt": "The dog in the hallway"}Open the URL in a private browser window first: if the picture shows there, the phone can load it too.
To replace a picture, upload the new file under a new name, or keep the
name and change the version in your payload (dog-cam.jpg?v=2). Either way,
the phone loads it at the next sync.
Custom domain or r2.dev
Section titled “Custom domain or r2.dev”Cloudflare describes the r2.dev URL as meant for development: it is
rate-limited, and Cloudflare recommends a custom domain for production. A
personal widget is a light load: each phone fetches a picture about once a
day, so r2.dev is fine for a home setup. If you already have a domain on
Cloudflare, connect it anyway: the URL is shorter, it’s yours, and Cloudflare
can cache the pictures. The domain must be a zone in the same Cloudflare
account as the bucket.
Home Assistant www folder
Section titled “Home Assistant www folder”Home Assistant serves the files in its www folder at /local/, without
asking for a login. That makes it a quick place for a few pictures, but only
if your Home Assistant is reachable from the internet over https://: with
Home Assistant Cloud remote access, or your own
setup such as a reverse proxy with a certificate. If your Home Assistant is
only reachable at home (or only over a VPN), the picture won’t load on a phone
away from it; use Cloudflare R2 instead.
-
Create a folder named
wwwinside your configuration folder (/config), for example with the File editor or Samba add-on. If the folder is new, restart Home Assistant once so it starts serving it. -
Put your prepared picture in it, for example
/config/www/aivi/dog-cam.jpg. -
Build the URL from your public Home Assistant address and the path below
www, with/local/in front:"image": {"url": "https://ha.example.com/local/aivi/dog-cam.jpg?v=1","alt": "The dog in the hallway"}Open it in a private browser window on mobile data to check that it loads away from home.
Anyone who knows a /local/ URL can open that file, so keep only pictures
you would share in www. When you replace a file, bump the version
(?v=2) in the payload so phones fetch the new one.
Other hosts
Section titled “Other hosts”Any static host works if the URL is public https:// and stays the same: a
web server you already run, another object storage service with public
reads, or your own website. Avoid links that expire: signed or presigned
storage URLs, camera snapshot links with a token, and share links that need a
login all stop working, and the tile falls back to its gradient or symbol.
Aivi: Live Activities and widgets over an API · Pricing · App Store