Skip to content

feat: Add DDC power mode (VCP 0xD6) support for HDMI display on/off#194

Open
caraar12345 wants to merge 1 commit intoleukipp:mainfrom
caraar12345:feat/ddc-power-mode
Open

feat: Add DDC power mode (VCP 0xD6) support for HDMI display on/off#194
caraar12345 wants to merge 1 commit intoleukipp:mainfrom
caraar12345:feat/ddc-power-mode

Conversation

@caraar12345
Copy link
Copy Markdown

Summary

  • Adds ddcutil setvcp/getvcp 0xD6 as a display status command for HDMI touchscreens that support DDC/CI power mode control
  • Preferred over DPMS when ddcutil is already used for brightness (no sysfs backlight — the exact scenario where DPMS shows "No signal" instead of turning off the panel)
  • Falls back to ddcutil when no DPMS tool (wlopm/kscreen-doctor/xset) is available but the display supports VCP feature D6

Problem

On HDMI-connected touchscreens without a sysfs backlight, the existing DPMS-based display on/off (wlopm/kscreen-doctor/xset) kills the HDMI signal rather than turning the panel off. The monitor shows "No signal" instead of actually powering down. TouchKio already uses ddcutil for brightness control on these screens — the same infrastructure can control power mode.

Solution

DDC/CI VCP feature 0xD6 (Power mode) properly turns HDMI panels off (0x04) and on (0x01) without losing the HDMI link. This PR:

  1. Detects D6 support during getDisplayBrightnessCommand() init (which already calls ddcutil capabilities), storing the result in HARDWARE.display.status.ddcPowerMode
  2. Selects ddcutil as the status command when:
    • ddcutil is already used for brightness AND D6 is supported (preferred), or
    • No DPMS tool is available AND D6 is supported (fallback)
  3. Gets display status via ddcutil getvcp d6 --brief (parses x01=ON, x04=OFF)
  4. Sets display status via ddcutil setvcp --noverify d6 <value> with cache file tracking
  5. Polls status changes via a Status.vcp cache file (same pattern as Brightness.vcp) to avoid slow ddcutil polling in the 1s update loop

Note on --noverify

The --noverify flag is required because many monitors return a DDC verification error on power-on even though the command succeeds. This is a well-known ddcutil behaviour (see ddcutil#36). Without it, successful power commands would be reported as failures.

Init reorder

Brightness detection is moved before status command detection in init() because getDisplayStatusCommand() now checks whether ddcutil is already being used for brightness to decide whether to prefer DDC power mode over DPMS.

Closes #187

Test plan

  • Verify Supported: {...} output at startup shows displayStatus: true on an HDMI touchscreen with ddcutil and D6 support
  • Verify startup log shows Display Status [ddc://vcp/feature/0xD6]: ON (ddcutil)
  • Send "OFF" via MQTT (light.turn_off) → screen turns off properly (no "No signal")
  • Send "ON" via MQTT (light.turn_on) → screen turns back on
  • Verify getDisplayStatus() correctly reports ON/OFF based on ddcutil getvcp d6
  • Verify brightness control continues to work independently
  • Verify existing DPMS setups (wlopm/kscreen-doctor/xset) are unaffected

🤖 Generated with Claude Code

HDMI-connected touchscreens without a sysfs backlight respond to DPMS
commands by showing "No signal" rather than actually turning the panel
off.  Many of these displays support DDC/CI power mode control via
VCP feature 0xD6, which properly turns the panel off/on without losing
the HDMI link.

This adds ddcutil setvcp/getvcp 0xD6 as a display status command:
- Preferred when ddcutil is already used for brightness (no sysfs
  backlight), since that is the exact failure scenario for DPMS
- Falls back to ddcutil when no DPMS tool is available
- Uses --noverify on setvcp because many monitors return a
  verification error on power-on despite the command succeeding
- Tracks status changes via a Status.vcp cache file (same pattern
  as brightness) to avoid slow ddcutil polling in the update loop

Closes leukipp#187

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@caraar12345
Copy link
Copy Markdown
Author

argh I did not mean to allow Claude to PR it straight away; I wanted to check through it first 😅

changes may be incoming - sorry for the possible slop 🙇

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.

Anmite HDMI Touchscreen: Brightness control works but cannot turn off screen

1 participant