Observed since 20 Oct, 17:51 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Python library for interacting with the Acaia Lunar coffee scale over Bluetooth Low Energy (BLE)
Python library for interacting with the Acaia Lunar coffee scale over Bluetooth Low Energy (BLE).
Built for specialty coffee enthusiasts who want to programmatically read weight data from their Acaia Lunar scale. Uses the bleak library for cross-platform BLE support (macOS, Linux, Windows).
Note: This library is specifically built for the Acaia Lunar model only — it does not support other Acaia scales (Acaia Pearl, Pyxis, etc.). It has been tested with the Lunar 2021 (Model AL008). Models AL009 and AL010 should work as well since they share the same BLE protocol, but have not been tested.

pip install acaia-lunar-ble
import asyncio
from acaia_lunar_ble import ScaleConnection
def on_weight(weight: float):
print(f"Weight: {weight:.2f} g")
async def main():
scale = ScaleConnection("YOUR-SCALE-ADDRESS", weight_callback=on_weight)
if not await scale.connect():
print("Failed to connect")
return
await asyncio.sleep(30) # read weights for 30 seconds
await scale.disconnect()
asyncio.run(main())
If you don't know your scale's BLE address, use the built-in discovery:
import asyncio
from acaia_lunar_ble import ScaleConnection
async def main():
acaia_devices, all_devices = await ScaleConnection.discover()
for d in acaia_devices:
print(f"{d.name}: {d.address}")
if not acaia_devices:
print("No Acaia scales found. All nearby BLE devices:")
for d in all_devices:
print(f" {d.name or '(unknown)'}: {d.address}")
asyncio.run(main())
An interactive example script is included in examples/demo.py:
python examples/demo.py <SCALE-ADDRESS>
Interactive commands during the session:
| Key | Action |
|---|---|
c | Connect to the scale |
d | Disconnect from the scale |
s | Show connection status |
t | Tare (zero the scale) |
1 | Start timer |
2 | Stop timer |
3 | Reset timer |
g | Get settings (battery, units, auto-off, beep) |
r | Toggle raw BLE data stream logging |
h | Show commands |
q | Quit |
Weight and timer readings update in real-time. Type a command letter and press Enter. Press q + Enter to quit, or Ctrl+C.
For automatic cleanup, use async with:
async with ScaleConnection(address, weight_callback=on_weight) as scale:
await asyncio.sleep(60) # stream weights for 60 seconds
# automatically disconnects when exiting the block
ScaleConnection(address, *, ...)Main class for interacting with the scale.
Constructor parameters:
address — BLE address (MAC or UUID) of the scaleweight_callback — called with each weight reading in grams (float)timer_callback — called with timer value in seconds (float)battery_callback — called with battery percentage (int, 0-100)settings_callback — called with a ScaleSettings object (battery, units, auto-off, beep)button_callback — called with button name (str): "tare", "start", "stop", or "reset"notification_callback — called with every raw BLE notification payload (bytearray)| Method | Description |
|---|---|
await connect() | Connect and start data streaming. Returns True on success. |
await disconnect() | Stop streaming and disconnect. |
await scan_until_found() | Block until the scale is found via BLE scan. |
await ScaleConnection.discover(timeout=5.0) | Scan for nearby Acaia scales. Returns (acaia_devices, all_devices). |
await tare() | Zero the scale. |
await start_timer() | Start the scale's built-in timer. |
await stop_timer() | Stop/pause the timer. |
await reset_timer() | Reset the timer to zero. |
await get_settings() | Request settings (response arrives via settings_callback). |
| Property | Type | Description |
|---|---|---|
weight | float | None | Latest weight reading in grams. |
timer | float | None | Latest timer value in seconds. |
settings | ScaleSettings | None | Latest settings from the scale. |
is_connected | bool | Whether the scale is currently connected. |
ScaleSettingsDataclass with fields: battery (int), units (str), auto_off_minutes (int), beep (bool).
decode_weight(data)Standalone function to decode a BLE notification payload into a weight value in grams. Returns None if the data doesn't match the expected format.
The Acaia Lunar uses a proprietary BLE protocol. Communication happens over two GATT characteristics:
49535343-8841-43f4-a8d4-ecbe34729bb3) — used for sending commands (identify, notification request, heartbeat)49535343-1e4d-4bd9-ba61-23c647249616) — streams weight and other data from the scaleThe initialization sequence must follow this exact order:
MIT
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 1.0.1 | 4 Apr 2026 | 1 |
This describes our collected data; it is not a security assessment.
Shared repository data · GitHub
Observed since 20 Oct, 17:51 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:ae331c1a16b1f51f181fa1d34b52477619a8321a654d22b37d1972cebe36a693