Skip to content

fix(system-info): tidy up x86 Device Info (CEC state + device model)#3119

Merged
vpetersson merged 3 commits into
masterfrom
fix/x86-cec-display-power
Jul 6, 2026
Merged

fix(system-info): tidy up x86 Device Info (CEC state + device model)#3119
vpetersson merged 3 commits into
masterfrom
fix/x86-cec-display-power

Conversation

@vpetersson

@vpetersson vpetersson commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Three fixes to the Display & hardware section of the System Info page as it renders on x86 players, reviewed against the x86 testbed.

1. Display Power (CEC) showed "CEC error"

x86 (and any host without a CEC adapter — no /dev/cec0 / /dev/vchiq, e.g. Pi 5) can only fail the libcec probe, so the periodic get_display_power task stored 'CEC error', which the System Info card and the v2 /info API surfaced verbatim — reading like a fault when CEC simply isn't present.

Now short-circuits on the existing diagnostics.cec_available() gate (the same one the Settings page and the display-power SET endpoint use): records a clear Not available and skips spawning a doomed subprocess every tick. CEC-capable boards (Pi 1–4) still report live On/Off.

2 & 3. Device model: stutter + awkward wrap

The card joined the raw DMI sys_vendor + product_name + CPU brand into one string with a ·, so the x86 label both stuttered and word-wrapped at an arbitrary point (splitting the CPU model, e.g. Intel Celeron | 4205U …):

Before

Device model
Intel Corporation Whiskey Platform · Intel Celeron
4205U @ 1.80GHz

After

Device model
Whiskey Platform
Intel Celeron 4205U @ 1.80GHz
  • Trailing corporate suffixes (Corporation / Inc. / Ltd. / …) are trimmed, and the board vendor is dropped when the CPU brand already names it (whitebox/reference boards set sys_vendor to the CPU maker). Branded OEM boxes keep their vendor because it differs: Dell Inc. OptiPlex 7090Dell OptiPlex 7090.
  • get_device_model_parts() now returns (board, cpu) and the template stacks the CPU as the card's secondary line — no ·, no mid-model wrap. Pi keeps its single firmware Model line.

Tests

  • get_display_power: existing True/False/error cases run with cec_available() == True; new test asserts 'Not available' is written and the probe skipped when no CEC adapter is present; soft-limit test updated.
  • get_device_model_parts: Pi, x86-with-DMI, redundant-vendor drop (Intel reference board), kept-but-trimmed branded vendor (Dell), virtual-chassis drop, and generic fallback — all asserting the (primary, secondary) tuple.
  • test_system_info_renders covers the template with the new device_model_detail line.

Verified on the x86 testbed

cec_available() returns False and the card renders "Not available"; the device-model helper produces ('Whiskey Platform', 'Intel Celeron 4205U @ 1.80GHz') for the box's actual DMI values.

🤖 Generated with Claude Code

On x86 (and any host that doesn't pass /dev/cec0 or /dev/vchiq into
the container, e.g. Pi 5) there is no CEC adapter, so the periodic
libcec probe can only fail — it stored 'CEC error', which the System
Info "Display Power (CEC)" card and the v2 /info API then surfaced as
though something were broken.

Gate the get_display_power Celery task on the same cec_available()
helper the settings UI and the display-power SET endpoint already use:
when no CEC adapter is present, record a clear 'Not available' and skip
spawning a doomed subprocess every tick. CEC-capable boards (Pi 1-4)
are unaffected and still report the live On/Off state.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vpetersson vpetersson requested a review from a team as a code owner July 6, 2026 20:09
@vpetersson vpetersson requested a review from Copilot July 6, 2026 20:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts the periodic get_display_power Celery task so hosts without a CEC adapter (e.g., x86) record "Not available" instead of surfacing "CEC error" via the System Info page and the v2 /info API.

Changes:

  • Short-circuit get_display_power on diagnostics.cec_available() and write "Not available" to Redis when CEC isn’t present.
  • Update existing tests to force cec_available() == True when exercising the probe path.
  • Add a new test asserting the non-CEC path writes "Not available" and does not call the probe.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/anthias_server/celery_tasks.py Short-circuits the display-power periodic task when CEC is unavailable, writing "Not available" to Redis.
tests/test_celery_tasks.py Adds/updates tests to cover both CEC-present probe behavior and the new CEC-absent short-circuit behavior.
Comments suppressed due to low confidence (1)

src/anthias_server/celery_tasks.py:347

  • SoftTimeLimitExceeded is only caught around the probe path; in the non-CEC short-circuit branch the Redis set() can still be interrupted by the soft time limit (or hang until the hard limit), which defeats the task’s “skip the tick instead of SIGKILLing the worker” safety behavior. Consider wrapping the whole body (including the early return) in the same try/except, and make the warning message not specific to the CEC probe so it stays accurate for both branches.
    if not diagnostics.cec_available():
        r.set('display_power', 'Not available', ex=3600)
        return
    try:
        # Single SET with ex= so the value and its TTL are written
        # atomically — a soft-limit signal landing between a separate
        # SET and EXPIRE would otherwise leave the key without a TTL
        # (a stale display_power that never expires).
        r.set('display_power', str(diagnostics.get_display_power()), ex=3600)
    except SoftTimeLimitExceeded:
        # The CEC query is meant to be bounded by its own
        # subprocess timeout, but a child wedged in libcec can keep
        # the pipe open past it. Skip this tick rather than let the
        # hard limit SIGKILL the worker (ANTHIAS-A / 9 / B); the next
        # beat tick re-queries.
        logging.warning(
            'get_display_power: CEC query exceeded %ss; skipping this tick',
            PERIODIC_POKE_SOFT_TIME_LIMIT_S,
        )

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

The Device model card joined the raw DMI sys_vendor, product_name and
CPU brand, so a reference/whitebox board rendered
'Intel Corporation Whiskey Platform · Intel Celeron 4205U @ 1.80GHz'
— a corporate suffix plus an 'Intel ... · Intel ...' stutter.

Trim trailing corporate suffixes (Corporation / Inc. / Ltd. / …) from
the vendor, and drop the board vendor entirely when the CPU brand
already names it (whitebox boards set sys_vendor to the CPU maker).
Branded OEM boxes keep their vendor because it differs from the CPU:
'Dell Inc. OptiPlex 7090' -> 'Dell OptiPlex 7090'. The x86 label
becomes 'Whiskey Platform · Intel Celeron 4205U @ 1.80GHz'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vpetersson vpetersson changed the title fix(system-info): show 'Not available' for CEC power on non-CEC boards fix(system-info): tidy up x86 Device Info (CEC state + device model) Jul 6, 2026
@vpetersson vpetersson requested a review from Copilot July 6, 2026 20:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

The Device model card joined the board and CPU into one string with a
'·', so a long x86 label word-wrapped at an arbitrary point (splitting
the CPU model, e.g. 'Intel Celeron' | '4205U ...').

Return the board and CPU as separate parts (get_device_model_parts) and
render the CPU as the card's secondary line, so the two facts stack
cleanly with no separator and no mid-model wrap:

    Whiskey Platform
    Intel Celeron 4205U @ 1.80GHz

Pi keeps its single firmware Model line (no secondary row).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Jul 6, 2026

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

@vpetersson vpetersson merged commit 58bf1a7 into master Jul 6, 2026
10 checks passed
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.

2 participants