obd-poller over the K-line via the Bluetooth ELM327; gnss publisher; elm_connected
Rust (L4T) / Clippy, test, build, glibc (push) Failing after 1s
/ crosscheck (push) Successful in 1s

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
This commit is contained in:
2026-10-13 22:57:30 +09:00
parent 54171aaf27
commit cce9711119
19 changed files with 809 additions and 405 deletions
+34
View File
@@ -0,0 +1,34 @@
//! 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))));
}
}
}