Skip to content

feat(services): offer device upload for the upload_image action - #131

Open
parkghost wants to merge 3 commits into
OpenDisplay:mainfrom
parkghost:feat/media-selector-image-upload
Open

parkghost wants to merge 3 commits into
OpenDisplay:mainfrom
parkghost:feat/media-selector-image-upload

Conversation

@parkghost

@parkghost parkghost commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

What

Sets image_upload: true on the image field's media selector in services.yaml:

selector:
  media:
    image_upload: true
    accept:
      - image/*
image

The field then renders an upload area with a "select media" link, instead of the media browser alone. On a phone that reaches the camera roll directly; today the only way in is the media browser dialog's Manage button, two dialogs deep and easy to miss.

It is a strict superset of the current picker — ha-picture-upload is rendered with select-media, so browsing server-side media is still one click away.

No Python change: the value is still the {media_content_id, media_content_type} pair that async_resolve_media already handles, including media-source://image_upload/<id>.

Minimum Home Assistant: 2026.10.0

MediaSelectorConfig only accepts image_upload from home-assistant/core#180452, which shipped in 2026.10.0. So this PR raises the floor to that release.

On anything older the option is not ignored. It fails selector validation, and _load_services_file then discards the whole services.yaml behind a single log warning. Every OpenDisplay action loses its field descriptions and renders an empty UI form. Verified against 2026.7.0:

extra keys not allowed @ data['upload_image']['fields']['image']['selector']['image_upload']

The second commit (chore: raise minimum Home Assistant to 2026.10.0) handles the floor:

dev moves too, because otherwise the latest leg (2026.9.1) would sit below the new floor. Until the weekly bump moves dev on, both legs test the same version.

uv.lock also upgrades the component requirements that 2026.10's usb and bluetooth components import, which uv cannot see: serialx 1.11.0, habluetooth 7.1.2, aiousbwatcher 1.1.2, bleak-retry-connector 4.7.1, bluetooth-data-tools 1.29.24. These match scripts/ha-component-reqs. Without them, conftest fails to import:

ImportError: cannot import name 'PortSettingsUpdate' from 'serialx.common'

That is the same failure that keeps the automated #129 (2026.10.0b0) red. This PR supersedes it, so #129 can be closed once this merges.

Testing

On CPython 3.14.8, the version CI uses:

Check Result
pytest (dev, HA 2026.10.0) 227 passed
pytest (min-ha, HA 2026.10.0) 227 passed
ruff check / ruff format --check pass

No test reads services.yaml. I checked the selector by hand on a live Home Assistant 2026.10.0 instance with no selector patches: the services load, and upload_image reports image_upload: true.

Note on CI

validate (hassfest) fails on every upstream PR since 2026-10-02, and that failure is unrelated to this change. Home Assistant core now ships a built-in opendisplay integration pinned to py-opendisplay==7.15.0, and hassfest rejects any other pin for the same domain:

[REQUIREMENTS] Requirement py-opendisplay[silabs-ota]==… is incompatible with py-opendisplay==7.15.0, which Home Assistant depends on.

Set image_upload on the image field's media selector so the field renders
an upload area with a media-browser link, instead of the browser alone.
On a phone this reaches the camera roll directly; previously the only way
in was the media browser dialog's "Manage" button, two dialogs deep.

Requires a Home Assistant release that ships home-assistant/core#180452:
MediaSelectorConfig only accepts image_upload from that PR. On anything
older the selector fails validation, which makes HA discard the whole
services.yaml behind a log warning and leaves every OpenDisplay action
with an empty UI form. Do not merge before the hacs.json floor reaches
the first release containing it.
The upload_image media selector sets image_upload, which stock
MediaSelectorConfig only accepts from 2026.10.0 (home-assistant/core#180452).
On anything older HA rejects the whole services.yaml.

Move the hacs.json floor and README to 2026.10.0, and pin both test legs
to pytest-homeassistant-custom-component 0.13.371 (Home Assistant 2026.10.0).

uv.lock also upgrades the component requirements that 2026.10's usb and
bluetooth components import but uv cannot see: serialx 1.11.0, habluetooth
7.1.2, aiousbwatcher 1.1.2, bleak-retry-connector 4.7.1 and
bluetooth-data-tools 1.29.24. Without them conftest fails to import
(cannot import name 'PortSettingsUpdate' from 'serialx.common').
@parkghost
parkghost marked this pull request as ready for review October 8, 2026 12:44
@parkghost
parkghost requested a review from g4bri3lDev as a code owner October 8, 2026 12:44
Resolve pyproject.toml and uv.lock. The dev leg takes upstream's
0.13.372 (Home Assistant 2026.10.1). The min-ha leg stays at 0.13.371
(2026.10.0, the new hacs.json floor), so the 2026.7.0-only serialx==1.8.2
pin and the aioesphomeapi extra are dropped; both legs now lock serialx
1.11.0, which 2026.10's usb component needs.

Claude-Session: https://claude.ai/code/session_01MDZaoRSv9bUmNLYwZd6vDe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant