cce9711119
obd-poller drops its CAN socket: the Z27AG answers OBD-II only on ISO 9141-2. It holds a raw RFCOMM link to the ELM (no pairing, no root), fixes the protocol (ATSP3) so nothing probes CAN, publishes the obd_* signals, and releases the adapter after a minute of ECU silence so it can sleep. gnss: gpsd's fix as yukart/gnss/<signal>. orin-status: elm_connected from BlueZ. One native deploy script (deploy-native.sh BIN) behind the per-service ones; /etc/default/yukart-elm holds the adapter's address. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
35 lines
1.1 KiB
Rust
35 lines
1.1 KiB
Rust
//! The Bluetooth link to the ELM327 (the OBD-II adapter on the K-line), as BlueZ sees
|
|
//! it. Only watched, never opened: the adapter takes one connection, and obd-poller
|
|
//! holds it while the ECU answers.
|
|
|
|
use std::process::Command;
|
|
|
|
use serde_json::{json, Value};
|
|
|
|
pub struct Elm {
|
|
/// "00:0C:BF:50:AF:3F"; None when no adapter is configured.
|
|
addr: Option<String>,
|
|
}
|
|
|
|
/// `bluetoothctl info` says "Connected: yes" while any link to the device is up,
|
|
/// the poller's serial link included. An unknown device is simply not connected.
|
|
fn connected(addr: &str) -> bool {
|
|
Command::new("bluetoothctl")
|
|
.args(["info", addr])
|
|
.output()
|
|
.map(|o| String::from_utf8_lossy(&o.stdout).lines().any(|l| l.trim() == "Connected: yes"))
|
|
.unwrap_or(false)
|
|
}
|
|
|
|
impl Elm {
|
|
pub fn new(addr: &str) -> Self {
|
|
Elm { addr: Some(addr.trim().to_string()).filter(|a| !a.is_empty()) }
|
|
}
|
|
|
|
pub fn read(&mut self, out: &mut Vec<(&'static str, Value)>) {
|
|
if let Some(a) = &self.addr {
|
|
out.push(("elm_connected", json!(connected(a))));
|
|
}
|
|
}
|
|
}
|