Розробка мобільного додатку для автомобільної телематики
Connected Car — екосистема, де автомобіль говорить з хмарою постійно: позиція GPS, дані CAN-шини, стан підсистем. Мобільний додаток — вікно в цю екосистему для власника або диспетчера автопарку. За простим інтерфейсом «посмотреть де машина» скривається багаторівневий стек: протоколи телематичних блоків управління (ТБУ), серверна платформа, real-time API та складна бізнес-логіка трекінгу, алертів та аналітики.
Телематичний блок управління та протоколи
ТБУ (або AVL-трекер) — OBD-II або CAN-пристрій з GSM/LTE модемом, GPS-модулем та внутрішньою пам'яттю для буферизації. Популярні серії: Teltonika FMB (FMB920, FMB003, FMB125), Concox GT06N, Queclink GV500.
Дані з ТБУ йдуть на сервер по TCP у проприетарному бінарному протоколі. Teltonika Codec 8/8E — найпоширеніший:
Preamble (4 байти): 0x00000000
Data Field Length (4 байти)
Codec ID (1 байт): 0x08 (Codec8) або 0x8E (Codec8 Extended)
Number of Data (1 байт): кількість AVL-записів
[AVL records]
Number of Data (1 байт): повтор для перевірки
CRC-16 (4 байти)
Кожна AVL-запис: timestamp (8 байт Unix ms), GPS-дані (lat/lon/alt/angle/satellites/speed), IO Elements (батарея, запалювання, пробіг, входи/виходи, CAN-дані).
Парсинг на сервері (Go):
type AVLRecord struct {
Timestamp time.Time
Longitude float64
Latitude float64
Altitude int16
Angle uint16
Satellites uint8
Speed uint16
IOElements map[uint16]int64
}
func parseAVLRecord(r *bufio.Reader) (AVLRecord, error) {
var rec AVLRecord
var tsMs uint64
binary.Read(r, binary.BigEndian, &tsMs)
rec.Timestamp = time.UnixMilli(int64(tsMs))
var priority uint8
binary.Read(r, binary.BigEndian, &priority)
// GPS Element: lon(4), lat(4), alt(2), angle(2), sat(1), speed(2)
var lonRaw, latRaw int32
binary.Read(r, binary.BigEndian, &lonRaw)
binary.Read(r, binary.BigEndian, &latRaw)
rec.Longitude = float64(lonRaw) / 10_000_000.0
rec.Latitude = float64(latRaw) / 10_000_000.0
// ... решта полів
return rec, nil
}
Серверна платформа: Traccar або своя
Traccar — open-source платформа, знає 200+ протоколів трекерів, надає REST API та WebSocket. Оптимальний вибір для стартапів та середніх автопарків.
Traccar REST API для мобільного клієнта:
interface TraccarApi {
@GET("devices")
suspend fun getDevices(@Query("groupId") groupId: Long? = null): List<Device>
@GET("positions")
suspend fun getLatestPositions(
@Query("deviceId") deviceId: Long? = null
): List<Position>
@GET("reports/trips")
suspend fun getTrips(
@Query("deviceId") deviceId: Long,
@Query("from") from: String, // ISO 8601
@Query("to") to: String,
): List<Trip>
@GET("reports/events")
suspend fun getEvents(
@Query("deviceId") deviceId: Long,
@Query("from") from: String,
@Query("to") to: String,
@Query("type") types: List<String>,
): List<Event>
}
Real-time позиції — WebSocket Traccar (wss://server/api/socket):
class TraccarLiveSession(private val baseUrl: String, private val sessionCookie: String) {
fun observe(): Flow<TraccarMessage> = callbackFlow {
val client = OkHttpClient.Builder()
.readTimeout(0, TimeUnit.MILLISECONDS)
.build()
val ws = client.newWebSocket(
Request.Builder()
.url("wss://$baseUrl/api/socket")
.header("Cookie", "JSESSIONID=$sessionCookie")
.build(),
object : WebSocketListener() {
override fun onMessage(webSocket: WebSocket, text: String) {
trySend(Json.decodeFromString(text))
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
close(t)
}
}
)
awaitClose { ws.close(1000, null) }
}
}
Карта автопарку з живими маркерами
Google Maps SDK — стандарт для Android, MapKit для iOS, Mapbox або Yandex MapKit для російського ринку (Google Maps недоступен в деяких регіонах).
Маркери транспортних засобів з анімацією переміщення між позиціями:
private fun updateVehicleMarker(position: Position) {
val latLng = LatLng(position.latitude, position.longitude)
val existing = vehicleMarkers[position.deviceId]
if (existing == null) {
vehicleMarkers[position.deviceId] = map.addMarker(
MarkerOptions()
.position(latLng)
.icon(getVehicleIcon(position.attributes["ignition"] as? Boolean ?: false))
.rotation(position.course.toFloat())
.flat(true) // маркер обертається разом з картою
)!!
} else {
// Плавна анімація переміщення
ValueAnimator.ofFloat(0f, 1f).apply {
duration = 1000
interpolator = LinearInterpolator()
val from = existing.position
addUpdateListener { anim ->
val f = anim.animatedFraction
existing.position = LatLng(
from.latitude + (latLng.latitude - from.latitude) * f,
from.longitude + (latLng.longitude - from.longitude) * f
)
existing.rotation = position.course.toFloat()
}
}.start()
}
}
Кластеризація для автопарків з > 50 машин: ClusterManager з Maps SDK Utilities. Без кластеризації карта з сотнями маркерів лагає — у GoogleMap внутрішнє обмеження на кількість маркерів без кластеризації.
Історія поїздок та геозони
Трек поїздки — Polyline по списку GPS-точок. Ломана лінія кольорова по швидкості (зелений/жовтий/червоний) дає миттєве візуальне розуміння манери їзди:
fun drawSpeedColoredRoute(points: List<Position>) {
points.zipWithNext().forEach { (from, to) ->
val color = when {
to.speed > speedLimitKph -> Color.RED
to.speed > speedLimitKph * 0.8 -> Color.YELLOW
else -> Color.GREEN
}
map.addPolyline(
PolylineOptions()
.add(LatLng(from.latitude, from.longitude))
.add(LatLng(to.latitude, to.longitude))
.color(color)
.width(4f)
)
}
}
Геозони — полігони на карті, при перетинанні яких сервер генерує события. Створення геозони з мобільного додатку: рисуємо полігон тапами на карті, відправляємо список координат в Traccar Geofences API. Прив'язка пристрою до геозони через notificationTypes (geofenceEnter, geofenceExit).
CAN-дані та розширена телематика
Через OBD-II порт або прямое підключення до CAN-шини (ТБУ типу Teltonika FMB003 з CAN-адаптером) отримуємо: рівень топлива, пробіг з ЕКУ (точніше одометра), обороти двигуна, навантаження, коди помилок DTC, температуру охолоджувальної рідини.
Ці дані приходять в IOElements AVL-записи за заздалегідь сконфігурованими IO ID. Для Teltonika: IO ID 12 = ignition, ID 67 = CAN speed, ID 82 = CAN fuel level. Маппінг IO ID → параметр зберігається на сервері, мобільний клієнт отримує вже іменовані поля.
Сповіщення та алерти
Алерти налаштовуються на сервері (Traccar Notifications → по типам подій) та доставляються через FCM або APNS. Типові алерти автопарку:
- перевищення швидкості > X км/ч
- виїзд з геозони в нерабочий час
- тривала стоянка з включенним двигуном (витрата впрасну)
- розрядка акумулятора (< 11.8 В)
- різке гальмування / прискорення (з даних акселерометра ТБУ)
- втрата зв'язку з пристроєм > 5 хвилин
На мобільному клієнті — стрічка алертів з фільтруванням по типу та пристрою, перехід до карти з позицією в момент события.
Звіти
Звіти по пробігу, поїздкам, простоям, топливу — формуються на сервері (Traccar Reports API), у мобільному додатку відображаються та експортуються в PDF/Excel. Генерація PDF через пакет pdf Flutter або через серверний endpoint.
Розробка мобільного додатку для автопарку з картою, real-time позиціями, історією поїздок та алертами на основі Traccar: 8–12 тижнів. Кастомна телематична платформа з CAN-даними, розширеною аналітикою та білим лейблом: 4–6 місяців. Вартість розраховується індивідуально після аналізу парку трекерів та бізнес-вимог.







