STEP 1419 — benchtop-mcp v0.9.1-alpha UART chemistry layer mock (MH-Z19C CO2)

2026-08-27 · STEP 1416 続編 (I2C 化学 → UART 化学) · STEP 1408 excluded_from_v09.uart_co2 candidate 実装 · MH-Z19C mock, 2 tools, hardware_available:False · benchtop-mcp commit 8649034

★ Inbox pattern 第 1 実 example: STEP 番号 = claim-step.ts atomic increment 取得、 memory hook + RECENT_UPDATES row 全 memory/hooks/ + docs/recent-updates-inbox/ 経由 (2026-08-27 protocol 準拠、 rei-aios-56 teammate 通知 対応)。

目的

STEP 1416 v0.9 の I2C 化学 layer 2 SKU (SCD40 CO2 + SGP40 VOC) の 自然な 続編として、 STEP 1408 で 明示された excluded_from_v09.uart_co2 candidate = Winsen MH-Z19C NDIR CO2 (UART 9600 baud) を benchtop-mcp v0.9.1-alpha として 別 module で mock 追加。 STEP 1407 akizuki_wireup pattern + STEP 1416 akizuki_chem pattern を そのまま 継承 (UART protocol 特有の 9-byte packet 合成 部分のみ 追加)。

実装内容

③ CO2 (NDIR UART) — Winsen MH-Z19C mock

2 MCP tool

tool役割主要 return
list_uart_chem_probes() 内蔵 mock UART chem probe registry 一覧 (1 SKU) probes / probe_count=1 / hardware_available:False / uart_baudrate + packet_length_bytes + command_read_co2 / excluded_from_v091 (v0.9.2+/v0.10+ candidate 明示)
measure_co2_uart_ndir(probe_id, condition_tag) MH-Z19C mock (CO2 ppm + 内蔵 温度 + 9-byte packet 合成 + verdict) co2_ppm / temperature_c / packet_hex_9byte / packet_bytes / packet_checksum_valid / status_byte 0x86 / verdict_d8 (TRUE/NEITHER) / is_packet_synthetic:True

Winsen 9-byte packet format

[0xFF] [0x86]     [CO2_H] [CO2_L] [TEMP+40] [0x00] [0x00] [0x00] [CHECKSUM]
 start  response   CO2 ppm 16-bit  temp byte  reserved 3 bytes   Winsen formula
        marker     big-endian

checksum formula (Winsen 独自): 0xFF - ((byte[1] + byte[2] + ... + byte[7]) & 0xFF) + 1

mock 実装は Winsen datasheet 準拠 で 合成、 checksum は formula-valid、 packet byte[2]<<8 | byte[3]co2_ppm と 完全一致 (selftest [6]/[24d] で 自己整合 verify)。

selftest 結果

✅ 全 test PASS — module selftest 7/7 + [24a-24e] MCP tool wire 5/5 + [1-23] regression clean。
--- benchtop_akizuki_uart_chem selftest (v0.9.1-alpha) ---
[1] list_uart_chem_probes: count=1 ids=['mhz19c-co2-uart-e1']
[2] measure_co2_uart_ndir(mhz19c, indoor-typical): co2=2716ppm t=-1.4C packet=FF 86 0A 9C 27 00 00 00 AD verdict=TRUE
[3] checksum formula verify: manual=0xad packet=0xad match=True
[4] measure_co2_uart_ndir determinism: co2_equal=True packet_equal=True
[5] tag-variance: crowded=1872ppm outdoor=3091ppm packet_diff=True
[6] packet CO2 encoding: packet_high_low=3008 co2_ppm=3008 match=True
[7] invalid probe rejected: wrong_registry=True unknown=True

 benchtop_akizuki_uart_chem: all 7 test PASS

--- [24] v0.9.1-alpha: Akizuki UART chemistry layer mock spike (2 MCP tool wire) ---
[24a] list_uart_chem_probes: count=1 hw=False ids=['mhz19c-co2-uart-e1']
[24b] measure_co2_uart_ndir(mhz19c, indoor-typical): co2=2716ppm packet=FF 86 0A 9C 27 00 00 00 AD verdict=TRUE
[24c] measure_co2_uart_ndir determinism: co2+packet equal
[24d] packet encoding self-consistency: packet_high_low=3008 co2_ppm=3008 match=True
[24e] invalid input rejected: wrong_registry=True unknown=True

全テスト成功。実機が無くてもこのサーバーは動作します。

Honest scope (8 条)

  1. hardware 未取得 — 全 return dict で hardware_available: False + is_mock: True + is_packet_synthetic: True marker 徹底。 Winsen MH-Z19C 実機発注は 別 STEP candidate (STEP 1411 pattern 継承)。
  2. mock 値は deterministic — probe_id + condition_tag の hashlib.md5 由来 seed で cross-process 再現可能。 md5 は cryptographic 用途ではない (単純 seed 用途)。
  3. 実 sensor physics 模倣なし — NDIR 4.26μm CO2 吸収線 IR 光量減衰 検出 は 一切 模倣していない = interface skeleton のみ。 3 分 warm-up も 未実装。
  4. CO2 range subset — 400-5000 ppm (datasheet 標準 upper range)、 実 sensor は 0-2000/0-5000/0-10000 ppm から user 選択可能。
  5. 温度 mock 不忠実 — -10-50°C uniform hash 選択、 実 sensor 精度 datasheet ±2°C 表記だが mock は tolerance 未考慮。
  6. packet 合成 = byte-identical だが 実測性ゼロ — Winsen datasheet 準拠 で 9-byte packet 合成、 checksum formula-valid、 packet CO2 encoding self-consistent、 だが 実 UART serial 出力 と は 一致しない (is_packet_synthetic:True marker で 機械判別可能)。
  7. STEP 1350 verdict 2-value subset — TRUE (in-range) / NEITHER (out-of-range or hardware not present) のみ、 BOTH / FALSE / SELF / ∞ / ○ / 〜 の 6 値 は 未使用 (2/8 subset)。
  8. SafetyGate 対象外 — MH-Z19C は 5V UART + 25mA 級 微弱電流 で SafetyGate rule 追加要否 なし。 STEP 1408 で 明示された 可燃性ガス系 (MQ-2/3B/4 = 内蔵ヒーター 5V/150mA + 発火源) は v0.10+ candidate = SafetyGate rule 拡張 と 同時 に 実装予定

v0.9.2+/v0.10+ candidate (excluded_from_v091 field で 明示)

categorySKUbarrier
UART CO2 variant MH-Z14B (Akizuki 116388) v0.9.2 = 同 Winsen protocol / range 違い、 mock 継承 easy
Analog Odor TGS2450 (100989) / AE-TGS8100 (115562) v0.9.2+ = ADC + calibration curve mock
Analog 可燃性 (SafetyGate 拡張) MQ-2 (116141) / MQ-3B (116269) / MQ-4 (116270) v0.10+ = 加熱器 5V/150mA + 発火源 → SafetyGate rule 拡張 + 同時実装
Analog CO2 加熱器 MG812 (116496) v0.10+ = 固体電解質 事前加熱 + 電源設計

Inbox pattern 第 1 実 example

本 STEP は 2026-08-27 導入 の Inbox pattern の 第 1 実 example として dogfood 検証:

  1. npx tsx scripts/claim-step.ts --claim --slug "benchtop-v091-uart-co2-mock" で STEP 1419 取得 (atomic increment、 audit log 記録、 next=1420 に 更新)
  2. memory/hooks/2026-08-27T00-37_step1419_benchtop_v091_uart_co2.md 作成 (MEMORY.md 直接編集 ゼロ)
  3. docs/recent-updates-inbox/2026-08-27T00-37_step1419_benchtop_v091_uart_co2.md 作成 (RECENT_UPDATES.md 直接編集 ゼロ)
  4. git commit 実行 → pre-commit hook が inbox 非空検知 → merger 自動 fire → 2 集約 file 更新 + auto-stage
  5. commit 完了、 push

期待効果 (2026-08-26 3 tab 併走 collision root cause fix): multi-tab collision 構造的 発生不能、 STEP 番号 conflict ゼロ、 直接編集 warn only (bypass 可能で 例外 permit)。

Rei stack alignment

References