Repository navigation
feat(device-discovery): integrate device_discoveryd for device-driven printer config and hotplug - #350
Merged
Conversation
When updating the system for the first time, the configurator will sync the config repo with the printer config directory, but it will create rescursive nested config dirs, the problem has two parts, first, the rescursiveness only happens when there is an update, and the repo/printer config are out of sync, the second is because of the legacy configurations. We now clean the previous printer config repo dirs, before actually symlinking the repo with the printer configurations. This is only part of the fix. The second part of this commit, adds the second sync mode to the tool, but it will not be used right now, this is prepign for future work.
Co-authored-by: Guilherme Costa <guilherme.costa@blockstec.com> Signed-off-by: Hugo Costa <hugo.santos.costa@gmail.com>
There was a problem with printer.cfg merging, everytime merging occured two things happened, first was that the beacon section on pritner.cfg was not ignored, this made the configured serial path to be lost, the second problem was that the saved configuration (footer) was duplicated everytime, so if the screen restarted we whould have thounsands of lines duplicated. With this fix, both issues are resolved. Another quality of life is that, the deletetion of the printer configurations subdirectories is not done unless there is actually something different between the config repo and the printers config dir.
…figurator-saved-duplication
…marker There were a bunch of problems that would make merging files difficult, one of those was the merger or configparser sections, the default is to use = but the code was using : to set values to options. Then there was a problem when checking nestes config dirs on the default configuration directory. This looks like it has been solved as well.
…on' into feat/device-discovery
Fix fallout from the merge:
- Remove a leftover conflict marker in tests/updater/test_executor_unit.py.
- Store the updater's last-seen HEAD as a dict state entry ("_updater"):
Release-2.0's self-heal reconcile drops non-dict entries, which made every
boot look like a fresh self-update, and NRestarts priming called .get on it.
- Skip enable_service when a provisioned unit is not installed yet
(install-updater.sh enables it).
- Stub DeviceConfigManager/DeviceConfigWatcher in test_sigterm_shutdown.py.
- DeviceDiscovery hook comment: HOOK_TIMEOUT is now 600 s.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
device_discoveryd now reports USB vendor/product IDs for serial devices (DeviceDiscovery "Report USB vendor/product IDs for serial devices"), so the AMU profile matches on 0x1d50:0xb001 and a reported ID is final: an AMU on Klipper's stock ID is no longer recognised by its "AMU" name. USB_IDS.md and the profile comments described the old fallback. Watcher tests used a fake manager that matched on the name, so the ID path was never exercised: add tests that run the daemon's actual AMU entries through the real profiles. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- AMU profile writes [mcu mmu] (the MCU Happy Hare's mmu.cfg uses) and asks the user first (confirm: true); consent persists in ~/.config/blockscreen/device_consent.json - USB vendor/product IDs are read from sysfs, since device_discoveryd reports 0 for serial entries - Boot scan merges the daemon snapshot with /dev/serial/by-id; printer.cfg writes are atomic; boot-time changes trigger a Klipper restart - Watcher polls /dev/serial/by-id when the daemon is unreachable - MainWindow shows a Configure / Not now prompt and restarts Klipper via machine.services.restart once no job is running - Discovery client resolves the socket path on every connection attempt - INFO logs along the whole hotplug path Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dedupe sync and client framing, fix SAVE_CONFIG key indent
gmmcosta15
approved these changes
Oct 14, 2026
RobeMartins
approved these changes
Oct 14, 2026
1 of 4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This branch moves serial device detection from BlocksScreen to the external device_discoveryd daemon, and uses the daemon's device list to keep printer.cfg matched to the hardware that's actually connected.
At boot, BlocksScreen applies the configs for connected devices to printer.cfg and writes the file atomically. If anything changed, it restarts Klipper once Moonraker is up and no print is running. While the screen runs, plugging in a device adds its config, and if the daemon can't be reached, the screen polls /dev/serial/by-id instead. Devices are described by templates in device_profiles.yaml. The AMU is matched by USB ID and only gets [mcu mmu] written after the user confirms, and the beacon's serial path is added automatically.
It also fixes several configuration manager bugs: recursive nested config dirs, the beacon serial path being lost on merge, and the SAVE_CONFIG footer being duplicated on every restart. Files and symlinks are now only rewritten when their content changed.
On the updater side, DeviceDiscovery is now a managed component with its own update hook, and first-time setup runs in install-updater.sh. RF50-Klipper tracks feat/amu-configs for the AMU configs, and BlocksScreen tracks dev. The default log level is now INFO, and the new code paths have unit tests.
Changes