ondotori-ble
Unofficial software. This project is independent of T&D Corporation.
ondotori-ble is a typed Python library for receiving selected current-value
advertisements from T&D Ondotori data loggers over Bluetooth Low Energy (BLE).
It does not pair with a logger, change settings, download recorded history, or
provide a command-line interface.
from ondotori_ble import read_all
for reading in read_all(duration=75):
print(reading.serial_number, reading.product_name, reading.measurements)
Support boundary
The package keeps unknown T&D packets observable, but it only converts a value when the layout and conversion have adequate evidence.
| Device or family | Status | Evidence |
|---|---|---|
| TR41, TR42, TR45 | Temperature decoded | T&D public example |
| TR41A | Temperature decoded | T&D public example |
| TR42A | Temperature decoded; hardware verified | T&D public example and live scan |
| TR43A, TR32B | Temperature and humidity decoded | T&D public example |
| RTR505B temperature mode | Temperature decoded; K hardware verified | Labelled hardware and live scan |
| Other RTR505B measurement modes | Product identified; raw packet retained | Module-labelled captures required |
| RTR501B/502B/503B/507B measurement modes | Not decoded | More evidence required |
| TR-7wb, TR7A, TR7A2 and related BLE layouts | Not decoded | More evidence required |
| TR-55i | Shared input modules, but no BLE transport | T&D product manual |
Legacy RTR units without B |
Out of scope | Not a BLE transport |
This release does not claim support for every T&D Bluetooth model or mode. See the protocol documentation for the exact evidence boundary.
Install
Python 3.11 or newer is required:
uv add ondotori-ble
Read without knowing a serial number
read() returns the first T&D advertisement observed before its deadline:
from ondotori_ble import read
reading = read(timeout=75)
if reading.is_decoded:
print(reading.temperature_c, reading.humidity_percent)
else:
print(f"Raw family {reading.family_code:02X}: {reading.raw_data.hex()}")
Use read("5F440123") when the eight-digit serial is known. The serial in this
example is synthetic.
Read every observed logger
from ondotori_ble import read_all
readings = read_all(duration=75)
The function waits for the complete collection window and returns the newest
packet from every serial observed in that interval, sorted by serial. BLE
discovery is probabilistic: no finite duration can guarantee that every nearby
device was received. Use decoded_only=True to exclude raw-only packets.
Async and server use
Async applications have matching read_async(), read_all_async(), and
scan_async() functions:
import asyncio
from ondotori_ble import read_all_async
async def main() -> None:
for reading in await read_all_async(duration=75):
print(reading.serial_number, reading.product_name, reading.measurements)
asyncio.run(main())
A long-running service can use the managed stream:
from ondotori_ble import stream_readings
async for reading in stream_readings(deduplicate=False):
await repository.store(reading.as_dict())
deduplicate=False emits every received advertisement. With the default
True, only payload changes are emitted per serial. Storage should still use
an application-defined idempotency policy because BLE does not guarantee
exactly-once delivery.
Advanced applications can manage lifecycle and inspect health directly:
from ondotori_ble import OndotoriScanner
async with OndotoriScanner() as scanner:
async for reading in scanner:
print(reading.as_dict())
print(scanner.state, scanner.stats, scanner.last_error)
Decode an existing packet
The pure decoder does not require Bluetooth hardware:
from ondotori_ble import decode_advertisement
reading = decode_advertisement(
bytes.fromhex("2301445f00000000d2041f06000000000000")
)
assert reading.temperature_c == 23.4
assert reading.humidity_percent == 56.7
Bleak separates T&D's company identifier (0x0392) from its payload. Set
company_id_included=True only when input still begins with little-endian
92 03.
reading.product_name is the verified product name derived from the T&D
manufacturer payload, such as TR42A. reading.name is the local or cached BLE
name reported by the operating system and may be missing or less specific.
Development
uv sync --all-groups
lefthook install
uv run ruff check .
uv run ruff format --check .
uv run ty check
uv run pytest
uv run --group docs mkdocs build --strict
uv build --no-sources
The full documentation is at ameyanagi.github.io/ondotori-ble. Ondotori, T&D, and related product names are trademarks of their respective owner.
Metadata
Release files for ondotori-ble 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ondotori_ble-0.1.0.tar.gz | 23.7 kB | Without provenance | Details for ondotori_ble-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ondotori_ble-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for ondotori_ble-0.1.0-py3-none-any.whl |
Total release size: 40.7 kB
Release files / ondotori_ble-0.1.0.tar.gz
| Download URL | ondotori_ble-0.1.0.tar.gz |
|---|---|
| Size | 23.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
78a4859d51765ab6b14f7917afcb7b1e37d0b72d7f0a47b5e028445c7fef1a4d
|
|
BLAKE2b-256 checksum How to use checksums |
11755e8c597c5d18d065a2d52b9f06db7a9ee3459fd769d3f31d7b2f1f01d4ef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / ondotori_ble-0.1.0-py3-none-any.whl
| Download URL | ondotori_ble-0.1.0-py3-none-any.whl |
|---|---|
| Size | 17.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
be175472afe7164291e68e24738457da2e2ea29469ca7581e2f12553f9099f31
|
|
BLAKE2b-256 checksum How to use checksums |
754afc790da7744b4c7328dd080ca0bf86ff4a8936219b5f5df81cc9ac2ab2e5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for ondotori-ble 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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.