Releases: waleedmandour/EVD
Release list
EVDx v1.5.3-pre
EVDx v1.5.3-pre
What's New
1. Auto-connect to paired devices (Quick Connect)
- New
getBondedOBDDevices()method checks Android's bonded (paired) BLE device list - When the user enters Bluetooth mode, EVDx instantly checks for previously-paired OBD adapters
- Paired devices appear at the top as Quick Connect options — no need to wait for the 8-second scan
- iOS BLE mode devices in the paired list show a warning and are disabled
2. Vgate iCar Pro "Android-Vlink" alias fix
- Added
android-vlinkas alias for Vgate iCar Pro profiles (not vLinker)
3. iOS BLE mode detection
- Adapters in "iOS BLE" mode are detected with a red warning badge and disabled connect button
4. Arab currencies (15+)
- Currency selector: OMR, SAR, AED, QAR, BHD, KWD, EGP, JOD, MAD, DZD, TND, LYD, IQD, SDG, YER + USD
5. Updated dedication
- English: Made with ❤ to EV Owners in the Arab World
- Arabic: إهداء إلي جميع ملاك السيارات الكهربائية في العالم العربي
6. Profile picker + FFF0 support
- 13 BLE adapter profiles including FFF0 for Vgate iCar Pro v3+
- Profile picker UI when auto-detection fails
- Firmware update information in Device tab
Verification
- TypeScript: 0 errors
- Gradle assembleRelease: BUILD SUCCESSFUL
- APK: v1.5.3, versionCode 10, 25.2 MB
Install
- Download
evdx-v1.5.3-pre-release.apkbelow - Install over existing EVDx (settings preserved)
- Connect → Bluetooth OBD → paired devices appear instantly as Quick Connect
Security Reminder
Revoke your GitHub token at https://github.com/settings/tokens
EVDx v1.5.2-pre — Fix "characteristics not found" on Vgate iCar Pro v3+
EVDx v1.5.2-pre
Fixes the "characteristics not found" error reported on Vgate iCar Pro OBDII adapters paired with Android 13+ phones (e.g. Google Pixel).
The Problem
Users reported that EVDx detected the Vgate iCar Pro during BLE scan, but the connection failed immediately with the raw error "characteristics not found" — with no recovery path.
Root Cause
Vgate has shipped several firmware variants of the iCar Pro over the years:
| Firmware | Service UUID | Char UUIDs | Era |
|---|---|---|---|
| v1.x, v2.x | 0000ffe0-... |
0000ffe1-... |
2017-2022 |
| v3.x (2023+) | 0000fff0-... |
0000fff1-... |
2023+ |
The v1.5.1 code only had the FFE0/FFE1 profile. When detectProfile() couldn't find FFE0/FFE1 on a v3+ adapter, it silently fell back to that same profile — which then failed at startNotifications() with the raw error.
The silent fallback was the real bug: it masked the actual problem and gave users no way to recover.
What's Fixed
1. Three new BLE profiles
| Profile | Service | Write | Notify | Use case |
|---|---|---|---|---|
| vGate iCar Pro v3+ (FFF0) | 0000fff0-... |
0000fff1-... |
0000fff1-... |
Vgate iCar Pro 2023+, BOLUTEK clones |
| BOLUTEK / CSR Clone (FFF0/FFF2) | 0000fff0-... |
0000fff1-... |
0000fff2-... |
Asymmetric write/notify clones |
| vGate iCar Pro (FFE0) | 0000ffe0-... |
0000ffe1-... |
0000ffe1-... |
(existing, renamed for clarity) |
2. detectProfile() no longer silently falls back
Throws NoMatchingProfileError instead. The UI catches this and shows a profile picker dialog so the user can manually try each profile.
3. Typed errors for better UI handling
Two new error classes:
CharacteristicsNotFoundError— includes device name + tried profileNoMatchingProfileError— includes device name + address
4. Profile picker UI in ConnectOverlay
When either typed error is caught, the ConnectOverlay shows a new profile picker section:
- Lists all 13 known BLE profiles
- User taps a profile →
connect()retries with that specific profile - User-friendly error messages explain what happened
- Suggests trying FFF0 profile for Vgate iCar Pro v3+
5. Firmware Update Information section in DeviceView
EVDx itself cannot update adapter firmware — that requires each manufacturer's proprietary tool. The new section documents the official update path:
| Brand | Update path |
|---|---|
| Vgate iCar Pro | No public tool. Use FFF0 profile instead. |
| OBDLink MX+/CX | OBDLink app (Play Store) |
| vLinker MC+/FS/BM+ | vLinker app (Play Store) |
| Veepeak | No public tool — contact support |
| Carly | Carly app (firmware updates free) |
| Generic ELM327 clones | No update path (masked ROM) |
6. Why no in-app firmware updater?
Vgate does not publish a firmware update tool. Their firmware is closed-source and can only be updated via the manufacturer's internal PC tool. Building an in-app updater would require reverse-engineering Vgate's proprietary format and protocol — not feasible for an open-source project.
The recommended fix for Vgate iCar Pro v3+ users is to use the FFF0 profile via the new profile picker, not to update firmware.
Verification
- TypeScript:
tsc --noEmitclean (0 errors). - Next.js production build: static export succeeds (5.6s compile).
- Gradle
assembleRelease: BUILD SUCCESSFUL. aapt dump badgingconfirmsversionName=1.5.2 versionCode=9 targetSdk=36.- All 34 protocol simulation tests pass.
- APK size: 25.8 MB.
Install
- Download
evdx-v1.5.2-pre-release.apkbelow. - Install over existing EVDx (vehicle profiles + settings preserved).
- Open EVDx → Connect → Bluetooth OBD → tap your Vgate iCar Pro.
- If you still see "characteristics not found", the profile picker appears automatically. Tap "vGate iCar Pro v3+ (FFF0)" first.
- If FFF0 doesn't work, try the other profiles in order.
Security Reminder
The GitHub token used to push this release was shared in plain text. Revoke it immediately at https://github.com/settings/tokens.
EVDx v1.5.1-pre — Critical BLE/OBD-II fixes
EVDx v1.5.1-pre
Pre-release with comprehensive fixes: BLE/OBD-II core fixes, real Mode 22 (manufacturer-specific) PID support, voice commands wired to actual actions, Arabic PDF rendering, onboarding flow with real BLE scan, WiFi cleartext whitelist expansion, settings persistence, and dead code removal.
Full details in CHANGELOG-v1.5.1.md. The commits in this pre-release:
c8bacdf— v1.5.1: Critical BLE/OBD-II fixes + real diagnostic scan5498d6b— v1.5.1+: CI workflow, README update, 9 audit-driven bug fixes6ccad7d— docs: bilingual user guide HTML sources3534fd8— v1.5.1++: Voice commands, real OBD (Mode 22), PDF Arabic, onboarding, dead code
What's New in this Build
1. Real OBD fields via Mode 22 (manufacturer-specific) PIDs
The biggest user-visible improvement. Previously, when connected to a real OBD-II adapter, only the standard SAE J1979 Mode 01 PIDs (speed, RPM, coolant temp, voltage, etc.) were polled. All the EV-specific data — pack voltage, pack current, SOC, SOH, cell voltages, battery temp, motor temp, inverter temp, coolant temps, aux battery, insulation resistance — stayed at their default values (0, 100, 999). Users saw a mix of real data and stale defaults.
Now EVDx queries manufacturer-specific Mode 22 PIDs for each brand:
| Brand | Custom PIDs | What's now exposed |
|---|---|---|
| BYD | 0x2101–0x210A | BMS Pack V/I, SOC, Cell Max/Min V, temps |
| Tesla | 0x2110–0x2219 | Pack V/I, nominal + remaining energy |
| Nissan | 0x5B9A–0x5BA4 | Battery Pack V/I, SOC, cell voltages |
| Hyundai/Kia | 0x2100–0x21FF | BMS data |
| VW Group | UDS 0x22xx | Battery data via UDS |
| + 13 more brands | see src/data/vehicles.json |
How it works:
BLEService.setCustomPIDs(defs)is called when the user picks a vehicle (viastore.setActiveVehicle).- During
connect(),detectCustomPIDs()probes each PID with a 1.5s timeout and stores the supported subset inadapterInfo.supportedCustomPIDs. startPolling()interleaves Mode 22 queries with the standard Mode 01 round-robin.parseOBDResponsehandles Mode 62 responses: looks up the PID def, evaluates the formula viaBLEService.evaluateFormula(strict-whitelist, noeval), and maps the result to the rightvehicleDatafield by name.- Derived values are computed when standard PIDs update:
power = V × A / 1000,range = SOC × capacity × 6 km/kWh.
Safety: The formula evaluator uses a strict regex whitelist (/^[ABCD\s\d+\-*/()<>|&^.,]*$/) and the Function constructor — it rejects property access, function calls, and global references. 8 new protocol tests cover BYD/Tesla/Nissan formulas + safety (34/34 tests pass, was 26).
2. Voice commands wired to actual actions (both EN + AR)
Previously, 12 voice commands spoke a confirmation but performed no action. Now all are wired:
| Command | Action |
|---|---|
| 'clear codes' / 'امسح الأعطال' | bleService.clearDTCs() (Mode 04) + clearDTCs() + setMilOn(false) |
| 'switch to arabic' / 'غيّر اللغة' | updateSettings({ language: 'ar' }) + i18n.changeLanguage('ar') |
| 'switch to english' | updateSettings({ language: 'en' }) + i18n.changeLanguage('en') |
| 'turn off voice' / 'إيقاف الصوت' | updateSettings({ voiceAssistant: false }) |
| 'enable alerts' / 'فعّل التنبيهات' | updateSettings({ notifications: true }) |
| 'mute alerts' / 'كتم التنبيهات' | updateSettings({ notifications: false }) |
| 'eco' / 'اقتصادي' | updateVehicleData({ mode: 'eco' }) |
| 'sport' / 'رياضي' | updateVehicleData({ mode: 'sport' }) |
| 'normal mode' / 'عادي' | updateVehicleData({ mode: 'normal' }) |
| 'export report' / 'تصدير التقرير' | generateReport() + downloadBlob() (PDF generated based on active tab) |
| 'start demo' / 'بدء العرض' | connectDemo() |
| 'stop demo' / 'إيقاف العرض' | disconnect() (only if in demo mode — won't kill real BLE) |
| 'connect adapter' / 'وصّل' | connectBluetooth() if autoConnect, else navigate to Device tab |
| 'disconnect adapter' / 'افصل' | disconnect() |
3. PDF Arabic rendering fixed
jsPDF's built-in Helvetica font has no Arabic glyphs, and even with an Arabic font embedded, jsPDF doesn't shape Arabic letters (join them correctly) or handle RTL. Fixed by:
- Bundling Amiri-Regular.ttf + Amiri-Bold.ttf in
public/fonts/(1.2 MB total). loadArabicFont()fetches them at PDF-gen time and registers viadoc.addFileToVFS+addFont.shapeArabic()runs text througharabic-reshaper(new dep) to convert logical-order Arabic into presentation forms, then reverses for RTL display.writeText()helper shapes text + flips alignment for Arabic.- All 40
doc.text/doc.setFontcalls migrated towriteText/setFont.
Also fixed: addDarkBackground() was missing on 3 of 5 addPage sites, causing white-on-white invisible text on multi-page reports. Now called after every addPage.
4. OnboardingFlow 'Connect Adapter' button — real scan + permissions
Was a fake 2-second timer that did nothing. Now:
- Calls
requestBlePermissions()(Android 12+: BLUETOOTH_CONNECT + BLUETOOTH_SCAN). - Initializes
bleServiceand runsscan(8000). - Shows the scanned device list inline so the user can pick one.
- On pick:
bleService.connect()+ ELM327 init +startPolling(). - On success: advances to the 'done' step.
- On failure: shows the error inline + offers a 'Skip — connect later' button so users can complete onboarding without an adapter.
Also added battery capacity input validation (min=1, max=1000, rejects NaN/negative).
5. ConnectOverlay connecting state + i18n
setConnectionStatus('connecting')is now set at the start of BLE/WiFi connect handlers (was jumping straight to 'connected', so the spinner never showed and users could tap Connect repeatedly, spawning concurrentbleService.connect()calls).- WiFi port input:
type="number" min=1 max=65535+ integer validation. - WiFi IP input: regex validation for dotted-quad IPv4 or DNS hostname.
- Demo button:
disabled={!demoBrand || !demoModel}(was no validation — user could start demo with no vehicle profile, breaking the simulator). - All 25+ hardcoded English strings migrated to
t()with new keys inen/ar common.json(bluetoothObd, wifiObd, noAdaptersFound, scanFailed, connectFailed, wifiConnectFailed, invalidPort, invalidIp, permissionsRequired, scanAgain, ipAddress, port, brand, model, selectBrand, selectModel, startDemoMode, etc.).
6. WiFi cleartext whitelist expanded
Was 25 specific IPs → now covers all common private-use subnets:
- Full 192.168.0.x and 192.168.1.x (most common)
- 192.168.2-10.x (OBDLink WiFi, vLinker)
- 192.168.43.x (Android WiFi hotspot — when phone is AP, adapter is client)
- 192.168.49.x (iOS Personal Hotspot)
- 10.0.x.x, 10.10.10.x (enterprise/home)
- 172.16.x.x (private enterprise)
Still blocks ALL public/non-private traffic — the privacy-first guarantee is preserved.
7. Settings persistence + Quiet Hours mislabel fixed
- New
AlertThresholdsandQuietHourstypes inAppSettings. SettingsViewbinds alert threshold inputs directly tosettings.alertThresholds(was localuseStatewith hardcoded '20'/'80'/'50' that never persisted — values were lost on tab change/app restart).- Quiet Hours switch now bound to
settings.quietHours.enabled(was bound tosettings.notifications— toggling it muted ALL notifications globally instead of enabling quiet hours).
8. Dead code removed
- Deleted
src/lib/db.ts(147 lines, never imported anywhere; claimed to use@capacitor-community/sqlitebut actually used localStorage). - Deleted
prisma/schema.prisma(Next.js template leftover with default User/Post models; Prisma not in package.json).
Additional fixes
simulator.resolveBrand: was failing to match most brand names ('VW Group' → 'vw-group' → no match → generic). Now uses substring matching with special cases for hyundai-kia and vw-group (matches vw/volkswagen/audi/porsche/skoda/seat/id./e-tron). This restores brand-specific chemistry (LFP vs NCA vs NMC), thermal coefficients, cell counts, charge curves, and DTC prefixes for most vehicles.store.parseOBDResponseMode 03: was wiping pending (Mode 07) DTCs viasetDTCs(dtcs). Now merges:[...storedDTCs, ...existingPending].
Verification
- TypeScript:
tsc --noEmitclean. - Next.js production build: static export succeeds (Turbopack, 6.5s).
- Gradle
assembleRelease: BUILD SUCCESSFUL. aapt dump badgingconfirmsversionName=1.5.1 versionCode=8 targetSdk=36.- Node OBD-II protocol simulation test: 34/34 pass (was 26 — added 8 Mode 22 / Mode 62 tests).
- APK size: 25.8 MB (was 25.3 MB — the extra 500 KB is the Amiri Arabic fonts).
⚠️ Note on hardware simulation
The task brief asked for a simulation verifying the APK detects OBD-II devices and reads diagnostic data accurately. Without physical ELM327 hardware or an Android emulator with ELM327 simulation, true end-to-end runtime testing against a live vehicle is not possible in a headless CI environment. The included Node-based protocol simulation test (scripts/obd-protocol-sim.test.mjs) exercises the exact byte-level parsing logic that the production app uses — including the new Mode 22 formula evaluator and Mode 62 response parser. For on-device verification, sideload the APK in this release and test against a real OBD-II adapter.
Install
- Download
evdx-v1.5.1-pre-release.apkbelow. - Transfer to your Android device (Android 7.0+ / API 24+).
- Enable 'Install from unknown sources' in Settings.
- Open the APK to install.
- Pair your OBD-II adapter via the in-app Connect screen.
For full setup, connection, and diagnostic workflow instructions, see the bilingual PDF user guides below.
Security reminder
The GitHub token used to push this release was shared in plain text in the original request. Revoke it immediately at https://github.com/settings/tokens and generate a new one through a secu...
EVDx v1.5.1 — Universal EV Diagnostics Pro
EVDx v1.5.1 — Universal EV Diagnostics Pro
Professional electric vehicle diagnostics companion — built with privacy at its core.
Build & Infrastructure
- Built with JDK 21 (Temurin) and Android SDK 36 (API 36)
- Fix duplicate
ic_launcher_backgroundresource merge conflict - Remove unused
/apistub route that broke Next.js static export - Sync web assets via Capacitor 8
- 25MB signed release APK built from main branch
System Requirements
- Android 7.0 (API 24) or later
- Bluetooth LE recommended
Installation
- Download
EVDx-v1.5.1.apkfrom this release - Enable "Install from Unknown Sources" in Android settings
- Open the downloaded APK and tap Install
- Launch EVDx and follow the onboarding wizard
Privacy
- No INTERNET permission in AndroidManifest
- Zero cloud dependency, zero telemetry, zero analytics
- All data on-device with SQLCipher encryption
Author
Dr. Waleed Mandour — waleedmandour@gmail.com — w.abumandour@squ.edu.om
EVDx v1.5.0 — Universal BLE Device Discovery
EVDx v1.5.0 — Universal BLE Device Discovery
🔍 Major Change: Show All BLE Devices
Previously, the BLE scan only displayed devices with OBD-like names. Many ELM327 adapters use non-standard names (BT05, HC-08, CC41-A, JDY-23, SP40, etc.) or advertise no name at all — these were completely hidden.
Now the scan shows ALL discovered BLE devices, letting the user choose their adapter:
- Known OBD devices are highlighted with a green profile badge
- Other BLE devices are shown with a "BLE" badge
- Devices with no name show "Name unavailable" and sort to the bottom
- Visual section separator divides OBD adapters from other devices
- Smart sorting: OBD-like devices first, then others by signal
🔧 Smart Profile Detection
When connecting to an unknown device, the app now probes BLE service UUIDs to auto-detect the correct adapter profile.
🐛 Bug Fixes
- Fixed Gauges.tsx TypeScript error
- Fixed AIEcoCoach.tsx missing efficiency category
- Fixed report-generator.ts tuple type assertion
📱 App Info
- Version: 1.5.0 (versionCode 7)
- Author: Dr. Waleed Mandour
- Min Android: 7.0 (API 24) | Target: 16 (API 36)
- Zero cloud/telemetry: All data stays on-device
EVDx v1.4.0 Pre-Release
EVDx v1.4.0 — Production-Grade OBD-II Connection Overhaul + Critical Fixes
🔧 OBD-II Device Connection & Protocol Improvements
BLE Service (ble-service.ts)
- Complete ELM327 initialization per ELM Electronics datasheet
- Protocol auto-detection with
ATSP0(SAE J1979 protocols 1–9, A–C) - Adapter identification: firmware (
ATI), description (AT@1), identifier (AT@2) - Clone chip detection: STN vs genuine ELM327 vs PIC clone
- 10 BLE adapter profiles
- PID support detection per SAE J1979
- DTC reading: Mode 03 (stored), Mode 07 (pending), Mode 0A (permanent)
- DTC clearing: Mode 04
- VIN retrieval: Mode 09 PID 02
- WiFi ELM327 support via WebSocket
- Adapter voltage reading (
ATRV) - Response buffer cleared on timeout to prevent stale data
🐛 Critical Bug Fixes (from comprehensive code review)
DTC Parser (store.ts + ble-service.ts)
- Fixed Mode 03 parser: skip count byte correctly
- Fixed DTC code encoding: hex for low nibble, preserve first digit from high nibble
- Fixed DTCEvent objects: add required
active/countfields - Fixed DTC severity: use valid
DTCSeverityvalues
VoiceAssistant.tsx
- Fixed Rules of Hooks violation: moved early return after all
useCallbackhooks
ChargingView + LiveDataView
- Fixed
Math.random()in render path causing infinite re-renders - Used
useMemo+ stable sine-based variation
BatteryView.tsx
- Fixed division by zero: guard
cellMaxVwith fallback 3.7V
Permissions (permissions.ts)
- Fixed
granted: truereturned even when permissions were missing
SessionsView.tsx
- Now uses
settings.electricityCostPerKwhinstead of hardcoded value
I18nProvider.tsx
- Added document-level
dir/langsetup for proper RTL support
Android Network Security
- Fixed
network_security_config.xml: removed brokenincludeSubdomainson IPs - Added comprehensive list of common ELM327 adapter IPs across subnets
Android config.xml
- Replaced wildcard
<access origin="*" />with local-only patterns
RTL Fixes
- Replaced
text-leftwithtext-startacross all components
Package Cleanup
- Removed incompatible:
next-auth,prisma/@prisma/client - Removed version-mismatched:
@dnd-kitpackages - Removed unused:
i18next-http-backend,next-intl,sharp
📚 References
- ELM327 Datasheet (ELM Electronics)
- SAE J1979-2016 OBD-II Standard
- ISO 15765-4 CAN Bus Protocol
⚠️ Pre-Release Notice
This is a pre-release version for testing.
Author: Dr. Waleed Mandour
EVDx v1.3.0 Pre-Release
EVDx v1.3.0 — Universal EV Diagnostics Pro
🎤 Major Voice Assistant Upgrade
- 90+ Arabic voice command phrases (up from 8 single keywords)
- 3 Arabic dialects supported: Modern Standard Arabic (MSA), Gulf Arabic, Egyptian Arabic
- 20+ command categories including: battery health, range, motor temp, faults, clear codes, drive modes, demo mode, adapter connect/disconnect, export report, read aloud, speed, temperature, voice help
- Intelligent sub-detection: "صحة البطارية" gives health-specific response; "شحن البطارية" gives charge level
- Dialect-rich matching: Egyptian (قد ايه, الموتور, ديمو, سيتينج), Gulf (ايش العطل, وصّل, اشبك, سبورت), MSA (حالة البطارية, تشخيص, إعدادات)
- New commands: cell voltage, vehicle speed, temperature, language switch, alerts on/off, drive modes (eco/sport/normal), stop reading, voice help
🔧 Technical
- Version bumped to 1.3.0 (versionCode 5)
- All previous fixes preserved (TTS enhancement, voice recognition, WiFi ELM327)
Author: Dr. Waleed Mandour
License: MIT