Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

radex

Unofficial Python driver for the Radex Obsidian radiation dosimeter Неофициальный Python-драйвер для дозиметра Radex Obsidian

Python License: MIT pyserial tests

English · Русский


Reverse-engineered USB/serial driver for the Radex Obsidian (QUARTA-RAD) dosimeter: a clean SDK, a live metrics streamer, and — because the sensor is a source of genuine quantum noise — a random number generator seeded from radioactive decay.

The protocol was reverse-engineered from a live device; the full write-up is in docs/reverse-engineering/protocol-notes.md.

Features

Live metrics Dose rate, CPS, beta, accumulated dose, temperature, battery, device clock
Streaming Console streamer with CSV / JSONL logging
Device info Manufacturer, model, serial number, firmware version
Hardware RNG RNG seeded from decay noise, with SP 800-90B entropy accounting
Pure Python Only dependency is pyserial; cross-platform
Auto-detect Finds the COM port by USB VID/PID — no configuration

Supported devices

Device USB VID:PID Status
Radex Obsidian ABBA:A006 ✅ tested on hardware
Radex Obsidian G Pro ABBA:A008 ⚙️ autodetected, untested
Radex Obsidian 2 ABBA:A00A ⚙️ autodetected, untested

The device shows up as a Silicon Labs CP210x virtual COM port (115200 8N1). The same frame protocol is also tunneled over BLE by the vendor apps, so a BLE transport can be added behind the same interface.

Install

pip install -e .

CLI

python -m radex                                  # live stream, port auto-detected
python -m radex stream --once                    # one sample and exit
python -m radex stream --csv log.csv --jsonl log.jsonl --interval 2
python -m radex stream --port COM3

Example output:

# QUARTA-RAD Obsidian sn=04250001002186 fw=v1.21
2026-08-20T16:08:46  DER 0.1260 +-0.0116 uSv/h  CPS  11.912  dose 235.1463 uSv  T 26.4C  bat 100%

SDK

from radex import RadexObsidian

with RadexObsidian.open() as dev:            # auto-detects the COM port
    print(dev.device_info())                 # manufacturer, model, serial, firmware
    m = dev.read_metrics()
    print(m.der, "uSv/h", m.cps, "cps", m.temperature_c, "C")

    for m in dev.stream(interval=1.0):       # forever
        ...

read_spectrum() is declared but not implemented yet — the gamma-spectrum readout command hasn't been found in the protocol.

Hardware RNG

The scintillator counts radioactive decays, and the number of decays per measurement cycle is fundamentally unpredictable — real quantum entropy. radex.entropy turns that into random bytes:

python -m radex rng --bytes 32 --true            # blocks until entropy is collected
python -m radex rng --bytes 1024                 # fast: HMAC-DRBG after a one-time seed
from radex import RadexRNG

with RadexRNG.open() as rng:
    seed = rng.true_random_bytes(32)             # pure quantum entropy (slow)
    bulk = rng.random_bytes(10**6)               # fast CSPRNG, continuously reseeded

How the accounting works. The firmware reports processed aggregates once per second; per cycle the device sees a Poisson-distributed count of decays (~12 cps at background). Entropy is estimated with the MCV min-entropy estimator (NIST SP 800-90B, 99% confidence) over the round(cps_instant) stream — taking the smaller of the measured and modelled value so it never over-credits (~1.8 bit/sample on hardware). Continuous RCT + APT health tests gate the credit; it stalls if the register freezes or CPS leaves a sane range. The whole raw register goes into a SHA-256 pool, but only the physics is credited (× 0.5 margin, capped at 256 bits).

Not a certified TRNG. The firmware sits between the sensor and us and only exposes 1 Hz aggregates, not the raw noise. Good as a seed source; not a per-pulse, auditable entropy source.

Tests

python -m pytest                                 # no hardware (uses captured frames)
RADEX_DEVICE=1 python -m pytest tests/test_hardware.py -v   # with the device plugged in

Disclaimer

Unofficial project, not affiliated with or endorsed by QUARTA-RAD. Do not use it for radiation-safety decisions.


Русский

Реверс-инжинированный USB/serial-драйвер для дозиметра Radex Obsidian (QUARTA-RAD): аккуратный SDK, консольный стример измерений и — поскольку сенсор ловит настоящий квантовый шум — генератор случайных чисел на радиоактивном распаде.

Протокол разобран по живому прибору; полный разбор — в docs/reverse-engineering/protocol-notes.md.

Возможности

Живые метрики Мощность дозы, CPS, бета, накопленная доза, температура, батарея, часы прибора
Стриминг Консольный стример с записью в CSV / JSONL
Паспорт прибора Производитель, модель, серийный номер, версия прошивки
Аппаратный ГСЧ Генератор на шуме распада с учётом энтропии по SP 800-90B
Чистый Python Единственная зависимость — pyserial; кроссплатформенно
Автоопределение Находит COM-порт по USB VID/PID — без настройки

Поддерживаемые приборы

Прибор USB VID:PID Статус
Radex Obsidian ABBA:A006 ✅ проверено на железе
Radex Obsidian G Pro ABBA:A008 ⚙️ автоопределяется, не тестировался
Radex Obsidian 2 ABBA:A00A ⚙️ автоопределяется, не тестировался

Прибор виден как виртуальный COM-порт Silicon Labs CP210x (115200 8N1). Тот же кадровый протокол вендорские приложения туннелируют и по BLE, так что BLE-транспорт можно добавить за тем же интерфейсом.

Установка

pip install -e .

CLI

python -m radex                                  # живой стрим, порт ищется сам
python -m radex stream --once                    # одно измерение и выход
python -m radex stream --csv log.csv --jsonl log.jsonl --interval 2
python -m radex stream --port COM3

Пример вывода:

# QUARTA-RAD Obsidian sn=04250001002186 fw=v1.21
2026-08-20T16:08:46  DER 0.1260 +-0.0116 uSv/h  CPS  11.912  dose 235.1463 uSv  T 26.4C  bat 100%

SDK

from radex import RadexObsidian

with RadexObsidian.open() as dev:            # порт определяется автоматически
    print(dev.device_info())                 # производитель, модель, серийник, прошивка
    m = dev.read_metrics()
    print(m.der, "uSv/h", m.cps, "cps", m.temperature_c, "C")

    for m in dev.stream(interval=1.0):       # бесконечно
        ...

read_spectrum() объявлен, но пока не реализован — команда выгрузки гамма-спектра в протоколе ещё не найдена.

Аппаратный ГСЧ

Сцинтиллятор считает распады, и число распадов за цикл измерения принципиально непредсказуемо — это настоящая квантовая энтропия. Модуль radex.entropy превращает её в случайные байты:

python -m radex rng --bytes 32 --true            # блокируется, пока не наберётся энтропия
python -m radex rng --bytes 1024                 # fast: HMAC-DRBG после одноразового сида
from radex import RadexRNG

with RadexRNG.open() as rng:
    seed = rng.true_random_bytes(32)             # чистая квантовая энтропия (медленно)
    bulk = rng.random_bytes(10**6)               # быстрый CSPRNG, непрерывный подсев

Как считается энтропия. Прошивка отдаёт обработанные агрегаты раз в секунду; за цикл прибор видит Пуассоновское число распадов (~12 cps на фоне). Энтропию оцениваем MCV-эстиматором min-энтропии (NIST SP 800-90B, 99% доверие) по потоку round(cps_instant) — берём меньшее из измеренного и модельного значения, чтобы не завысить (~1.8 бита на сэмпл на реальном приборе). Непрерывные health-тесты RCT и APT гейтят зачёт; он стопается, если регистр завис или CPS вне разумного диапазона. Весь сырой регистр идёт в SHA-256-пул, но зачитывается только физика (× 0.5 запаса, кап 256 бит).

Это не сертифицированный TRNG. Между сенсором и нами стоит прошивка, наружу она отдаёт только 1 Гц агрегаты, а не сырой шум. Годится как источник для засева, но не как попульсовый аудируемый источник энтропии.

Тесты

python -m pytest                                 # без железа (на захваченных кадрах)
RADEX_DEVICE=1 python -m pytest tests/test_hardware.py -v   # с подключённым прибором

Дисклеймер

Неофициальный проект, не аффилирован с QUARTA-RAD и не одобрен им. Не использовать для принятия решений о радиационной безопасности.

About

Python SDK for Radex Obsidian

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages