BLE environment-sensor backend for lab-executor-mcp
Project description
lab-ble-mcp
lab-executor-mcp 用の BLE 環境センサ backend です。温湿度・気圧・CO2 などを実験記録の一部として取得します。
対応機種
| profile | 機器 | 取得できる測定量 | 経路 |
|---|---|---|---|
omron_2jcie |
OMRON 2JCIE-BU01 | 温度・湿度・照度・気圧・騒音・eTVOC・eCO2 | advertisement / GATT |
switchbot_meter |
SwitchBot Meter | 温度・湿度・電池残量 | advertisement のみ |
どちらの profile も実機で検証済みです(2026-07-20)。同梱の mock backend は、そのとき実機から採取したペイロードをそのまま再生します。テストは手書きの例ではなく、装置が実際に送出したバイト列を復号して検証しています。
使い方
python -m pip install -e ".[dev]"
pytest -q
lab-ble profiles
lab-ble serve --resource "BLE::omron_2jcie/D0:ED:3E:53:EE:22" --dry-run
- resource:
BLE::<profile>/<ADDRESS>- profile は小文字の slug、address は大文字コロン区切り。正規形は1つだけで、小文字アドレスは黙って変換せず拒否します。
- profile を resource 名に含めるのは、BLE のペイロードが自己記述的でないためです。復号器はバイトを解釈する前に確定している必要があり、設定ミスで別ベンダのフィールド地図を当ててしまう事故を防ぎます。
- query:
READ <測定量>/INFO <項目> - write: ありません(後述)
lab-ble serve --resource "BLE::switchbot_meter/D6:DF:02:E9:08:48"
Python library
from lab_ble_mcp import BleBackend
backend = BleBackend(resources=["BLE::omron_2jcie/D0:ED:3E:53:EE:22"])
value = await backend.query("BLE::omron_2jcie/D0:ED:3E:53:EE:22", "READ temperature")
lab-executor backend discovery
インストール時に entry point lab_executor.backends: ble が登録されます。lab-executor serve --backends ble または _system.yaml の backends: から選択できます。
安全設計
この backend は書き込みを一切行いません。 コマンド文法に write の opcode が存在しないため、実行時の許可リストに頼らず、文法上writeを表現できません。
これは理屈ではなく実機の観察に基づく判断です。OMRON 2JCIE-BU01 は閾値設定用の書き込み可能な characteristic に加えて、Nordic buttonless DFU characteristic (8ec90003-f315-4f60-9fb8-838830daea50) を公開しています。ここへ誤って書き込むと装置が使用不能になり得ます。測定用 backend がそこへ到達する理由はありません。
その他の原則:
- 未知の resource、未知の opcode、profile が公開していない測定量、長さの足りないペイロードは、推測せず fail-closed で拒否します。
- 読み取りは profile が両経路を持つ場合 advertisement を優先します。ブロードキャストは接続枠を消費しないため、ポーリングがスマートフォンアプリや他ホストを締め出しません。書き込み可能な characteristic へ接続すること自体を避けられます。
support_level: verifiedは、実機から採取したペイロードがその profile で復号できる場合にのみ宣言できます(テストで強制)。
機器ごとの2つの定義ファイル
機器1台につき、役割の異なる YAML を2枚持ちます(ファイル名は同じ)。
| ファイル | 答える問い | 位置づけ |
|---|---|---|
profiles/<name>.yaml |
バイト列をどう物理量へ復号するか | BLE 固有。SCPI は文字列を返すので VISA には無い層 |
builtin_instruments/<name>.yaml |
名前付きコマンドは何があるか、単位・説明 | lab-executor エコシステム共通。list_commands / execute_named_command の情報源 |
機器定義の scpi にはこの backend のワイヤ言語(READ temperature 等)を書きます。SCPI ではありませんが、エコシステムの InstrumentDefinition 形式に揃えることで VISA・Modbus 機器と同じ手順で扱えます。
2つの文書は手書きなので乖離し得ます。そのためテストで、測定量とコマンドが過不足なく一致すること、全 scpi がワイヤ文法で解析できること、state_query の単位が一致すること、support_level が一致することを強制しています。
対応機種を増やす
上記2枚の YAML を追加します。Python の変更が必要になるのは、フィールドが固定幅リトルエンディアンで表現できない場合だけです(SwitchBot の温度は2バイトにまたがるマスク済みニブルなので、codec.CUSTOM_DECODERS に専用の復号器を持ちます)。詳細は ADDING_A_PROFILE.md を参照してください。
制約
- 連続ストリーミングは対象外です。 現行の BEF 契約は
query() -> strに凍結されており、波形や生体信号のような連続データが backend から出ていく経路がありません。BITalino 等のストリーミング機器はこの制約の対象です。 - advertisement の送出間隔は機種差が大きく、待ち時間を要します。
timeout_msは黙って延長せず、その操作の期限としてそのまま使います。実測では 2JCIE-BU01 は数秒間隔で安定して取得できましたが、SwitchBot Meter は不規則で、25000 ms でも取り逃すことがありました。定期取得ではcache_ttl_ms(既定 10000 ms)が1回の受信を複数の測定量へ行き渡らせるため、測定量ごとに待ち直すことはありません。 list_resources()は設定された resource だけを返します。BLE のスキャンは profile を持たない近隣のビーコンまで列挙してしまうためです。
開発と公開
CI は Python 3.11、Ruff、BEF 適合、latest release 統合、lab-executor main 互換 smoke、build を検証します。タグは PyPI、手動 workflow は既定で TestPyPI へ Trusted Publishing で公開します。
ライセンス
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lab_ble_mcp-0.1.0.tar.gz.
File metadata
- Download URL: lab_ble_mcp-0.1.0.tar.gz
- Upload date:
- Size: 30.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
56332e54b13bd719cd772f486bf1ed132cdc17d81f59aee2376b2ad8482e32f5
|
|
| MD5 |
cdfd37dc9a71e226ae5239be04efbae9
|
|
| BLAKE2b-256 |
b2f962cc56bf13a3dd7eb72db5d469c9baadee1d051873f6fecbcef430b7dfc6
|
Provenance
The following attestation bundles were made for lab_ble_mcp-0.1.0.tar.gz:
Publisher:
publish.yml on TECTOS-JP/lab-ble-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lab_ble_mcp-0.1.0.tar.gz -
Subject digest:
56332e54b13bd719cd772f486bf1ed132cdc17d81f59aee2376b2ad8482e32f5 - Sigstore transparency entry: 2210135103
- Sigstore integration time:
-
Permalink:
TECTOS-JP/lab-ble-mcp@f54e5ac73dd94b52fbe92ce54c6c4c8460e12334 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/TECTOS-JP
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f54e5ac73dd94b52fbe92ce54c6c4c8460e12334 -
Trigger Event:
push
-
Statement type:
File details
Details for the file lab_ble_mcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: lab_ble_mcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cdeb375c0a0152c2644eee43406fea7823551c26993fceb80d18547daadbae87
|
|
| MD5 |
cea25ce89e8e89bcb03cc9a5a805bae4
|
|
| BLAKE2b-256 |
ad2f57d455298aeb4652f7352f49337484cce58b9671a85a94f5ee2c6a6f1c84
|
Provenance
The following attestation bundles were made for lab_ble_mcp-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on TECTOS-JP/lab-ble-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lab_ble_mcp-0.1.0-py3-none-any.whl -
Subject digest:
cdeb375c0a0152c2644eee43406fea7823551c26993fceb80d18547daadbae87 - Sigstore transparency entry: 2210135172
- Sigstore integration time:
-
Permalink:
TECTOS-JP/lab-ble-mcp@f54e5ac73dd94b52fbe92ce54c6c4c8460e12334 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/TECTOS-JP
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f54e5ac73dd94b52fbe92ce54c6c4c8460e12334 -
Trigger Event:
push
-
Statement type: