Bygga
Type the product name from the box. Bygga shows every assembly step in 3D, with the parts, screws and tools for each one, and reads it out loud.
翻译准备中
Report your Mac to Home Assistant over MQTT: a native macOS menu bar app with Now Playing, media controls and MQTT discovery
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗faintghost.github.io/mac2mqtt · English | 简体中文
A native macOS menu bar app that brings your Mac into Home Assistant over MQTT: its network, power, screen and display, camera and microphone, sound and what it is playing, with controls for playback, volume, the screen and the display, notifications, speech and Shortcuts. Home Assistant creates the device and its entities by itself through MQTT discovery.
Built with MyGo: native UI drawn by the app itself, Liquid Glass included, in a single small binary with no webview.
media_player, so Mac2MQTT publishes one for the
MQTT Media Player
integration, and generates a universal media player for those without
HACS.With Homebrew:
brew install --cask faintghost/tap/mac2mqtt
Or from Terminal, which checks the download's signature:
curl -fsSL https://github.com/FaintGhost/mac2mqtt/releases/latest/download/install.sh | sh
Or download a disk image from the latest release:
| File | For |
|---|---|
Mac2MQTT-<version>-universal.dmg | Any Mac |
Mac2MQTT-<version>-arm64.dmg | Apple silicon (M1 and later) |
Mac2MQTT-<version>-amd64.dmg | Intel |
Open it and drag Mac2MQTT to Applications. Requires macOS 13 or later.
Mac2MQTT is signed with a Developer ID and notarized by Apple, so it opens like any app. The first time it connects to a broker on your local network, macOS asks whether to allow it: choose Allow. If you declined, allow it in System Settings → Privacy & Security → Local Network; the app says so when that is why it cannot connect.
homeassistant).Mac2MQTT updates itself from these releases: it checks in the background and offers new versions with their notes, or installs them by itself if you let it in Settings → Updates; Check for Updates… is in the menus. Versions before 0.3.0 cannot update themselves: install 0.3.0 once by hand.
Turn on Open at Login in Settings to keep reporting after a restart. If macOS asks, allow Mac2MQTT in System Settings → General → Login Items.
Each group can be turned off in Entities; its entities then leave Home Assistant.
| Group | Entities |
|---|---|
| Network | Network Connectivity (binary sensor) |
| Power | Power Source; Battery and Charging on laptops |
| Screen and Session | Screen Lock (Locked or Unlocked), Display (binary sensors), Idle Time; Lock Screen, Sleep Display, Wake Display and Sleep buttons |
| Camera and Microphone | Camera In Use, Microphone In Use (binary sensors) |
| Sound | Volume (number), Mute (switch) |
| Now Playing | Media State, Now Playing (title, with artist, album, app and timing as attributes), Play/Pause, Next Track and Previous Track buttons, Media player |
| Notifications and Speech | Notification, Speak (notify) |
| Shortcuts (off by default) | Run Shortcut (select of your shortcuts) |
| Diagnostics | Last Update, Uptime, App Uptime, App Version, Hostname |
A Refresh button, which publishes the state at once, is always there.
Pick one:
configuration.yaml and restart Home Assistant. It uses the
built-in universal media player.
The YAML names the entities as Home Assistant does by default, such as
sensor.mac_mini_now_playing: adjust them if you renamed yours.With the default base topic mac2mqtt/<device>:
| Topic | Direction | Payload |
|---|---|---|
<base>/state | Mac → broker | The state document (JSON, below) |
<base>/availability | Mac → broker | online / offline, retained, last will |
<base>/media/state | Mac → broker | playing, paused or idle |
<base>/media/attributes | Mac → broker | Now Playing as JSON |
<base>/media/{title,artist,album,duration,position,volume,mute,mediatype} | Mac → broker | One field each, for the media player |
<base>/volume/set | HA → Mac | 0 to 100 |
<base>/mute/set | HA → Mac | ON / OFF |
<base>/media/command | HA → Mac | PLAY, PAUSE, PLAY_PAUSE, STOP, NEXT, PREVIOUS |
<base>/media/seek | HA → Mac | Seconds from the start |
<base>/media/volume/set | HA → Mac | 0 to 1 |
<base>/media/mute/set | HA → Mac | mute / unmute |
<base>/system/command | HA → Mac | LOCK, DISPLAY_SLEEP, DISPLAY_WAKE, SLEEP |
<base>/notify | HA → Mac | Text, or {"title": "…", "message": "…"} |
<base>/say | HA → Mac | Text to speak |
<base>/shortcut/run | HA → Mac | A shortcut's name, or {"name": "…", "input": "…"} |
<base>/refresh | HA → Mac | Anything: publish the state now |
Commands are taken only on the topics of groups that are on.
Discovery documents go to <prefix>/<component>/<node-id>/<object-id>/config.
{
"last_seen": "2026-10-25T16:20:00+08:00",
"app": { "version": "0.1.0", "uptime_seconds": 42 },
"device": {
"hostname": "mac-mini.local",
"os_version": "27.0.1",
"arch": "arm64",
"model": "Mac mini",
"model_id": "Mac16,10",
"uptime_seconds": 273600
},
"network": { "online": true, "metered": false },
"power": { "on_battery": false, "source": "AC" },
"session": { "locked": false, "idle_seconds": 12 },
"activity": { "camera_in_use": false, "microphone_in_use": true },
"display": { "awake": true },
"audio": { "volume": 35, "muted": false },
"media": {
"state": "playing",
"title": "Come Away With Me",
"artist": "Norah Jones",
"app_name": "Music",
"duration_seconds": 198,
"position_seconds": 42.5,
"playback_rate": 1
}
}
# An on-air light while the Mac is in a call
automation:
- alias: On air
triggers:
- trigger: state
entity_id: binary_sensor.mac_mini_microphone_in_use
actions:
- action: "light.turn_{{ 'on' if trigger.to_state.state == 'on' else 'off' }}"
target: { entity_id: light.door_sign }
# Lock the Mac when everyone leaves
- alias: Lock the Mac
triggers:
- trigger: state
entity_id: zone.home
to: "0"
actions:
- action: button.press
target: { entity_id: button.mac_mini_lock_screen }
# Tell the Mac when the laundry is done
- alias: Laundry done
triggers:
- trigger: state
entity_id: sensor.washer_status
to: done
actions:
- action: notify.send_message
target: { entity_id: notify.mac_mini_speak }
data: { message: The laundry is done }
Settings live in ~/Library/Application Support/Mac2MQTT/config.json, with
owner-only permissions. The broker password is stored there in plain text:
give Mac2MQTT a broker user of its own, limited to its topics.
| Setting | Meaning |
|---|---|
| Reporting | Connects and publishes while on |
| Host, Port, TLS | The broker; TLS usually on port 8883, verified with the system's trust store |
| Username, Password | Optional broker credentials |
| Discovery prefix | Usually homeassistant |
| Base topic | Root of the state and command topics |
| Device name | The device's name in Home Assistant |
| Interval | Seconds between reports, 5 to 3600 |
| Client ID | MQTT client and Home Assistant node ID (Advanced) |
| Retain state | Keeps the last state on the broker (Advanced) |
osascript, signed by Apple, with a short
JavaScript for Automation script, for reading and for commands alike.ioreg) and
kept current by lock and unlock notifications.main.go, app.go, ui_*.go the window, the menu bar and the settings (MyGo native UI)
internal/config the configuration, validated and saved atomically
internal/broker the MQTT client (paho) behind a small interface
internal/homeassistant the discovery documents and the universal media player
internal/service connecting, discovery, publishing and commands
internal/system what the Mac reports, and its controls
locales/ the catalogs (en, zh-Hans, zh-Hant) and their accessors
Requires Go 1.27.3 or later, on macOS.
go test ./... # unit tests: fake broker and commands, no real audio or media
go tool mygo dev # run with live reload
go tool mygo build # build/darwin-arm64/Mac2MQTT.app and a DMG
go tool mygo vet . # MyGo's checks
go tool mygo i18n check # the catalogs
After editing locales/*.json, run go tool mygo generate to update the
accessors. MAC2MQTT_SNAPSHOTS=<dir> go test -run TestSnapshots . renders
every page, light and dark, to PNGs.
Set version in mygo.json, commit, and push a matching tag:
git tag v0.2.0 && git push origin v0.2.0
Add the version's section to CHANGELOG.md first: it is the release's notes,
which the update window shows.
The release workflow checks that the tag and mygo.json agree, builds the
arm64, amd64 and universal disk images, signs the updates, and publishes
them with their SHA-256 checksums. With the MACOS_CERTIFICATE, MACOS_CERTIFICATE_PASSWORD
and NOTARY_KEY, NOTARY_KEY_ID, NOTARY_ISSUER_ID secrets (a Developer ID
Application certificate and an App Store Connect API key), it signs the app
with the Developer ID and has Apple notarize it. Updates are signed with the secret key
that go tool mygo keygen made, kept in the repository's
MYGO_UPDATER_PRIVATE_KEY secret; installed apps check them against the
public key in mygo.json. Losing the secret key strands installed apps on
their version: keep a copy in a password manager.
osascript cannot call.Mac2MQTT stands on the work of others: