ποΈ CLIs to Get/Set/Stream Mac Hardware Outputs & Sensors Inputs
August 29, 2026 Β· View on GitHub
Modern MacBook Pros are full of interesting hardware: lid-angle and ambient-light sensors, microphones, undocumented MEMS accelerometers and gyroscopes, plus fast controls for keyboard/display brightness, speakers, fans, and more.
This repo exposes that hardware as small, fast, composable Unix CLIs backed by Appleβs private APIs.
-
sensors: (ο£Ώ only supported on non-Intel Apple laptops)
- π³
accelerometer - πͺ
gyroscope - π€οΈοΈ
microphone - π»
lid-angle - π‘
ambient-light
- π³
-
transformers: (pipe any signal source in, outputs new signal)
- π
volume-shift - β
frequency-shift - π
bandpass - π₯
metronome - β€οΈ
heartbeatdetect human-heartbeat BPM or any dominant beat in music or other sensor data between 60 ~ 180 BPM
- π
-
outputs:
- π
visualizer(live TUI that shows frequency bins, histogram, and more) - π
speaker - β¨οΈ
keyboard-brightness(ο£Ώ only onM*Mac laptops) - π
screen-brightness(ο£Ώ only onM*Mac laptops) - π£
fan-speed(ο£Ώ only onM*Mac laptops)
- π
Quickstart
# recommended: install the suite with uv
uv tool install mac-hardware-toys
# show FFT + more info about current motion
accelerometer | visualizer
# pulses your keyboard lights to the beat
microphone | heartbeat | keyboard-brightness
# or get/set raw values directly, and more...
keyboard-brightness --help
All commands have basic args like --set ..., --json, --raw, making it easy to do useful things with your mac hardware.
- π‘ Flash your β¨οΈ keyboard lights + play a sound when a background processes completes
- π΅ Pulse your fans in sync with some musc playing ambiently π΅ music bpm
- β€οΈ Pulse your screen brightness in sync with your heart, detecting your pulse from wrists resting on laptop (via accelerometer)
- π¬ Get/Set/Stream accelerometer+gyroscope+microphone/etc. data as simple
--rawscalar values or--json, or...
By default when used in pipes, commands represent signals as an audible πΌ mono audio tone, expressed as a byte stream.
π€ read realtime sensor feeds represented as sine waves
ποΈ mix/filter/transform those sine waves to shape them
π emit piped realtime signal to speakers/any other hw output
Tip
Some truly wild things are possible now that you can pipe together anything on your Mac...
π· Share your craziest combos!

Quickstart
pip install mac-hardware-toys
# or
uvx tool add mac-hardware-toys
Examples
# flash your screen according to your microphone input
microphone | screen-brightness
# play a sine wave tone based on your screen lid-angle
lid-angle | speaker
# flash the keyboard according to your heartbeat (keep your wrists on palm rests)
accelerometer | metronome | keyboard-brightness
# see more detail about any given signal by piping it into visualizer
microphone | visualizer
sine 1000 | visualizer
gyroscope | tee >(speaker) | visualizer
Tools
accelerometer
- Purpose: read Apple SPU accelerometer and emit mono signal.
- Args:
--rate <hz>(<= 800),--axis x|y|z|mag,--raw. - Notes: requires root; when run from a terminal it auto-prompts via
sudo.
ambient-light
- Purpose: read ambient light sensor and emit tone mapped from low light to high light.
- Default mapping:
500 Hz -> 5000 Hzand low volume -> high volume as light goes0% -> 100%. - Args:
--rate,--low-hz,--high-hz,--low-volume,--high-volume,--json. - Notes: requires root; when run from a terminal it auto-prompts via
sudo.
lid-angle
- Purpose: read lid angle sensor and emit tone mapped from lid closed to open.
- Default mapping:
500 Hz -> 5000 Hzand low volume -> high volume as angle goes--angle-min -> --angle-max. - Args:
--rate,--low-hz,--high-hz,--low-volume,--high-volume,--angle-min,--angle-max,--json. - Notes: requires root; when run from a terminal it auto-prompts via
sudo.
gyroscope
- Purpose: read fused orientation (accel+gyro, Mahony AHRS) and emit tone mapped from the selected orientation axis.
- Default mapping:
500 Hz -> 5000 Hzand low volume -> high volume as selected axis angle maps to0..360. - Args:
--rate,--low-hz,--high-hz,--low-volume,--high-volume,--json,--axis roll|pitch|yaw,--decimate. - Notes: requires root; when run from a terminal it auto-prompts via
sudo.roll/pitchare absolute to gravity;yawis relative and can drift without magnetometer.
microphone
- Purpose: capture mono mic signal and emit stream.
- Args:
--rate <hz>,--block-size <frames>.
metronome [bpm]
- Purpose: emit metronome pulses; with piped stdin it auto-detects/follows BPM.
- Args: optional
bpm,--rate(fixed mode),--pulse-ms,--tone-hz,--level,--accent-every,--accent-gain,--block-size,--count,--min-bpm,--max-bpm,--detect-low-hz,--detect-high-hz,--self-echo-ms,--follow,--debug,--raw.
bandpass <low_hz> <high_hz>
- Purpose: realtime cascaded high/low-pass filter.
- Args: positional cutoffs or
--low/--high,--chunk-bytes,--raw --rate.
frequency-shift <factor>
- Purpose: best-effort realtime frequency scaling, takes a scalar multiplier like 0.1~1000.
- Args:
factor,--chunk-bytes,--raw --rate.
volume-shift <gain>
- Purpose: scalar amplitude gain.
- Args:
gain,--chunk-bytes,--raw --rate.
heartbeat
- Purpose: emit BPM/confidence JSON lines from incoming signal (typically bandpassed). When piped onward, it passes the signal through on stdout and writes JSON to stderr. Perfect for detecting your actual heartbeat from the subtle pulsing of your wrists resting on the palmrests. Also works great for detecting BPM from music.
- Args:
--interval,--window-seconds,--emit-final,--chunk-bytes,--raw --rate.
speaker
- Purpose: play incoming stream on default output device.
- Args:
--device-rate,--block-size.
visualizer
- Purpose: terminal waveform + level monitor.
- Args:
--fps,--window-seconds,--chunk-bytes,--raw --rate.
keyboard-brightness
- Purpose: beat-follow keyboard backlight control.
- Args:
--send-hz,--fade-ms,--gain,--attack-ms,--release-ms,--baseline-ms,--decay-per-s,--debug,--as-root,--pulse,--on-time,--off-time,--set. - Notes:
--set=<0..100>without--pulsesets brightness and exits immediately (ignores stdin).--pulse=<N>ignores stdin and pulses N times;--setcontrols pulse max brightness.
screen-brightness
- Purpose: beat-follow display brightness control.
- Args:
--send-hz,--min-level,--max-level,--gain,--attack-ms,--release-ms,--baseline-ms,--decay-per-s,--debug,--no-restore,--pulse,--on-time,--off-time,--set. - Notes:
--set=<0..100>without--pulsesets display brightness and exits immediately (ignores stdin).--pulse=<N>ignores stdin and pulses N times;--setcontrols pulse max brightness.
fan-speed
- Purpose: signal-follow fan RPM control (both fans in sync by default; beat-alternating optional).
- Args:
--send-hz,--min-rpm,--max-rpm,--min-frac,--max-frac,--pulse-depth,--couple,--alternate,--input-map,--beat-threshold,--beat-hold-ms,--gain,--attack-ms,--release-ms,--baseline-ms,--decay-per-s,--debug,--no-restore.
Example Usage
Heartbeat from accelerometer:
accelerometer | bandpass 0.8 3 | heartbeat
Ambient light as signal source:
ambient-light | visualizer
Lid angle as JSONL:
lid-angle --json
Gyroscope fused orientation as JSONL:
gyroscope --axis roll --json
Music-reactive keyboard + speakers:
microphone --rate 44100 \
| tee >(keyboard-brightness --send-hz 30 --fade-ms 20) \
| volume-shift 0.8 \
| speaker
Metronome to speakers:
metronome 120 | speaker
Auto-follow metronome from mic input, emits a metronome tone in sync with the beat of whatever audio is playing:
microphone | metronome | speaker
Auto-follow metronome from accelerometer, driving keyboard pulses:
accelerometer | metronome | keyboard-brightness
Metronome driving keyboard pulses:
metronome 120 | keyboard-brightness
Heartbeat telemetry while still driving keyboard brightness:
accelerometer | heartbeat | keyboard-brightness
Set keyboard backlight to 100% and exit:
keyboard-brightness --set=100
Pulse keyboard 5 times (1.2s on / 5.5s off) at 100%:
keyboard-brightness --pulse=5 --on-time=1.2 --off-time=5.5 --set=100
Set screen brightness to 40% and exit:
screen-brightness --set=40
Pulse screen brightness 3 times:
screen-brightness --pulse=3 --on-time=1.2 --off-time=5.5 --set=100
Metronome driving fan pulses:
metronome 120 | fan-speed --send-hz 4 --alternate --input-map beat --min-frac 0.30 --max-frac 0.70
Slow sine fan sweep (sync L/R):
sine 0.1 | fan-speed
One source, multiple sinks:
accelerometer \
| bandpass 0.8 3 \
| tee >(keyboard-brightness) \
| frequency-shift 1000 \
| volume-shift 0.8 \
| tee >(speaker) \
| visualizer
Notes
accelerometerrequires root (AppleSPU HID access) and will auto-reexec throughsudoby default.ambient-light,lid-angle, andgyroscopedo the same for AppleSPU HID access.- Set
MSIG_AUTO_SUDO=0to disable auto-reexec and only print rerun guidance on stderr. microphone/speakerdepend onsounddevice+ PortAudio runtime.- Keyboard/display brightness tools need supported hardware/permissions.
keyboard-brightnessuses the bundled Apple Silicon KBPulse binary atlib/KBPulse(arm64).fan-speeduses AppleSMC private IOKit APIs on Apple Silicon; writing fan targets typically requiressudo.frequency-shiftis intentionally lightweight and artifact-prone at extreme factors.
Development Setup
git clone https://github.com/pirate/mac-hardware-toys
cd mac-hardware-toys
uv sync
source .venv/bin/activate
Stdio Audio Format
All stream tools read/write:
- header:
MSIG1 <sample_rate_hz>\n - payload: little-endian
float32mono samples
Most processors also support raw float32 input via --raw --rate <hz>.
Why?
It's fun. Here are some ideas to get started:
- make your keyboard lights flash for security alerts using Security Growler
- make your keyboard flash right before your display is about to sleep
- make your keyboard flash on incoming email
- make your keyboard flash to the beat of music
- make your keyboard flash when your boss's iPhone comes within bluetooth range
Related Projects
- https://pirate.github.io/soundview/ (https://github.com/pirate/soundview)
- https://github.com/olvvier/apple-silicon-accelerometer IOReg accelerometer reading code
- https://github.com/EthanRDoesMC/KBPulse/ keyboard brightness code for M1, M2, M3, etc. macs
- https://github.com/vlasvlasvlas/spank
- https://github.com/maxmouchet/LightKit
- https://github.com/tcr/macbook-brightness
- http://stackoverflow.com/questions/3239749/programmatically-change-mac-display-brightness
- https://web.archive.org/web/20110828210316/http://mattdanger.net:80/2008/12/adjust-mac-os-x-display-brightness-from-the-terminal/
- http://osxbook.com/book/bonus/chapter10/light/
- https://github.com/samnung/maclight/blob/master/lights_handle.cpp
- http://www.keindesign.de/stefan/Web/Sites/iWeb/Site/iSpazz.html the OG
- https://github.com/bhoeting/DiscoKeyboard