Skip to content

Releases: waleedmandour/EVD

EVDx v1.5.3-pre

Choose a tag to compare

@waleedmandour waleedmandour released this 19 Jun 20:29

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-vlink as 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

  1. Download evdx-v1.5.3-pre-release.apk below
  2. Install over existing EVDx (settings preserved)
  3. 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+

Choose a tag to compare

@waleedmandour waleedmandour released this 18 Jun 09:20

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 profile
  • NoMatchingProfileError — 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 --noEmit clean (0 errors).
  • Next.js production build: static export succeeds (5.6s compile).
  • Gradle assembleRelease: BUILD SUCCESSFUL.
  • aapt dump badging confirms versionName=1.5.2 versionCode=9 targetSdk=36.
  • All 34 protocol simulation tests pass.
  • APK size: 25.8 MB.

Install

  1. Download evdx-v1.5.2-pre-release.apk below.
  2. Install over existing EVDx (vehicle profiles + settings preserved).
  3. Open EVDx → Connect → Bluetooth OBD → tap your Vgate iCar Pro.
  4. If you still see "characteristics not found", the profile picker appears automatically. Tap "vGate iCar Pro v3+ (FFF0)" first.
  5. 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

Choose a tag to compare

@waleedmandour waleedmandour released this 17 Jun 18:59

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 scan
  • 5498d6b — v1.5.1+: CI workflow, README update, 9 audit-driven bug fixes
  • 6ccad7d — docs: bilingual user guide HTML sources
  • 3534fd8 — 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:

  1. BLEService.setCustomPIDs(defs) is called when the user picks a vehicle (via store.setActiveVehicle).
  2. During connect(), detectCustomPIDs() probes each PID with a 1.5s timeout and stores the supported subset in adapterInfo.supportedCustomPIDs.
  3. startPolling() interleaves Mode 22 queries with the standard Mode 01 round-robin.
  4. parseOBDResponse handles Mode 62 responses: looks up the PID def, evaluates the formula via BLEService.evaluateFormula (strict-whitelist, no eval), and maps the result to the right vehicleData field by name.
  5. 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:

  1. Bundling Amiri-Regular.ttf + Amiri-Bold.ttf in public/fonts/ (1.2 MB total).
  2. loadArabicFont() fetches them at PDF-gen time and registers via doc.addFileToVFS + addFont.
  3. shapeArabic() runs text through arabic-reshaper (new dep) to convert logical-order Arabic into presentation forms, then reverses for RTL display.
  4. writeText() helper shapes text + flips alignment for Arabic.
  5. All 40 doc.text/doc.setFont calls migrated to writeText/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:

  1. Calls requestBlePermissions() (Android 12+: BLUETOOTH_CONNECT + BLUETOOTH_SCAN).
  2. Initializes bleService and runs scan(8000).
  3. Shows the scanned device list inline so the user can pick one.
  4. On pick: bleService.connect() + ELM327 init + startPolling().
  5. On success: advances to the 'done' step.
  6. 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 concurrent bleService.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 in en/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 AlertThresholds and QuietHours types in AppSettings.
  • SettingsView binds alert threshold inputs directly to settings.alertThresholds (was local useState with 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 to settings.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/sqlite but 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.parseOBDResponse Mode 03: was wiping pending (Mode 07) DTCs via setDTCs(dtcs). Now merges: [...storedDTCs, ...existingPending].

Verification

  • TypeScript: tsc --noEmit clean.
  • Next.js production build: static export succeeds (Turbopack, 6.5s).
  • Gradle assembleRelease: BUILD SUCCESSFUL.
  • aapt dump badging confirms versionName=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

  1. Download evdx-v1.5.1-pre-release.apk below.
  2. Transfer to your Android device (Android 7.0+ / API 24+).
  3. Enable 'Install from unknown sources' in Settings.
  4. Open the APK to install.
  5. 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...

Read more

EVDx v1.5.1 — Universal EV Diagnostics Pro

Choose a tag to compare

@waleedmandour waleedmandour released this 17 Jun 06:01
5cd4f3b

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_background resource merge conflict
  • Remove unused /api stub 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

  1. Download EVDx-v1.5.1.apk from this release
  2. Enable "Install from Unknown Sources" in Android settings
  3. Open the downloaded APK and tap Install
  4. 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.comw.abumandour@squ.edu.om

EVDx v1.5.0 — Universal BLE Device Discovery

Choose a tag to compare

@waleedmandour waleedmandour released this 15 Jun 08:20

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

Pre-release

Choose a tag to compare

@waleedmandour waleedmandour released this 14 Jun 08:32

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/count fields
  • Fixed DTC severity: use valid DTCSeverity values

VoiceAssistant.tsx

  • Fixed Rules of Hooks violation: moved early return after all useCallback hooks

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 cellMaxV with fallback 3.7V

Permissions (permissions.ts)

  • Fixed granted: true returned even when permissions were missing

SessionsView.tsx

  • Now uses settings.electricityCostPerKwh instead of hardcoded value

I18nProvider.tsx

  • Added document-level dir/lang setup for proper RTL support

Android Network Security

  • Fixed network_security_config.xml: removed broken includeSubdomains on 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-left with text-start across all components

Package Cleanup

  • Removed incompatible: next-auth, prisma/@prisma/client
  • Removed version-mismatched: @dnd-kit packages
  • 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

Pre-release

Choose a tag to compare

@waleedmandour waleedmandour released this 13 Jun 16:01

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