Repository navigation
Conversation
Wake the AV receiver (or TV) on the far end of a Pi's HDMI link and switch
it to our input before Sendspin audio hits the HDMI output, instead of
failing to open the vc4-hdmi ALSA device while the receiver is in standby.
UniversalProxy.Cec drives `cec-ctl` from v4l-utils (shipped by the
nerves_systems_universal_proxy rpi4 system >= 0.1.12) rather than a NIF:
the kernel keeps the claimed logical address as adapter state, so one
`--playback` claim at boot and short-lived one-shots for everything else
are enough.
- Cec.Enumerate: /dev/cecN adapters, paired with the HDMI ALSA card via the
shared platform device under /sys/class/{cec,sound}/*/device.
- Cec.Server: discovery (10 s hotplug scan), claim + physical address,
receiver power/volume/mute state from bus traffic; subscribes to the
Sendspin state topic and fires One Touch Play (Image View On + Active
Source) on `stream_start` for the paired HDMI output.
- Cec.Monitor: one `cec-ctl -m` per adapter, parsed into PubSub records.
- Cec.Parser: monitor stream, one-shot replies, Driver Info.
- Cec facade: one_touch_play, standby, power_status, audio_status,
volume_up/down, mute, user_control — catch :exit idiom like the other
optional subsystems; commands run in the caller's process.
- Supervisor returns :ignore unless `UniversalProxy.Cec` has enabled: true
(set in config/target.exs), so host/test never spawn cec-ctl.
- mix.exs: UP_SYSTEMS_PATH switches the custom systems to path: deps on a
local checkout, for building against a locally built system.
Tests cover the parser formats, sysfs pairing, discovery, auto-wake on
stream_start, receiver state updates, hotplug removal and the facade's
degraded behaviour, with a recording fake cec-ctl in test/support.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3zFyNeDAeaCXyznuLUnv8
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved CEC symlink-resolution and monitor-lifecycle defects can prevent receiver wake-up and cause duplicate events, while the pinned system release lacks the required CEC commands.
6 open issues
Resolve sysfs symlinks before pairing ALSA and CEC devices · New Normalize HDMI names in the default discovery path · New Track replacement monitor processes after crashes · New Filter power reports by the configured receiver address · New Restart MonitorSupervisor with Server on crashes · New Pin firmware to a release that includes cec-ctl · New
What changed in this PR
This PR adds friendlier HDMI output defaults and introduces HDMI-CEC control alongside the existing Sendspin audio subsystem.
Changes:
- Adds HDMI display-name defaults while preserving saved names.
- Introduces CEC discovery, monitoring, receiver commands, and automatic One Touch Play on stream start.
- Adds tests, firmware configuration, and a local Nerves-system dependency override.
| File | Description |
|---|---|
test/universal_proxy/cec/server_test.exs |
Tests discovery, auto-wake, receiver state, and facade commands. |
test/universal_proxy/cec/parser_test.exs |
Tests CEC output parsing and status decoding. |
test/universal_proxy/cec/enumerate_test.exs |
Tests adapter-to-audio-card pairing. |
test/universal_proxy/audio/store_test.exs |
Tests HDMI naming defaults and saved-name preservation. |
test/support/fake_cec_ctl.ex |
Provides recorded commands and canned CEC responses. |
README.md |
Documents CEC support and local system builds. |
mix.exs |
Adds the UP_SYSTEMS_PATH dependency override. |
lib/universal_proxy/cec/supervisor.ex |
Defines the CEC supervision subtree. |
lib/universal_proxy/cec/server.ex |
Manages adapters, receiver state, and automatic wake-up. |
lib/universal_proxy/cec/parser.ex |
Decodes CEC messages, events, and adapter information. |
lib/universal_proxy/cec/monitor.ex |
Runs per-adapter monitors and broadcasts parsed events. |
lib/universal_proxy/cec/enumerate.ex |
Discovers CEC adapters and pairs ALSA cards. |
lib/universal_proxy/cec/ctl.ex |
Runs cec-ctl and builds command arguments. |
lib/universal_proxy/cec.ex |
Exposes receiver control and status APIs. |
lib/universal_proxy/audio/store.ex |
Adds friendlier HDMI fallback names. |
lib/universal_proxy/application.ex |
Adds CEC to application supervision. |
config/target.exs |
Enables CEC on firmware targets. |
config/config.exs |
Defines CEC defaults, disabled on host. |
Review effort: Balanced
| github: "bbangert/nerves_systems_universal_proxy", | ||
| sparse: to_string(target), | ||
| tag: @up_systems_tag |
Resolve sysfs symlinks before pairing ALSA cards with CEC adapters, name monitors through a Registry so a restarted one is still stopped on unplug, restart the CEC subtree one_for_all, only take status reports from the receiver, and apply the HDMI name when outputs are first discovered. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
The pinned system lacks cec-ctl, while CEC handling can leave cached state stale, report failed transmissions as successful, and leak subprocesses when the monitor is killed.
6 open issues
Pin a CEC-capable custom systems release · New Validate cec-ctl transmission failures before success · New Complete final cec-ctl message when output goes silent · New Terminate cec-ctl when its BEAM owner exits · New Parse cec-ctl monotonic event timestamps · New Pin firmware to a release that includes cec-ctl
5 resolved since last review
Review effort: Balanced
| # HDMI-CEC: the custom rpi0_2/rpi4 systems (>= v0.1.12) ship cec-ctl and the | ||
| # vc4 CEC driver. On a system without either the subsystem simply finds no | ||
| # adapters (no /dev/cecN) or logs that cec-ctl is missing. | ||
| config :universal_proxy, UniversalProxy.Cec, enabled: true |
There was a problem hiding this comment.
Same issue as the mix.exs pin thread. It stays open until there is a systems release with cec-ctl. The CEC system change currently exists only on lawik/nerves_systems_universal_proxy hdmi (3d962d7) and needs a PR to the systems repo and a v0.1.12 release. Until then, CEC on a v0.1.11 system finds cec-ctl missing: the monitor stops with :cec_ctl_missing and logs a warning instead of crashing.
Generated by Claude Code
cec-ctl exits 0 on a failed send, so check each reported transmit status; run the monitor with -v so its Sequence trailer completes each message; accept cec-ctl's real event timestamp formats; and run the monitor under MuonTrap so cec-ctl dies with its owner. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>


No description provided.