Muse Clock is a Lenovo Smart Clock running Debian 12 ARM64 with a custom interface for the Muse voice assistant. It uses the original display, buttons, microphone, and speaker. Additional features include AirPlay audio, timers, notifications, AI usage monitor, and connections to local automation services.
The software runs on the clock's internal storage using Lenovo's original Linux kernel. Muse provides the assistant connection, while a separate local server generates speech with Kokoro. The clock handles input, display, audio playback, and requests to configured services.
This article covers the implemented features, hardware changes, and installation method. The screenshots are unaltered captures from the installed Word Clock theme's on-device preview cycle.
Linux installation · Muse SDK · Connected controls
Voice controls and audio
Holding + records a request; releasing it sends the recording to Muse and closes microphone capture. The avatar indicates listening, thinking, and speaking. When music is playing, the clock lowers it for the spoken response and restores it afterward. This sequence was checked on the device.
Tapping − switches between the active display and a dim clock on black. Muse commands, the Maurice connection, and notifications remain available in standby. The rear microphone switch remains available as a hardware control.
The Muse Linux Gadget SDK provides device pairing and the command connection. Our application adds the controls, interface, voice adapter, and coordination between audio services. Reply text goes to Kokoro on a separate local server; the assistant model does not run on the clock.
The clock also operates as an AirPlay 2 audio receiver using Shairport Sync. Its music screen displays track information and artwork. Vertical swipes adjust volume, and the setting persists after a restart. The animated bars use colors from the artwork; they do not measure the audio signal.
Audio testing identified truncated spoken replies and a kernel audio-buffer problem that could reboot the clock after playback. Subsequent device checks covered complete replies, interruptions, and restoration of music.
Timers, usage, and notifications
The timer supports start, pause, resume, cancel, and remaining-time requests through Muse, as well as touch controls on the clock. Its display includes a countdown and an animated hourglass. Starting or resuming a timer wakes the display; completion wakes it again and plays a chime. The installed command handlers and standby transitions were checked. A final spoken timer-request test was still pending in that record.
The AI usage clock displays Codex usage as a percentage and ring, with a countdown to the reset. Swipe right from home to open it, and swipe left or tap Home to return. A refresh requests current information through the Mac integration. If a refresh is unavailable, the saved reading is labeled cached.
Notifications increment the inbox count without replacing the current screen. In the inbox, vertical swipes scroll a card and horizontal swipes change cards; those gestures do not adjust volume. The PDF reader supports page navigation, zoom, margin controls, and a saved reading position. File delivery remained partly unresolved because of slow transfers and a rejected private download route.
The installed appearances include Classic, plain and image versions of Quiet Clock, Ambient Stage, and Midnight Terminal, plus Word Clock, Windows XP, and Mac OS X Aqua. The selected theme applies across the timer, inbox, music, and usage screens and persists after restart. Holding + and − together opens the preview cycle, including a device-details screen.
Halloween decoration controls
Muse Clock connects to the local Monster Lab controller through a searchable API catalog. The controller exposes operations for animated eyes, face or motion tracking, floodlight color and brightness, saved scenes, scene loops, scare sounds, background audio, projector playlists, and daily on/off schedules.
Muse can use the catalog to find an operation and its parameters before submitting a request through the clock. Examples include selecting an eye theme, setting lights to orange, or scheduling systems to start and stop. Schedules repeat daily in the controller's timezone; a schedule named for Halloween is not automatically limited to October 31. Scene loops can continue after the browser closes.
During integration, we corrected support for the controller's required request header, created a temporary schedule through the clock, read it back, and removed it. This verified the scheduling API connection. It did not verify the physical response of every connected decoration.
iOS Shortcuts through Maurice
Maurice for iOS exposes registered Apple Shortcuts through a local REST API. The clock's Maurice connector allows Muse to select a Shortcut and supply input parameters. The execution sequence is Muse → clock → Maurice on the iPhone → Apple Shortcuts.
The Shortcut runs on the iPhone with its configured apps and permissions. This allows existing iOS workflows to be invoked from the clock without implementing them again in the clock application. The connection did not require a new public endpoint or port forwarding.
After the Halloween schedule test, the clock requested a completion text through Maurice, which reported success. That response confirms Maurice's reported result; it does not independently establish delivery by every downstream service.
Linux installation method
The target was a Lenovo Smart Clock CD-24501F with a MediaTek MT8167S. Our approach retained the vendor's 4.4.95+ Linux kernel, replaced the boot ramdisk, and put Debian userspace on internal storage. The result boots Linux directly; its Debian services run in a chroot under a BusyBox-based startup environment.
1. Preserve the original system. We began from an already AVB-unlocked clock and verified the existing full-flash backup with checksums. The original boot image remained available for recovery. Android's Fastboot code documents the host-side tool used to communicate with the bootloader.
2. Replace the ramdisk, retain the hardware kernel. We repacked the stock kernel and device tree with a custom BusyBox initramfs. Temporary fastboot boot attempts failed: the vendor bootloader passed ramdisk arguments using an obsolete function signature. Its normal storage-boot path passed them correctly. We therefore flashed the bootstrap to boot_a, checked its readback, and used normal startup without modifying the bootloader itself.
3. Install Debian's ARM64 filesystem. A small custom USB service provided a shell and file transfer when the stock Android connection daemon did not. We downloaded and verified the Bookworm ARM64 filesystem layers from debuerreotype's Debian artifacts, then unpacked them into /mnt/data/muse-linux on internal storage.
4. Start services inside the chroot. Startup scripts bind-mounted /dev and /dev/pts, mounted /proc, /sys, and /run, and entered Debian with chroot. BusyBox remained PID 1; custom scripts supervised networking, Bluetooth, Muse, and the screen. This build does not use systemd as its service manager.
5. Adapt the vendor hardware interfaces. The stock Wi-Fi modules were reused. Bluetooth needed a compatibility bridge to the Linux HCI interface, and the display needed an exact-build framebuffer mapping fix plus backlight configuration. Lenovo's Smart Clock source release supplied vendor reference code. We saved the fixes into startup and verified the screen and radios after a restart.
Display changes. The initial black screen involved a backlight fault and a framebuffer mapping error. The stock driver treated a graphics-device address as a physical memory address, preventing application writes from reaching the display buffer. We corrected the mapping and rotation, saved the changes in startup, and verified the display after a restart.
Boot path: vendor bootloader → boot_a → vendor kernel + BusyBox initramfs → internal Debian chroot → Muse Clock services.
These links identify upstream code and source material. The custom bootstrap, USB service, and hardware patches are local project components, not a complete installer provided by those repositories.
Muse SDK integration
6. Install the SDK inside Debian. We prepared the Python-based Muse Linux Gadget SDK in the ARM64 filesystem, with its virtual environment at /opt/musegadget/venv. Its package definition identifies the cryptography and websockets dependencies. The clock's startup scripts launch our runtime with that interpreter. Because BusyBox owns startup, our supervisor replaces the standard systemd service setup described upstream.
7. Pair through Bluetooth LE. The vendor-to-HCI bridge, BlueZ, and system D-Bus gave the SDK the Bluetooth peripheral support needed for discovery. We opened pairing with musegadget pair, enabled Developer mode in the Muse phone app, and added the clock. Wi-Fi was configured separately in Linux; the app's network step did not replace that configuration. The SDK credential was stored with root-only permissions, and pairing state persisted on internal storage so ordinary restarts did not require pairing again.
8. Establish the command connection. The SDK's service layer handles connection retries and credential refresh. Its link client opens an authenticated WebSocket, establishes a Noise XX encrypted session, and registers capabilities on /link-control. Commands arrive as link.invoke; the device returns link.result. Our integration eventually separated this command connection from the long-lived voice-reply stream after sharing them prevented commands from arriving.
9. Add clock-specific commands. The upstream executor defines system.run, file.read, file.write, and device.health. File operations transfer chunks of up to 64 KiB; they are not a continuous attachment-download service. We added timer controls, notification delivery, and configured API connectors around the local runtime. Shell and file access follow the configured execution account's permissions; the API connector restrictions do not apply to all SDK operations.
10. Add the voice adapter. Our custom voice adapter reuses the SDK's identity and encrypted transport. Holding + captures a voice note; release sends it to Muse, and the reply handler selects the response belonging to that conversation turn. Reply text goes to Kokoro on a separate local server, then audio returns to the clock's speaker. The application coordinates avatar states, interruption, and the music handoff. The voice adapter and audio coordination are clock-specific additions to the SDK.
Verification: the build record confirmed automatic reconnection after restart, successful live health and notification requests after the connection fix, and a physical hold-to-talk test with music quieting, a spoken answer, and music returning. The links above expose upstream implementation details; our clock adapter and service scripts remain local project code.
Connected controls: APIs and local state
Halloween discovery and control. The Yoda adapter provides catalog search, catalog refresh, and request execution for the Monster Lab controller. Its initial catalog described 49 operations. Muse can search definitions, discover current scene or media IDs, and submit a documented request. The clock calls the configured controller; the controller handles the eyes, lights, audio, and projector.
Lighting requests specify a target, action, color, and brightness. Scheduling requests specify start and stop times plus the systems to enable or disable. Writes use JSON with the controller's required request header. When a write times out, status must be checked before retrying: repeating it could create a duplicate schedule. Light readback reports the controller's saved state, not an electronic acknowledgement from a fixture.
The local API connectors use configured destinations, reject redirects, and bound requests. A failed catalog refresh preserves the existing catalog. These restrictions apply to the connectors; SDK shell and file operations retain the execution account's permissions.
iOS Shortcuts through Maurice. The adapter is restricted to the configured Maurice server and its supported API operations. It discovers registered Shortcuts, selects one by name or ID, and passes input parameters to Maurice's executor. That executor invokes Apple's Shortcuts URL and callback mechanism. The iPhone must be available, with the Shortcut registered and its required permissions satisfied. An API response is evidence from Maurice, not independent proof of every downstream action.
Built-in tools use local state. The timer commands update the clock's own countdown and display state through the existing SDK integration. Notifications enter the local inbox without taking over the screen. The Codex usage view reads a saved snapshot supplied through the Mac integration and marks unavailable refreshes as cached. A running timer, an incoming notification, and an externally sourced usage reading therefore have different update paths, even though they share one interface.
The Halloween controller, Maurice app, and clock adapters are separate project codebases. The Maurice App Store listing describes the iOS application; the SDK links above point to its upstream implementation.