状態監視
Client の read_state の返り値を見ることで, デバイスとの通信が正常に動いているかどうかを監視できる.
Response の device_status は, その返信の時点の各デバイスの状態 DeviceStatus の配列を返す.
DeviceStatus は以下を持つ.
state: デバイスの状態 (DeviceState).ptp_locked: PTP がロックしているか.failsafe_active: フェイルセーフで出力を止めていて, まだ解除されていないか
全デバイスが Ready か, といった集約は返り値から作る (下の例を参照).
ptp_locked と failsafe_active はその返信の値である.
DeviceStateの意味は以下の通り.
| 状態 | 意味 |
|---|---|
Ready |
返信があり, 時刻が同期されている |
Syncing |
返信はあるが, 時刻を合わせている途中 |
以下は, 一定間隔で生存確認を送って device_status を見て, 状態が変化したときだけ出力する例.
let mut last: Vec<DeviceStatus> = Vec::new();loop { let Ok(response) = tokio::time::timeout(CHECK_INTERVAL, client.read_state()).await else { println!("not every device replied within {CHECK_INTERVAL:?}"); continue; }; let status = response?.device_status(); if last != status { for (i, s) in status.iter().enumerate() { println!("device[{i}]: {}", s.state); } println!( "all ready: {}", status.iter().all(|s| s.state == DeviceState::Ready) ); last = status; } tokio::time::sleep(CHECK_INTERVAL).await;}last = Nonewhile True: try: response = await asyncio.wait_for(client.read_state(), timeout=CHECK_INTERVAL) except TimeoutError: print(f"not every device replied within {CHECK_INTERVAL} s") continue status = response.device_status() if status != last: for i, s in enumerate(status): print(f"device[{i}]: {s.state}") all_ready = all(s.state == DeviceState.Ready for s in status) print(f"all ready: {all_ready}") last = status await asyncio.sleep(CHECK_INTERVAL)DeviceStatus[] last = Array.Empty<DeviceStatus>();while (true){ using var timeout = new CancellationTokenSource(CheckInterval); DeviceStatus[] status; try { status = (await client.ReadStateAsync(timeout.Token)).DeviceStatus(); } catch (OperationCanceledException) { Console.WriteLine($"not every device replied within {CheckInterval}"); continue; } if (!status.SequenceEqual(last)) { for (var i = 0; i < status.Length; i++) { Console.WriteLine($"device[{i}]: {status[i].State}"); } var allReady = status.All(s => s.State == DeviceState.Ready); Console.WriteLine($"all ready: {allReady}"); last = status; } await Task.Delay(CheckInterval);}