Skip to content

Instantly share code, notes, and snippets.

@lynaghk
Last active August 5, 2025 00:30
Show Gist options
  • Save lynaghk/e549eb86d59dac59e68ce7389a87a971 to your computer and use it in GitHub Desktop.
Save lynaghk/e549eb86d59dac59e68ce7389a87a971 to your computer and use it in GitHub Desktop.
control macos brightness of monitor(s) via MIDI input
#!/usr/bin/env python3
# launch with `uv run`. https://docs.astral.sh/uv/
# uses https://github.com/waydabber/betterdisplay/ to control the monitors
# /// script
# dependencies = [
# "python-rtmidi==1.5.8",
# "requests==2.32.4",
# ]
# ///
import requests
import rtmidi
import subprocess
import sys
import time
from contextlib import contextmanager
@contextmanager
def timer(label):
start = time.perf_counter()
try:
yield
finally:
print(f"{label} took {time.perf_counter() - start:.4f} seconds")
# MIDI CC to display mapping (adjust these for your setup)
CC_TO_DISPLAY = {
# vertical monitor is ID = 3
72: 3,
76: 3,
# top
73: 1,
# bottom
77: 2,
}
def set_brightness(display, brightness):
# curl -X GET -G http://localhost:55777/set -d "brightness=80%" -d "displayID=1"
requests.get("http://localhost:55777/set",
params={"displayID": display,
"brightness": brightness})
def midi_callback(message, data):
msg, deltatime = message
# print(msg)
if len(msg) == 3 and msg[0] == 0xB0: # Control Change on channel 1
cc_number = msg[1]
cc_value = msg[2]
if cc_number in CC_TO_DISPLAY:
display = CC_TO_DISPLAY[cc_number]
brightness = cc_value / 127
set_brightness(display, brightness)
# print(f"CC {cc_number} → Display {display}: {brightness}")
def main():
midi_in = rtmidi.MidiIn()
# Find LPD8 port
ports = midi_in.get_ports()
lpd8_port = None
for i, port in enumerate(ports):
if "LPD8" in port or "Akai" in port:
lpd8_port = i
break
if lpd8_port is None:
print("LPD8 not found. Available ports:")
for i, port in enumerate(ports):
print(f" {i}: {port}")
sys.exit(1)
print(f"Connecting to: {ports[lpd8_port]}")
midi_in.open_port(lpd8_port)
midi_in.set_callback(midi_callback)
print("MIDI brightness control running... Press Ctrl+C to stop")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nShutting down...")
finally:
midi_in.close_port()
if __name__ == "__main__":
main()
# Tried to have this auto start but couldn't get it working in 20 minutes, so I just launch it myself in a terminal window like an animal ¯\_(ツ)_/¯
# PLISTPATH=~/Library/LaunchAgents/com.keminglabs.midi-brightness.plist
# cat << 'EOF' > $PLISTPATH
# <?xml version="1.0" encoding="UTF-8"?>
# <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
# <plist version="1.0">
# <dict>
# <key>Label</key>
# <string>com.keminglabs.midi-brightness</string>
# <key>ProgramArguments</key>
# <array>
# <string>/Users/dev/.dotfiles/uv_shim</string>
# <string>run</string>
# <string>/Users/dev/.dotfiles/bin/midi-brightness.py</string>
# </array>
# <key>RunAtLoad</key>
# <true/>
# <key>KeepAlive</key>
# <true/>
# <key>StandardOutPath</key>
# <string>/Users/dev/Library/Logs/midi-brightness.log</string>
# <key>StandardErrorPath</key>
# <string>/Users/dev/Library/Logs/midi-brightness.log</string>
# </dict>
# </plist>
# EOF
# launchctl load -w $PLISTPATH
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment