# flighthook
Shared type definitions for the flighthook launch monitor bridge. Used by both
the application crate (`flighthook-app`) and the UI crate (`flighthook-ui`).
## Configuration types
Types for the TOML config file and unit-aware value handling.
| `FlighthookConfig` | Top-level config with per-section `HashMap`s (webserver, mevo, gspro, mock_monitor, random_club) |
| `WebserverSection` | Web server instance (name + bind address) |
| `MevoSection` | Mevo device instance (address, ball type, tee height, range, surface height, track %) |
| `GsProSection` | GSPro integration instance (address, per-mode monitor routing) |
| `MockMonitorSection` | Mock launch monitor instance |
| `RandomClubSection` | Random club cycling integration instance |
| `ShotDetectionMode` | `Full` / `Putting` / `Chipping` |
| `UnitSystem` | `Imperial` / `Metric` |
| `Distance` | Unit-aware distance (ft, in, m, cm, yd, mm). Re-exported from `flightrelay`. Serializes as suffix string: `"1.5in"`, `"8ft"` |
| `Velocity` | Unit-aware velocity (mph, mps, kph, fps). Re-exported from `flightrelay`. Serializes as suffix string: `"90.3mph"` |
| `DistanceExt` | Extension trait for `Distance` — `unit_key()`, `from_value_and_unit()`, `to_mm()` |
| `VelocityExt` | Extension trait for `Velocity` — `unit_key()`, `from_value_and_unit()` |
## Bus event types
All inter-component communication flows through a single
`broadcast<FlighthookMessage>` channel.
### Message envelope
| `FlighthookMessage` | Bus message: actor ID, optional device ID (FRP), optional `RawPayload`, typed `FlighthookEvent` |
| `RawPayload` | `Binary(Vec<u8>)` (serializes as hex) or `Text(String)` |
### Event variants (`FlighthookEvent`)
All variants are flat struct variants with named fields (no wrapper types).
| `ShotTrigger` | Ball strike detected (carries `ShotKey`) — FRP |
| `BallFlight` | Ball flight data (key, ball data) — FRP |
| `ClubPath` | Club path data (key, club data) — FRP |
| `FaceImpact` | Face impact location (key, impact data) — FRP |
| `ShotFinished` | Shot sequence complete (key) — FRP |
| `DeviceTelemetry` | Device telemetry (identity, readiness, battery, tilt, temp) — FRP |
| `Alert` | User-visible warn/error/critical (severity + message) — FRP |
| `SetDetectionMode` | Detection mode and/or handedness change (both optional, latched) — FRP |
| `PlayerInfo` | Player name update |
| `ClubInfo` | Club selection update |
| `ConfigCommand` | Config mutation request (from POST handler) |
| `ConfigOutcome` | Mutation acknowledgment (from SystemActor) |
| `ActorStatus` | Actor lifecycle + telemetry |
### Shot data
| `ShotKey` | Shot correlation: UUID v4 `shot_id` (String) + `shot_number` (u32). Re-exported from `flightrelay` |
| `ShotData` | Complete shot: actor, shot number, optional ball flight, optional club, optional face impact |
| `ShotAccumulator` | Low-level: collects individual shot lifecycle events into a `ShotData` |
| `ShotAggregator` | High-level: feed `FlighthookMessage`s, get complete `ShotData` back when shots finish |
| `BallFlight` | All fields `Option`. Re-exported from `flightrelay`. Launch speed, elevation, azimuth, carry/total distance, max height, flight time, backspin/sidespin |
| `ClubData` | All fields `Option`. Re-exported from `flightrelay`. Club speed, path, attack angle, face angle, dynamic loft, smash factor, swing plane, offset/height |
| `FaceImpact` | All fields `Option`. Re-exported from `flightrelay`. Face impact location data |
### Actor status
| `ActorStatus` | Lifecycle enum: `Starting` / `Disconnected` / `Connected` / `Reconnecting` |
### Commands and outcomes
| `ConfigAction` | `ReplaceAll` / `UpsertWebserver` / `UpsertMevo` / `UpsertGsPro` / `Remove` / ... |
| `Severity` | `Warn` / `Error` / `Critical`. Re-exported from `flightrelay` |
## API types
REST request/response types shared between the web server and the UI.
| `StatusResponse` | `GET /api/status` -- actor map + current mode |
| `ActorStatusResponse` | Per-actor: name, status, telemetry map |
| `ModeRequest` | `POST /api/mode` -- target detection mode |
| `PostSettingsResponse` | `POST /api/settings` -- lists of restarted/stopped actors |
## WebSocket client (`client` feature)
A synchronous WebSocket client for connecting to a running flighthook server.
Behind the `client` feature flag (adds `tungstenite`). Not included by default
so UI/WASM builds are unaffected.
```toml
[dependencies]
flighthook = { version = "0.1", features = ["client"] }
```
| `FlighthookClient` | WebSocket client. `connect`, `recv`, `try_recv`, `send`. |
| `ClientError` | Error enum: `WebSocket`, `Json`, `Closed` |
### Blocking
```rust
use flighthook::{FlighthookClient, ShotAggregator};
let mut client = FlighthookClient::connect("ws://localhost:5880/frp", "my-app")?;
let mut shots = ShotAggregator::new();
loop {
let msg = client.recv()?;
if let Some(shot) = shots.feed(&msg) {
println!("shot #{}: {:?}", shot.shot_number, shot.ball.as_ref().and_then(|b| b.launch_speed));
}
}
```
### Non-Blocking (Game Loop)
```rust
use flighthook::{FlighthookClient, ShotAggregator};
let mut client = FlighthookClient::connect("ws://localhost:5880/frp", "my-sim")?;
client.set_nonblocking(true)?;
let mut shots = ShotAggregator::new();
loop {
// Drain all pending messages
while let Ok(Some(msg)) = client.try_recv() {
if let Some(shot) = shots.feed(&msg) {
println!("shot #{}: {:?}", shot.shot_number, shot.ball.as_ref().and_then(|b| b.launch_speed));
}
}
// ... render frame, physics tick, etc.
}
```
## Game state types
| `Club` | 19-variant enum (Driver through Putter). Serializes to GSPro codes (`"DR"`, `"7I"`, `"PT"`). `mode()` maps to detection mode. |
| `ClubInfo` | Current club selection |
| `PlayerInfo` | Player name |
| `Handedness` | `Right` / `Left`. Re-exported from `flightrelay` |
| `GameStateSnapshot` | Immutable snapshot: player info, club info, current mode |