From f1c076d71a932f5c26603827b396fcab7a3136f1 Mon Sep 17 00:00:00 2001 From: fiatcode Date: Thu, 30 Apr 2026 10:45:39 +0700 Subject: [PATCH] docs: add traccar client design spec --- .../specs/2026-04-30-traccar-client-design.md | 274 ++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-30-traccar-client-design.md diff --git a/docs/superpowers/specs/2026-04-30-traccar-client-design.md b/docs/superpowers/specs/2026-04-30-traccar-client-design.md new file mode 100644 index 0000000..f0b7ea0 --- /dev/null +++ b/docs/superpowers/specs/2026-04-30-traccar-client-design.md @@ -0,0 +1,274 @@ +# Traccar Client Rewrite - Specification + +**Date**: 2026-04-30 +**Project**: traccar_client +**Type**: Fresh Flutter + Native Android GPS tracking app + +--- + +## 1. Project Overview + +- **Purpose**: Reliable background GPS location tracking app for Android that reports to a self-hosted Traccar server +- **Target Platform**: Android only +- **Traccar Protocol**: Standard HTTP-based protocol (compatible with any self-hosted Traccar server) + +--- + +## 2. Architecture + +### 2.1 Technology Stack + +| Layer | Technology | Responsibility | +|-------|------------|----------------| +| **UI** | Flutter | Settings screen, main screen, status/log viewer | +| **Bridge** | Platform Channels | MethodChannel + EventChannel between Flutter and Android | +| **Service** | Kotlin Android | Foreground service for reliable background tracking | +| **Location** | FusedLocationProviderClient (Google Play Services) | GPS location acquisition | +| **Storage** | Room (SQLite) | Offline location buffer + event log | +| **Network** | OkHttp | HTTP POST to Traccar server | +| **Background** | WorkManager | Heartbeat scheduling, periodic sync | + +### 2.2 Data Flow + +``` +[FusedLocationProvider] + ↓ +[DistanceFilterProcessor] → (discard if within threshold) + ↓ +[LocationTrackingService] → [Room: locations buffer] ← (if offline) + ↓ +[TraccarHttpClient] → POST to server → [Room: mark synced] + ↑ (when online) +[WorkManager] → periodic sync attempt +``` + +--- + +## 3. Components + +### 3.1 Flutter UI Layer + +| Screen | Purpose | +|--------|---------| +| `main_screen.dart` | Toggle tracking on/off, display last location, speed, timestamp | +| `settings_screen.dart` | All configuration options | +| `status_screen.dart` | Event log viewer for debugging | +| `preferences.dart` | SharedPreferences wrapper for settings persistence | + +### 3.2 Platform Bridge + +| Class | Type | Purpose | +|-------|------|---------| +| `location_bridge.dart` | Flutter | Platform channel wrapper | +| `BridgeModule.kt` | Kotlin | Registers MethodChannel + EventChannel | + +### 3.3 Android Service Layer + +| Class | Purpose | +|-------|---------| +| `LocationTrackingService` | Foreground service with persistent notification | +| `FusedLocationProvider` | Google Play Services location API wrapper | +| `DistanceFilterProcessor` | Distance/interval/angle filtering with Haversine | +| `HeartbeatScheduler` | Stationary heartbeat via WorkManager | +| `AppDatabase` | Room database | +| `LocationDao` | CRUD for buffered locations | +| `EventLogDao` | CRUD for event log entries | +| `TraccarHttpClient` | HTTP POST with retry and auth | +| `ConnectivityReceiver` | Network change listener | +| `Location` | Data model | + +--- + +## 4. Settings + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `serverUrl` | String | `https://demo.traccar.org` | Traccar server URL | +| `deviceId` | String | Auto-generated 8-digit | Device identifier | +| `accuracy` | String | `HIGH` | GPS accuracy: HIGH/HIGH_ACCURACY/BALANCED/LOW | +| `distanceFilter` | int | `75` | Min distance between reports (meters) | +| `interval` | int | `300` | Time-based fallback filter (seconds) | +| `heartbeat` | int | `60` | Stationary heartbeat interval (seconds) | +| `offlineBuffer` | bool | `true` | Queue locations when offline | +| `stopDetection` | bool | `true` | Auto-stop tracking when stationary | +| `password` | String | `""` | Basic auth password for server | + +--- + +## 5. Foreground Notification + +**Layout**: +``` +┌─────────────────────────────────────────┐ +│ 📍 Traccar Client [ON/OFF] │ +├─────────────────────────────────────────┤ +│ Lat: 37.7749 Lon: -122.4194 │ +│ Speed: 45 km/h │ +│ Last: 09:41:23 │ +└─────────────────────────────────────────┘ +``` + +**Updates**: Notification content updates in real-time as locations are captured and sent. + +--- + +## 6. Traccar Protocol + +**Endpoint**: `{serverUrl}/?id={deviceId}&lat={lat}&lon={lon}×tamp={ts}&speed={speed}&...` + +**Parameters**: +- `id` - Device identifier +- `lat` - Latitude +- `lon` - Longitude +- `timestamp` - Unix timestamp (milliseconds) +- `speed` - Speed in km/h +- `bearing` - Heading in degrees +- `accuracy` - GPS accuracy in meters +- `altitude` - Altitude in meters +- `is_moving` - 1 if moving, 0 if stationary + +**Authentication**: HTTP Basic Auth if password is set. + +--- + +## 7. Offline Buffering + +**When offline**: +1. Location is captured and passes filters +2. Location is saved to Room `locations` table with `synced=0` +3. App continues tracking and buffering + +**When connectivity restored**: +1. WorkManager triggers sync +2. All buffered locations are sent to server +3. Locations marked as `synced=1` + +--- + +## 8. Heartbeat Behavior + +| State | Behavior | +|-------|----------| +| **Moving** | Normal location updates based on distance/interval filters | +| **Stationary** | Heartbeat fires every N seconds (configurable), triggers single location fix | +| **Stop detected** | Tracking auto-stops if `stopDetection=true`, heartbeat continues | + +--- + +## 9. Event Log + +**Logged Events**: +| Event Type | When Logged | +|------------|-------------| +| `LOCATION` | Location captured and accepted | +| `FILTERED` | Location filtered (reason: distance/interval/angle) | +| `SYNC` | Location successfully sent to server | +| `HEARTBEAT` | Heartbeat event fired | +| `NETWORK_CHANGE` | Network went online/offline | +| `ERROR` | Any error condition | + +**Log Entry Fields**: timestamp, event_type, message + +--- + +## 10. File Structure + +``` +traccar_client/ +├── lib/ +│ ├── main.dart +│ ├── main_screen.dart +│ ├── settings_screen.dart +│ ├── status_screen.dart +│ ├── preferences.dart +│ └── bridge/ +│ └── location_bridge.dart +├── android/app/src/main/ +│ ├── kotlin/com/traccar/traccar_client/ +│ │ ├── MainActivity.kt +│ │ ├── BridgeModule.kt +│ │ ├── service/ +│ │ │ └── LocationTrackingService.kt +│ │ ├── location/ +│ │ │ ├── FusedLocationProvider.kt +│ │ │ ├── DistanceFilterProcessor.kt +│ │ │ └── HeartbeatScheduler.kt +│ │ ├── storage/ +│ │ │ ├── AppDatabase.kt +│ │ │ ├── LocationDao.kt +│ │ │ └── EventLogDao.kt +│ │ ├── network/ +│ │ │ ├── TraccarHttpClient.kt +│ │ │ └── ConnectivityReceiver.kt +│ │ └── model/ +│ │ └── Location.kt +│ └── AndroidManifest.xml +├── docs/ +│ └── superpowers/ +│ └── specs/ +│ └── 2026-04-30-traccar-client-design.md +└── pubspec.yaml +``` + +--- + +## 11. Dependencies + +### Flutter (pubspec.yaml) +```yaml +dependencies: + flutter: + sdk: flutter + shared_preferences: ^2.2.0 + workmanager: ^0.5.0 + sqflite: ^2.3.0 + http: ^1.1.0 + permission_handler: ^11.0.0 + flutter_local_notifications: ^16.0.0 +``` + +### Android (app/build.gradle) +```groovy +implementation 'androidx.room:room-runtime:2.5.0' +implementation 'com.google.android.gms:play-services-location:21.0.1' +implementation 'androidx.work:work-runtime:2.8.0' +implementation 'androidx.appcompat:appcompat:1.6.1' +``` + +--- + +## 12. Android Permissions + +```xml + + + + + + + + +``` + +--- + +## 13. Verification Criteria + +| Test | Expected Result | +|------|------------------| +| Home→Office route (10km) | 20+ coordinate points captured | +| Offline mode | Locations queued, synced when connection restored | +| Stationary 5+ minutes | Heartbeat fires every N seconds (configurable) | +| Arrival detection | Tracking stops, heartbeat continues | +| App restart | Settings persist, tracking resumes | +| Notification | Shows ON/OFF status, coordinates, speed, timestamp | + +--- + +## 14. Implementation Phases + +1. **Phase 1**: Project Setup - Flutter project, Android permissions, dependencies +2. **Phase 2**: Native Android Layer - Location service, Room database, HTTP client +3. **Phase 3**: Flutter UI Layer - Main screen, settings screen, status screen +4. **Phase 4**: Platform Channel Bridge - MethodChannel, EventChannel +5. **Phase 5**: Integration & Testing