This Go application reads battery data from an electric vehicle via OBD-II and sends it to aa-proxy-rs for Android Auto integration.
- Reads battery state of charge (SoC %), available energy (Wh), and external temperature
- USB connection to OBDLink EX adapter (no Bluetooth support, other USB ELM327 may work but untested)
- Configurable polling interval (default: 5 seconds)
- Support for multiple vehicle configurations via YAML files
- Mock mode for testing without vehicle connection
- Automatic retry and caching of last known good values
GOOS=linux GOARCH=arm64 go build -o ev-obd-feeder
- Build for ARM64:
GOOS=linux GOARCH=arm64 go build -o ev-obd-feeder
- Copy the binary, config, and init script to the Radxa:
scp -O ev-obd-feeder root@10.0.0.1:/usr/bin/
scp -O configs/ioniq5n.yaml root@10.0.0.1:/etc/ev-obd-feeder.yaml
scp -O init.d/S99ev-obd-feeder root@10.0.0.1:/etc/init.d/
- SSH into the Radxa:
ssh root@10.0.0.1
- Verify the OBDLink EX USB connection:
# The OBDLink EX appears as /dev/ttyUSB0 when connected via USB
ls -la /dev/ttyUSB0
# The config should already have the correct path (/dev/ttyUSB0)
# Edit only if needed:
vi /etc/ev-obd-feeder.yaml
- Make the files executable and start the service:
chmod +x /usr/bin/ev-obd-feeder
chmod +x /etc/init.d/S99ev-obd-feeder
/etc/init.d/S99ev-obd-feeder start
# Normal mode
/usr/bin/ev-obd-feeder -config /etc/ev-obd-feeder.yaml
# Debug mode (verbose logging)
/usr/bin/ev-obd-feeder -config /etc/ev-obd-feeder.yaml -debug
# Test mode (mock data, no vehicle needed)
/usr/bin/ev-obd-feeder -config /etc/ev-obd-feeder.yaml -test -debug
# Start service
/etc/init.d/S99ev-obd-feeder start
# Stop service
/etc/init.d/S99ev-obd-feeder stop
# Restart service
/etc/init.d/S99ev-obd-feeder restart
# Check if running
/etc/init.d/S99ev-obd-feeder status
# Tail default log location
tail -f /var/log/ev-obd-feeder.log
The application uses YAML configuration files. See configs/ioniq5n.yaml
for an example.
Key configuration sections:
serial
: OBD adapter settings (device path and baud rate)vehicle
: Vehicle name, battery capacity, and PID mappingsaaproxy
: URL for aa-proxy-rs battery endpoint (http://localhost:80/battery)poll_interval
: How often to query the vehicle (default: 5s)
Currently configured for:
- Hyundai Ioniq 5 N (configs/ioniq5n.yaml)
The PID configuration is flexible and can be adapted for other vehicles by creating new YAML config files, should work seamlessly with other EGMP vehicles, anything else is untested.
-
No data from ECU: Ensure vehicle is ON or in accessory mode
-
Connection failed: Check OBDLink EX USB connection:
# Verify USB device exists: ls -la /dev/ttyUSB0 # Check if device is detected in kernel: dmesg | grep -i 'usb\|serial' | tail -10 # Ensure OBDLink EX is powered on and connected via USB cable
-
aa-proxy connection failed: Verify aa-proxy-rs is running:
ps aux | grep aa-proxy-rs # Should see: /usr/bin/aa-proxy-rs # Check if listening on port 80: netstat -an | grep :80 # Check aa-proxy-rs service: /etc/init.d/S93aa-proxy-rs status
The application sends JSON data to aa-proxy-rs in this format:
{
"battery_level_percentage": 67.5,
"battery_level_wh": 54000,
"battery_capacity_wh": 80000,
"external_temp_celsius": 22.0
}
- Was this vibe coded?: Yes, most of the OBD scraping and parsing of the vendor specific Hyundai Mode 22 OBD codes were vibe coded. As is the debug function.
- What is this purpose of this?: This was created as I wanted a seamless destination route planning inside Google Maps for use with my current car, aa-proxy-rs provided that and also had the added benefit of moving wireless AA to 5GHz for less interference. Hopefully this is useful for you as well.
- How much RAM does this use?: This should use around 250MB RAM, so make sure your SBC has enough RAM.