Skip to content

rioriost/BirdMenu

Repository files navigation

BirdMenu

BirdMenu is a macOS menu bar app for compatible Bluetooth Low Energy thermometer/hygrometer sensors.

It listens for the device's BLE advertisements and shows the communication state, temperature, and humidity in the menu bar. The detail menu also shows battery level, RSSI, and the last update time.

When multiple compatible sensors are detected, BirdMenu keeps the latest reading for each device. The menu bar shows the average temperature and humidity by default, and the menu lets you switch the display to a specific sensor.

Compatibility testing has been performed with the INKBIRD ITH-11-B sensor. BirdMenu is an independent utility and is not affiliated with or endorsed by INKBIRD.

BirdMenu screenshot

History Fetch

The menu includes Fetch Sensor History. It connects to the selected compatible sensor and tries the history-read command pattern observed from related BLE hygrometers:

  • subscribe to notify characteristics on service 0000fff0-0000-1000-8000-00805f9b34fb
  • write one-byte read commands to 0000fff8-0000-1000-8000-00805f9b34fb
  • never write to the history-delete characteristic 0000fff9-0000-1000-8000-00805f9b34fb

Some tested sensors do not expose fff8; observed devices expose fff3, fff4, fff5, fff6, fff7, and an additional 5833ff01-9b8b-5191-6142-22a4536ef123 service. In that case BirdMenu saves a read-only GATT snapshot: it discovers all services, reads all readable characteristics, subscribes to notify characteristics, and does not write unknown history commands.

Fetched data is saved under ~/Documents/BirdMenu Logs/. The app always writes a raw JSON dump. If the packet layout can be decoded confidently, it also writes history.csv.

Use Settings to generate a graph for a specific local date. BirdMenu scans the saved history.csv files that still exist under ~/Documents/BirdMenu Logs/, combines records for the selected date, and writes history_yyyymmdd.png to the logs folder.

For observed sensors, the companion-app command sequence appears to return records that have not yet been synced rather than the full retained memory every time. In practice this means repeated fetches may produce only the new records since the previous successful sync. Keep the raw JSON files if you need to audit or re-decode the captured BLE packets later.

This feature is intentionally conservative because the offline history protocol is not publicly documented and is not implemented by inkbird-ble.

Debug Logging

Enable Debug Logging from the menu to write received BLE data to macOS Unified Logging. The app logs decoded temperature/humidity/battery/RSSI values, raw advertisement bytes, and history-fetch GATT packets.

View recent logs with:

log show --style compact --last 10m --predicate 'subsystem == "st.rio.birdmenu"'

For live logs:

log stream --style compact --predicate 'subsystem == "st.rio.birdmenu"'

Official App Trace Analysis

The tested sensor's offline history protocol is not exposed through fff8 on observed units. To identify the real sync command, capture an Android Bluetooth HCI snoop log while the companion app syncs offline data, then run:

node Tools/analyze-btsnoop.js /path/to/btsnoop_hci.log
node Tools/analyze-btsnoop.js --summary /path/to/btsnoop_hci.log
node Tools/analyze-btsnoop.js --plan /path/to/btsnoop_hci.log
node Tools/analyze-btsnoop.js --json /path/to/btsnoop_hci.log > trace.json

The tool extracts ATT writes, notifications, and indications, including traffic around fff0 and 5833ff01-9b8b-5191-6142-22a4536ef123. The output is intended to identify the characteristic and command bytes used by the official app for offline history sync.

--plan prints non-CCCD write candidates in the order they appeared, with the response characteristic and sample notification payloads. The JSON output also includes candidateCommandPlan, which is the safest starting point for implementing a replay only after the trace clearly shows the official app's history-sync command.

Typical Android capture flow:

  1. Enable Developer options on the Android phone.
  2. Enable Bluetooth HCI snoop log.
  3. Force stop the companion app, then reopen it.
  4. Connect to the sensor and wait until the app finishes syncing offline data.
  5. Export the bug report or retrieve btsnoop_hci.log from the phone.

The useful lines are usually non-CCCD write_request or write_command entries followed by notification or indication packets within a few seconds.

Apple PacketLogger captures from a real iPhone or iPad can also be passed to the same tool. The analyzer reports PacketLogger metadata, interesting advertisements, and whether ATT connection traffic is present. A capture that only contains LE advertising reports is not enough for offline history implementation; it must include the official app's BLE connection writes and notifications during a history sync.

Build and Run

make run

The app bundle is generated at build/BirdMenu.app.

On first launch, macOS may ask for Bluetooth permission. Allow it so the app can receive BLE advertisements.

BLE Parsing

The advertisement parsing follows the tested sensor behavior documented by inkbird-ble:

  • service UUID: 0000fff0-0000-1000-8000-00805f9b34fb
  • manufacturer id: 9289
  • 18-byte advertisement payload
  • temperature/humidity: bytes [6..<10], little-endian signed temperature and unsigned humidity, both in tenths
  • battery: byte [10]

The app drops impossible humidity values above 100% and battery values above 100%, matching the corruption guards used by inkbird-ble.

Privacy

BirdMenu does not collect, transmit, sell, share, or track personal data. Bluetooth readings and history exports are processed locally on your Mac.

See Privacy Policy (English) and プライバシーポリシー (日本語).

Acknowledgements

The BLE parsing logic is based on the MIT-licensed inkbird-ble project.

The history-fetch command sequence is informed by public reverse-engineering notes for related BLE hygrometers.

License

BirdMenu is released under the MIT License. See LICENSE.

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors