Skip to content

Changelog

All notable changes to emeet-pixyd are documented here.

  • Documentation website launched at emeet-pixyd.lars.software
  • Device recognition — the daemon now classifies everything on the bus: controllable PIXY-family devices, known fixed EMEET webcams (C960 family, C950, C970, S600L), and unknown EMEET products. Fixed webcams are recognized but never receive vendor commands (the standard UVC driver already handles them completely); when no PIXY is present the daemon logs an actionable hint, and emeet-pixy device repeats it. See Supported Devices
  • EMEET_PIXYD_EXTRA_PRODUCT_IDS — onboard unlisted PIXY-family variants (a regional SKU or the wireless model when it lands) without waiting for a release: comma-separated hex product IDs, displayed as PIXY (PID 0x…)

New HID Command Families (official V2 protocol)

Section titled “New HID Command Families (official V2 protocol)”

The official EMEET STUDIO command table (162 command heads) was extracted from the vendor binary — the daemon now speaks the same protocol:

  • Motor speed — speed <pan|tilt|zoom> <value> over the official SetMotorSpeed command, plus three speed sliders in the web UI
  • Tracking variants — tracking <none|face|halfbody|fullbody> with a web picker, one level below the binary track switch. The enum was corrected to the official app’s 1-based scheme (0 = “No Smart Composition”, decoded from the official binary); variants persist across daemon restarts
  • Battery/charge — battery command plus battery lines in status, Waybar, and the web panel (best-effort: absence is an expected outcome)
  • Motor-preset mirroring — preset push <name> moves the camera and saves the position into a hardware slot, and preset pull sweeps hardware slots back into software presets (read-only, never overwrites your named presets) with a Pull button in the web panel
  • Identity queries — device output now includes serial number, firmware versions, and the capability bitfield when the device answers
  • Camera model — detected PIXY vs PIXY 2K shows in the web panel footer, Waybar tooltip, and Waybar JSON
  • Permission warning on hotplug — the udev hint now fires when the device appears, not only at daemon startup

The vendor’s Windows app (2.0.0-Beta.25) was re-acquired and disassembled; its parser code corrected several of our documented assumptions:

  • V2 response framing — responses echo the 4-byte request head, carry a reserved dword, and place the payload at offset 8 (minimum length 9). Our parsers previously assumed offset 4 and would have misread every V2 response on real hardware
  • Tracking enum — official values are 1-based with 0 = none; the none variant (“No Smart Composition”) is now exposed
  • Charge status semantics — charge values 1 and 2 both mean “charging” (0 = discharging); the Waybar output now tags charging/discharging classes on the battery line
  • Cross-verification — 108 of the 162 extracted command heads confirmed byte-for-byte in the Windows build, zero contradictions; the other 53 are absent from that build (verified by exhaustive scan), and command IDs are identical between the two app versions
  • Echo routing mask — official parsers mask the response’s device byte (& 0x1F) before validating the echo; our parsers do the same, so both motor-routing forms validate
  • Speed persistence — configured motor speeds survive restarts (state.json) and are re-asserted before every move

All corrections are statically evidenced from the official binary; hardware confirmation is tracked for the next device session.

  • /proc/*/fd scanning for universal call detection
  • Debounced state transitions (configurable count + interval)
  • Four auto modes: full, tracking-only, privacy-only, off
  • Dark-themed glass-morphism control panel
  • Live MJPEG camera preview with snapshot
  • PTZ sliders with spatial position radar
  • Camera mode cards with SVG icons and keyboard shortcuts
  • Preset save/load/delete chips
  • Server-Sent Events for live state updates
  • Automatic PipeWire default source switching via wpctl
  • Three audio modes: Noise Cancel, Live, Original
  • Hardware-verified pan (-150 to 150 degrees), tilt (-90 to 90), zoom (100 to 150)
  • Absolute and relative positioning modes
  • Delayed hardware readback (500ms) to correct cache
  • Named presets with validation
  • NixOS module with udev rules, systemd user service, tmpfiles.d
  • Waybar JSON output with CSS class variants
  • Prometheus metrics via OpenTelemetry SDK
  • Netlink uevent listener for USB hotplug
  • systemd sd_notify (READY=1, WATCHDOG=1)
  • Dependency injection via function fields (no interfaces for external deps)
  • Branded types (PID, SourceID) for compile-time safety
  • Split locks (hidMu + v4l2Mu) for concurrency
  • Atomic state persistence (.tmp + rename)
  • Schema-versioned state file for forward compatibility

EMEET_PIXYD_AUTO=true / false / 1 / 0 are still accepted but mapped to full / off. New code should use the explicit enum values.

CLI accepts "org" as shorthand for "original". The stored value is always "original". Both are accepted by ParseAudioMode.

The state file now carries a "v" field. Old state files missing this field load as version 0. The daemon logs a warning but still loads the data.