Skip to main content

openble-lifesense

The Lifesense A2/A3 Bluetooth weight-scale protocol, as spoken by the Philips DL8780 and other scales built on the Lifesense SDK.

  • openble.lifesense.packets: parsers for the weight (8A21, 8A24) and body-composition (8A22) packets.
  • openble.lifesense.link: the 8A81 command frames, and the pair and sync handshake that makes the scale send a weigh.
  • openble.lifesense.identify: matches advertisements and GATT tables to a scale.
  • openble.lifesense.uuids: service and characteristic ids.

Pure Python 3.11+ with no dependencies and no Bluetooth stack. The handshake takes a write coroutine and a queue of indications, so it runs over bleak, a test double, or anything else.

pip install openble-lifesense

Parse a weigh

from openble.lifesense.packets import parse_a3_append, parse_a3_weight

weight = parse_a3_weight(
    bytes.fromhex("1f 16 26 00 fe 89 50 91 1f 00 00 00 00 17 13 00 ff 01 19 00")
)
weight["weight_kg"], weight["impedance"], weight["date"]
# ('97.5', '488.7', '2026-10-13 19:50:33')

append = parse_a3_append(
    bytes.fromhex("6d 89 50 91 1f 01 fc f0 32 f2 79 f1 26 f0 00 00 00 00 00 00")
)
append["body_fat_ratio"]
# '25.2'

parse_scale_notification(short, data, family=..., previous=...) picks the parser the Lifesense dispatcher would use for a characteristic. identify.protocol_digit(service_uuids) gives the family.

Pair and sync with bleak

The scale sends a 0xA0 password when it is in pairing mode (hold the unit button for 3 s) and a 0xA1 random when it is already paired. run_scale_handshake answers either one. It stores the password and broadcast id in a ScaleStore JSON file, and it needs that same file for every later sync.

import asyncio
from pathlib import Path

from bleak import BleakClient
from openble.lifesense.link import ScaleStore, run_scale_handshake
from openble.lifesense.packets import parse_a3_weight
from openble.lifesense.uuids import sig


async def weigh(address: str) -> None:
    commands: asyncio.Queue[bytes] = asyncio.Queue()
    async with BleakClient(address) as client:
        await client.start_notify(
            sig("8a24"), lambda _, data: print(parse_a3_weight(bytes(data)))
        )
        await client.start_notify(
            sig("8a82"), lambda _, data: commands.put_nowait(bytes(data))
        )

        async def write(payload: bytes) -> None:
            await client.write_gatt_char(sig("8a81"), payload, response=True)

        await run_scale_handshake(
            write=write,
            queue=commands,
            store=ScaleStore(Path("scale.json")),
            device_key=address,
            user_number=1,
            user_name="User",
            password_override=None,
            listen_seconds=60,
            log=lambda kind, **payload: print(payload.get("message", "")),
        )

apps/ble-probe and apps/bathroom-hub in the repository are complete clients built this way.

Protocol notes

Not affiliated with Philips or Lifesense. The names identify the devices this interoperates with.

License

MIT License, copyright 2026 Kadima Tech.

Metadata

Release files for openble-lifesense 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for openble-lifesense 0.1.0
File Size Uploaded Provenance
openble_lifesense-0.1.0.tar.gz 38.7 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for openble-lifesense 0.1.0
File Interpreter ABI Platform
openble_lifesense-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 54.7 kB

Release files / openble_lifesense-0.1.0.tar.gz

Download URL openble_lifesense-0.1.0.tar.gz
Size 38.7 kB
Tags Source
SHA-256 checksum
How to use checksums
9c2771cf1664ed20a6e996c961842d958995e327724fd4c02bbad28751a7f73b
BLAKE2b-256 checksum
How to use checksums
cb0de836a9fe56a5ec40619a71f8d0c90e2428da83aac8eab44643ffc92ebf1a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / openble_lifesense-0.1.0-py3-none-any.whl

Download URL openble_lifesense-0.1.0-py3-none-any.whl
Size 16.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d8750fb4fba1bbeeb1a591eb1cecd0fe6a1d8775e6b351d874e1b9209afb588c
BLAKE2b-256 checksum
How to use checksums
a99329428a20fbb7873c1c3fe432fd7b9940a3dabb2235cb665e5439f5b8a1bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Security for openble-lifesense 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for openble_lifesense-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page