Expose panel resolution, physical size and colour scheme - #86
Conversation
|
Can you resolve conflicts. |
f3ef75a to
1ac6854
Compare
|
Rebased onto the current The only real conflict was the import block in Verified: full test suite passes locally (134 tests), and |
|
Recommend merge after clearing conflicts. |
1ac6854 to
0aa630b
Compare
|
Love this! May I suggest calling the entity |
|
Thanks for taking a look! For my use case either shape works — I just need some template-readable way to reach a panel's specs, so state vs attributes isn't really the deciding factor for me. What makes me lean toward keeping a narrow |
|
@parkghost I guess what stuck me was the attributes, and not the resolution. The attributes carry a lot of extra stuff that currently isn't available at all. And that I think would be useful to expose some way. Just out of curiosity: Can you illustrate the use case you will enable with this feature? |
The panel reports its pixel dimensions, physical size and colour scheme in the display config packet, but none of it reached Home Assistant: __init__.py reads the pixel dimensions to build the device model and then discards them whenever the diagonal is known, and the diagonal it shows is itself derived from the millimetres. Consumers were left string-parsing a human-facing display name, and could not get the resolution at all. That blocks a real use case: an automation that renders an image at runtime and pushes it with opendisplay.upload_image needs the panel's resolution and colour scheme to size and quantise the render. A template can only read entity state, so the values have to live on an entity. Adds sensor.<device>_resolution, state WIDTHxHEIGHT, with the pixel and physical dimensions and the colour scheme as attributes. Diagnostic and disabled by default, like the other device-fact sensors. - One sensor per device, reporting displays[0]. The config packet is repeatable (max 4), but upload_image and drawcustom take no display argument and both use displays[0] - unlike activate_led/activate_buzzer/play_melody, which do take an instance. A sensor for display 1..3 would describe a panel nothing can draw on, and a consumer sizing a render from it would silently produce an image for the wrong panel. If display addressing is added to those services, this grows to match, keyed the same way. - The state is the panel's NATIVE resolution, never transposed. What a consumer should compose is a question about how the panel is mounted and what the caller wants on it, not a property of the packet. - Rotation is deliberately left out, although the packet carries it. It is a stored firmware offset, not an orientation: a frame configured at one base is still something a person can stand on its side, so the value answers neither "is this panel portrait or landscape" nor "what should I compose". It is only one term in the device's (base + rotate) % 360, and a deployment that needs that arithmetic settles it once per panel by experiment. Exposing it would widen the entity for a fact no consumer can act on by itself. - The config is re-read on every access. delivery.py replaces runtime_data.device_config wholesale on a wake-time resync without reloading the entry, so a snapshot taken at construction would serve stale geometry. - Stays available while the panel sleeps, since the value comes from config rather than from advertisements. value_fn becomes optional on the description: last_seen already passed a dead no-op to satisfy it, and this sensor would have been a second one.
0aa630b to
8884212
Compare
|
@schlomo I run about seven OpenDisplay screens across four sizes (7.5", 7.3", 4.2", 2.9") in three colour schemes (BWGBRY, BWR, MONO). What goes on them comes from all over: HA integrations (weather, calendar, OpenAI image generator), internal MCP servers (timers, scheduled tasks), an external MCP server (Notion), and live voice-assistant turns. The images are composed at runtime by an AI agent — Claude Code or the voice assistant (based on Pi) — which picks the layout from both the content AND the target panel's characteristics, then hands the PNG to So on every single render the composer needs the target panel's geometry, and it has to come from HA — an MCP tool call or a Jinja template — because that is all these callers can reach. That is what this PR is for. That is also why the attributes are the part I actually use. My renderer takes five arguments for a target, and three of them are read straight off the panel: the canvas ( You mentioned some of it would be useful to expose "some way" — which parts? Happy to fold them in here if they fit, or leave them for a follow-up. @g4bri3lDev — a maintainer call would help here, and I would rather build the shape you want than leave this sitting. |
|
@parkghost nice use case, thanks a lot for sharing! I think that we simply should make all information that OD has on a display also available via states and attributes. For example, for #127 I need to be able to read the last content sent to a display via That is why I was wondering about the extra attributes attached to the resolution vs. having a state that simply carries that and more information. |
Would a |
Closes #85
Adds
sensor.<device>_resolution— stateWIDTHxHEIGHT, with the pixel and physical dimensions and the colour scheme as attributes. Diagnostic and disabled by default, like the other device-fact sensors.