Mock デバイスで開発する(ハードウェア不要)#
🚀 5分クイックスタート#
ハードウェアなしで、すぐに haniwers をテストしたい場合:
# 1. プロジェクトディレクトリへ移動
cd haniwers
# 2. Mock デバイスでデータ取得テスト(5秒で終了)
poetry run haniwers-v1 daq --mock -v
# 3. Mock デバイスで閾値設定テスト(v1.2.0以降)
poetry run haniwers-v1 threshold write --thresholds "1:100" --mock -v
うまくいったら、次は「詳しく学ぶ」セクションに進んでください!
📚 詳しく学ぶ#
Mock デバイスとは?#
実際の OSECHI 検出器がなくても、開発・テストができるようにシミュレートされたデバイスです。
項目 |
説明 |
|---|---|
何ができるのか? |
ハードウェア不要でコマンドをテストできる |
どのコマンドに対応? |
DAQ(データ取得)、Threshold(閾値設定) |
CLI での使い方 |
コマンドに |
Python での使い方 |
|
3 つの Mock デバイスの違い#
┌─────────────────────────────────────────────────────┐
│ 実際のデバイス(Device) │
│ OSECHI 検出器を接続しているときだけ使える │
└─────────────────────────────────────────────────────┘
↑
設定でどちらかを選択
↓
┌─────────────────────────────────────────────────────┐
│ RandomMocker(ランダムデータ) Mocker(CSV再生) │
│ 設定不要、すぐ始められる 過去データを使いたい │
│ 開発・テスト向け CI/CD・再現テスト向け │
└─────────────────────────────────────────────────────┘
🎯 使用例#
例 1: CLI で Mock デバイスを使う(最も簡単)#
# データ取得テスト
poetry run haniwers-v1 daq --mock
# 閾値設定テスト
poetry run haniwers-v1 threshold write --thresholds "1:100;2:120;3:110" --mock
# ポート情報表示(実ハードウェアの確認用)
poetry run haniwers-v1 port list
例 2: Python コードで RandomMocker を使う#
from haniwers.v1.config.model import MockerConfig
from haniwers.v1.daq.mocker import RandomMocker
# 1. Mock デバイス設定
config = MockerConfig(
csv_path=None, # CSV ファイルなし = ランダムデータ
speed=10.0, # 10倍速でシミュレート
jitter=0.01, # 現実的なばらつき
)
# 2. Mock デバイスを作成
mocker = RandomMocker(config, seed=42) # seed=42 で再現可能
# 3. 使用
mocker.connect()
data = mocker.readline() # センサーデータ(7項目)を取得
print(data) # 例: '2 5 8 512 25.43 100550.12 55.67'
mocker.disconnect()
例 3: Python コードで閾値設定テスト(v1.2.0 新機能)#
from haniwers.v1.config.model import MockerConfig
from haniwers.v1.daq.mocker import RandomMocker
from haniwers.v1.threshold.writer import write_threshold
# Mock デバイス初期化
mocker = RandomMocker(MockerConfig())
# 成功ケース:正常に閾値書き込み
success = write_threshold(mocker, ch=1, vth=100)
print(f"書き込み成功: {success}") # → True
# 失敗ケース:デバイスが拒否
mocker.set_next_response("dame") # 拒否レスポンスを設定
success = write_threshold(mocker, ch=1, vth=200)
print(f"書き込み成功: {success}") # → False
🔧 詳細設定#
設定ファイルを使う(Python コード開発向け)#
ファイル: sandbox/config.toml
# Mock デバイス用の最小設定
[device]
port = "/dev/null" # Mock デバイス(ハードウェアなし)
[mocker]
csv_path = null # ランダムデータ生成
speed = 5.0 # 5倍速シミュレート
jitter = 0.01 # 現実的なばらつき
Python コード:
from pathlib import Path
from haniwers.v1.config.loader import ConfigLoader
from haniwers.v1.daq.mocker import RandomMocker
from haniwers.v1.daq.sampler import Sampler
# 設定ファイルから設定を読み込み
loader = ConfigLoader(Path("sandbox/config.toml"))
config = loader.config
# Mock デバイス作成
mocker = RandomMocker(config.mocker)
# データ取得実行
output_dir = Path("sandbox/data")
output_dir.mkdir(parents=True, exist_ok=True)
sampler = Sampler(mocker, config.daq, output_dir)
try:
sampler.acquire_by_count(
file_path=output_dir / "test_data.csv",
event_count=100 # 100イベント取得
)
print("✅ データ取得成功")
finally:
mocker.disconnect()
設定ファイルを使う(再現テスト向け)#
過去に記録した CSV ファイルを再生したい場合:
ファイル: sandbox/config-replay.toml
[device]
port = "/dev/null"
[mocker]
csv_path = "examples/sample_data.csv" # CSV ファイルを指定
shuffle = false # 順序を保持
speed = 1.0 # 実時間速度
❓ よくある質問#
Q: --mock フラグはどのコマンドで使える?#
# ✅ 使える
poetry run haniwers-v1 daq --mock
poetry run haniwers-v1 threshold write --mock
poetry run haniwers-v1 threshold scan --mock
# ❌ 使えない
poetry run haniwers-v1 port list --mock # ハードウェア確認コマンドなので不要
Q: “CSV ファイルが見つからない” というエラーが出た#
# ❌ 間違い:ファイルが存在しないパス
config = MockerConfig(csv_path="data/missing.csv")
# ✅ 正解:存在するパスを指定
config = MockerConfig(csv_path="examples/sample_data.csv")
# または ✅ ランダムデータを使う(推奨)
config = MockerConfig(csv_path=None) # None を指定する
Q: seed パラメータって何?#
# 同じ seed を使うと、毎回同じデータが出力される(再現可能)
mocker1 = RandomMocker(config, seed=42)
mocker2 = RandomMocker(config, seed=42)
# mocker1 と mocker2 は同じデータを生成
# seed を指定しないと、実行のたびに異なるデータが出力される
mocker3 = RandomMocker(config, seed=None) # または seed を省略
Q: 実デバイスと Mock を切り替えるには?#
設定ファイルだけで切り替え可能(コード不要):
# Mock デバイスを使う
[device]
port = "/dev/null"
# 実デバイスに切り替える
[device]
port = "/dev/cu.usbserial-14230"
Python コードは同じ:
from haniwers.v1.daq.device import Device
device = Device(config.device) # 設定に応じて自動選択
Q: Mock でも閾値書き込みテストできる?#
はい!v1.2.0 以降で対応しました:
# CLI での閾値設定テスト
poetry run haniwers-v1 threshold write --thresholds "1:100" --mock
# Python コードでのテスト
from haniwers.v1.threshold.writer import write_threshold
result = write_threshold(mocker, ch=1, vth=100)
print(f"成功: {result}") # → True
Q: RandomMocker と Mocker の使い分けは?#
場面 |
使うもの |
理由 |
|---|---|---|
ローカルで開発中 |
RandomMocker |
CSV ファイル不要、すぐ始められる |
過去データで検証 |
Mocker |
同じデータで再現性のあるテストができる |
CI/CD テスト |
Mocker |
毎回同じデータなので結果が予測可能 |
ストレステスト |
RandomMocker |
様々なパターンをランダムに生成 |
🐛 トラブルシューティング#
エラー: “No such file or directory”#
# ❌ 原因:ファイルパスが間違っている
mocker = Mocker(MockerConfig(csv_path="./data/missing.csv"))
# ✅ 解決策 1:ファイルの存在確認
import os
if os.path.exists("examples/sample_data.csv"):
print("ファイルあり")
else:
print("ファイルなし - ランダムモデを使おう")
# ✅ 解決策 2:ランダムモデを使う
mocker = RandomMocker(MockerConfig())
エラー: “port already in use”#
このエラーが出ても Mock デバイスには影響ありません。
# 実デバイスを接続している場合だけ出ます
poetry run haniwers-v1 daq --mock # Mock なら問題なし
エラー: “Invalid threshold value”#
# ❌ 間違い:閾値の範囲外(1-1023)
write_threshold(mocker, ch=1, vth=2000) # 大きすぎる
# ✅ 正解:有効な範囲内
write_threshold(mocker, ch=1, vth=100) # OK
📖 関連ドキュメント#
テストガイド - ユニットテスト、CI/CD テスト
設定ガイド - ConfigLoader の詳細
CLI 開発ガイド - 新しいコマンド開発
サンドボックスガイド - sandbox ディレクトリの使い方
💡 ベストプラクティス#
開発フロー#
1. Mock で機能をテスト
poetry run haniwers-v1 daq --mock
2. 実ハードウェアで動作確認(手元に有る場合)
poetry run haniwers-v1 daq
3. ユニットテスト追加
poetry run pytest tests/
4. コミット・プッシュ
git commit -m "feat: add new feature"
git push
チェックリスト#
Mock デバイスで動作確認した
ユニットテストを追加した
poetry run ruff formatでコード整形したpoetry run pytestですべてのテストが通った