- Introduce DisplayCoordinator polling /api/display/monitors once per
cycle and fan out to all per-display entities via CoordinatorEntity.
Removes ~9x redundant requests per polling cycle that came from each
binary_sensor/number/select/sensor/switch entity calling
get_display_monitors() in its own async_update.
- Optimistic write-through via coordinator.apply_optimistic(...) keeps
sibling entities in sync after slider/select writes without an extra
network round-trip.
- Make CONF_TOKEN optional. The media server already supports running
without auth (auth_enabled() returns False when api_tokens is empty),
so the integration omits the Authorization header and ?token= query
from REST/WS/album-art URLs when no token is configured. Server-side
auth-enabled rejections still surface as invalid_auth in the UI.
- Bump manifest version to 0.3.2.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Restructure how displays are exposed in Home Assistant:
Each physical monitor is now its own HA device linked to the media-server
hub via `via_device`. The hub keeps the media_player + script buttons; per-
display devices hold the power switch, brightness slider, and the new
capability entities. This lets users place displays in their own area/room
and keeps related entities grouped together in the UI.
New platforms:
- sensor: DisplayResolutionSensor (diagnostic, from EDID)
- binary_sensor: DisplayPrimaryBinarySensor + DisplayPowerControlBinarySensor
(both diagnostic; help users see why a power switch is or isn't created)
- select: DisplayInputSourceSelect (HDMI1/DP1/...), DisplayColorPresetSelect
(color temperature), DisplayPictureModeSelect (VCP 0xDC scene modes)
- number: added DisplayContrastNumber alongside brightness
Other changes:
- display_device helper centralises the per-display DeviceInfo; pulls real
manufacturer/model from EDID; device name no longer prepends the hub
title since via_device already shows the hierarchy.
- api_client gains set_display_{contrast,input_source,color_preset,picture_mode}
and stops forcing `?refresh=true` on every poll so HA can ride the
server's TTL cache instead of triggering full DDC/CI probes per entity.
- select / number entities now check the server's `success` flag and re-
sync from the actual monitor state when a write was silently rejected
(some monitors honor reads but ignore writes for certain DDC/CI codes).
Bumps manifest.json to 0.3.0 - the device topology change is user-visible
and existing brightness/power entities migrate to per-display devices on
first reload (unique_ids are preserved).