Нашим инспекторам, осматривающим автомобили при их приёмке на аукцион, условия выбирать не приходится — они работают и в дождь, и в снегопад, и в летнюю жару. Они не просто тщательно осматривают автомобиль, но и заполняют сотни пунктов чек-листов, снимают десятки, а то и сотни фотографий, записывают видео. И всё это без пачки бумаг, фотоаппарата и камеры, а с помощью одного лишь смартфона и нашего специального приложения. Недавно мы даже защитили патентом нашу систему осмотра автомобилей. Под катом — рассказ с подробностями.
Когда к нам приезжает человек, желающий продать свой автомобиль, нужно провести подробный осмотр машины, зафиксировать комплектацию, повреждения и скрытые дефекты, а также проверить её юридическую чистоту. Этим занимаются инспекторы — специально подготовленные специалисты по автомобилям в филиалах CarPrice: по чек-листам из нескольких сотен пунктов они внимательно осматривают автомобиль, фотографируют все найденные дефекты, снимают на видео, чтобы можно было послушать звук мотора, вводят все необходимые учётные данные. Поскольку автомобиль нужно сфотографировать со всех возможных сторон и ракурсов, порой неожиданных, изначально для инспекторов были закуплены iPad Mini первого поколения: вышло относительно недорого, с неплохой камерой и достаточно большим экраном. На планшетах инспекторы заходили в веб-интерфейс нашего внутреннего сервиса, куда и заносили все данные.
Но инспекторы не всегда работают в комфортных условиях отапливаемых офисов с Wi-Fi, зачастую автомобили осматривают на открытых площадках, за городом, на территории продавца, в отдалённых регионах, где и обычная сотовая связь может быть нестабильной. Веб-приложения любят тепличные условия, а инспектору нужна мобильность, да и неудобно было через такой интерфейс заливать большой объём фото и видео. И поскольку даже Wi-Fi не всегда ловится за пределами офиса, сотрудникам приходилось выполнять двойную работу, бегая от автомобилей в офис, чтобы сбросить материалы сначала на рабочую станцию, а потом заливать их на веб-сервис.
Мы решили разработать полноценное мобильное приложение, которое сделает процесс осмотра строго формализованным, универсальным для всех сотрудников и предсказуемым по времени. Ну и ускорит процедуру осмотра, чтобы владелец авто не ждал долго, в нетерпении поглядывая на часы.
Выбор архитектурного паттерна
Приложение изначально должно было быть этаким «швейцарским ножом», чтобы инспектор мог осмотреть автомобиль и внести всю информацию о нём, не выходя из приложения. По нашей задумке, при осмотре должны были:
- Параллельно выполняться целый ряд ресурсоемких процессов, таких как: работа с файлами, захват фото и видео, обработка медиаданных (фото, видео, аудио), взаимодействие с хранилищем данных, сетью и внешними сервисами.
- Генерироваться многочисленные данные, объединенных в комплексные сущности. Эти сущности мы планировали хранить локально и редактировать на лету, они должны быть доступны в онлайн- и офлайн-режиме.
Изучив багаж знаний человечества, мы остановились на реактивном подходе с RxJava. Нам нужно было создавать подписки на изменение данных и зависимостей, надёжно связать динамически создаваемые визуальные компоненты чек-листа и данные, формат которых был строго формализован.
Так что, в нашем случае, базовый архитектурный паттерн MVVM был наилучшим выбором, потому что он обеспечивает двустороннее взаимодействие моделей с визуальными элементами, а любое изменение визуальной части мгновенно фиксируется и обновляется в БД. Для повышения гибкости разработки решили использовать Dependency Injection, популярный в последнее время, закрыв глаза на некоторую потерю прозрачности и увеличение порога входа. В результате нам удалось внутри фронтенда построить четко синхронизированную систему взаимодействия с визуальной частью, систему фоновой обработки большого количества данных, а также механизм обмена данными между приложением и бэкендом.
Мобильное приложение напрямую взаимодействует только с двумя узлами:
- с серверной частью посредством собственного API. В основе лежат принципы REST. Серверная часть сильно разветвлённая, она обращается к дополнительных сервисам (для юридической проверки, для изменения размеров изображений и видео, для обработки фотографий с помощью нейросети и так далее), получает от них данные и отдаёт клиентам;
- с AmazonAWS для выгрузки медиа-файлов с последующей синхронизацией через API-методы.
От начала разработки до запуска первой версии прошло 2,5 месяца. Изначально бэкенд писала наша команда, а альфа-версия самого клиента создавалась компанией, специализирующейся на мобильной разработке. К сожалению, задача оказалась слишком сложной, чтобы доверить её незнакомым людям, и мы собрали свою команду, которая смогла сделать полноценное приложение для осмотра и выставления авто на торги.
А теперь подробнее о некоторых аспектах устройства и работы приложения.
Выбор смартфона
Мы решили отказаться от планшетов в пользу смартфонов. На то было несколько причин. Во-первых, в планшетах камеры обычно хуже, чем в дорогих смартфонах, а качество съёмки было ключевым фактором, ведь встречают по одёжке — потенциальные покупатели оценивают лот по фотографиям. И во-вторых, планшеты гораздо больше по размеру, из-за чего инспекторы часто роняли и разбивали их. Когда инспектор осматривает машину, то с собой у него:
- Фонарик.
- Салфетки для протирания загрязнённых деталей.
- Толщиномер для измерения лакокрасочного покрытия.
- Сканер OBD
Всё это должно быть под рукой, инструменты нередко висят на запястьях на петельках. К тому же инспектор может быть в перчатках, нитяных или утеплённых, подходящих для работы с емкостными экранами. Чтобы всем этим пользоваться, заполнять чек-листы и не ронять ощутимо стоящий девайс, нужно иметь на одну-две руки больше.
А раз мы решили перейти на смартфоны, то и интерфейс будущего приложения нужно было адаптировать для экранов соответствующего размера. Устройство для наших инспекторов мы выбирали по таким критериям:
- Самое главное — качество съёмки.
- Батарейка.
- Защитные чехлы.
- Работа в диапазоне температур от +30 до -50.
- Чтобы SDK поддерживалось и развивалось.
- Чтобы была влагозащита, потому что иногда машины приезжают в дождь.
Изучили рейтинги и обзоры смартфонов на сайтах вроде www.techradar.com и www.cnet.com, проанализировали параметры и купили несколько разных моделей. Потом начали придирчиво тестировать их возможности по фото- и видеосъёмке. Проверяли работу автофокусировки при плохом освещении, во время осадков. Проводили слепые тесты по результатам съёмки. Изучали размер получающихся фотографий и видеозаписей, уровень шумов на матрице. Проверяли надёжность: роняли, замораживали, поливали водой и вообще всячески издевались, чтобы выбрать действительно сильнейшего.
Всю полосу препятствий прошёл только Sony Z3. К слову, для него выпускалось больше антивандальных чехлов, чем для других рассматривавшихся нами смартфонов.
Камера
Учитывая объём работы с фото и видео, сразу было понятно, что функциональности стандартной камеры нам не хватит. Как минимум, её интерфейс надо гармонично встроить в наше приложение, иными словами — написать новый. Поэтому мы разработали своё решение на основе модуля Camera из Android SDK.
Инспектор фотографирует строго по чек-листу. Поскольку не все рождаются фотографами, приложение выводит подсказки, как нужно держать смартфон — вертикально или горизонтально. Не выходя из интерфейса камеры, инспектор может перейти к съёмке следующей детали автомобиля.
Также мы реализовали систему подсказок при съёмке определённых деталей. Например, когда инспектор фотографирует VIN, тот дополнительно выводится текстом, чтобы инспектор мог сразу посмотреть, всё ли в порядке. Также на фото размываются номера автомобиля, выводятся стикеры и так далее.
Когда мы начали снимать видео работы двигателя и выхлопной системы, то столкнулись с тем, что на аппаратном уровне в прошивке Sony Z3 не предусматривалась смена разрешения. Видеоролики писались только в стандартном разрешении, прописанном в SDK Sony — Full HD, 60 кадров/сек. И хотя мы использовали свой собственный кодек, одноминутный файл занимал 100—150 Мб. Естественно, это сказывалось на скорости передачи по сети, особенно на 3G. И SDK никак не позволял аппаратно обратиться к модулю камеры. Пришлось помучиться, перепробовали несколько разных решений постпроцессинга, включая декодирование на лету перед отправкой, подбирали битрейт и фреймрейт. Постпроцессинг занимал мало времени, но «кушал» очень много батарейки и утяжелял приложение. Мы безуспешно боролись с этим до тех пор, пока Sony не вняла пользовательским мольбам и не выпустила обновление, в котором можно менять разрешение видео.
Интерфейс и безопасность
Формализованное описание состояния транспортного средства — задача не такая простая. Ведь через наш аукцион могут продаваться не только легковые автомобили, но и мотоциклы, и квадроциклы, и мопеды, и даже грузовики. Очевидно, что у каждого класса свои технические особенности. Поэтому мы сформировали три типа чек-листов: элементы конструкции и агрегаты транспортного средства, комплектация и повреждения. Эти чек-листы — краеугольный камень приложения, ради них всё и затевалось.
Чтобы не писать отдельную вёрстку для каждой модели автомобиля, интерфейс должен формироваться «на лету» на основании чек-листа, в зависимости от типа осматриваемого транспортного средства. Для этого мы сделали конфигурационные файлы, актуальная версия которых единовременно подгружается при запуске клиента. На основе этих файлов динамически генерируется интерфейс чек-листов для конкретного автомобиля. Также мы написали набор бизнес-логики, которая при переходе на определенный этап заполнения информации об автомобиле берёт структуру данных из конфигурационного файла и на её основе динамически генерирует наборы полей. В структуре данных конфигурационных файлов указан не только набор, количество и типы полей для заполнения, но и зависимости между этими полями. То есть когда инспектор заполняет чек-лист, при изменении какого-то параметра могут появиться дополнительные поля.
Например, если в поле «Тип транспортного средства» выбрать «автомобиль», то появится поле для выбора усилителя руля, которое не появится для мотоцикла. Естественно, при смене верхнего уровня зависимости — например, мы заполняли встречу про ВАЗ-2109, и вдруг решили выбрать Harley-Davidson, — интерфейс перестраивается.
Это дает огромное пространство для маневра. Например, чтобы изменить порядок чек-листа или внести дополнительные опции не требуется даже изменять фронтенд. А значит, не нужно пересобирать приложение, выкладывать в маркет и возиться с прочими операциями. Для хранения конфигурационных файлов используется Realm ORM, по скорости чтения это одна из самых быстрых ORM.
В приложении достаточно необычная авторизация. Помимо того, что инспектор может войти в него только под своей учётной записью, он может это сделать только в своё рабочее время и только под своим филиалом.
Также партнёрам, которые хотят использовать наше приложение, мы передаём установочный APK-файл, потому что в Google Play приложение распространяется только для нашего корпоративного домена.
Бэкенд
Бекенд состоит из нескольких логических частей.
Генератор конфигурационных файлов: сервис, создающий файлы, на основе которых при запуске приложения генерируется пользовательский интерфейс.
Авточек: это отдельный сервис, в который из приложения инспектора посредством HTTP-запроса передаются данные о машине и владельце (VIN, СТС, ПТС, регистрационный номер, ФИО владельца и так далее). «Авточек» автоматически проверяет эти данные в различных сервисах, которых на сегодня около 15 штук (Автокод, ГИБДД, AVInfo, ФМС, ФНП и др.), делает скриншоты каждой проверки и сохраняет информацию о количестве штрафов, их суммам, ограничениях на регистрационные действия, соответствии VIN-номера ПТС, участии авто в ДТП, пробеге на момент последнего ТО. Буквально через минуту инспектор получает полный отчет об автомобиле. Если машина «проблемная», инспектор может отказать в дальнейшем осмотре и распрощаться с продавцом.
Звезды: это сервис автоматической оценки автомобиля по четырём категориям (Кузов, Салон, Техническое состояние, Сопутствующие факторы). Для каждой из них настроены правила оценки от 1 до 5 звезд. Все категории, кроме «Сопутствующих факторов», рассчитываются исходя из количества и степени повреждений. Сопутствующие же факторы оцениваются по таким параметрам, как количество хозяев по ПТС, на гарантии ли автомобиль, есть ли сервисная книжка, какой пробег и тому подобное. Суммарно автомобиль может заработать не более 20 звёзд (по 5 в каждой категории). Большая часть лотов имеет от 10 до 15 звёзд, крайне редко на аукцион попадают «убитые» машины с 9 звёздами и меньше. Свыше 15 — это практически идеальное состояние, такие автомобили входят в топовый рейтинг аукциона.
Все фоновые задачи и процессы — проверки, подгрузка и отправка данных, — реализованы в виде отдельных, асинхронно обрабатываемых потоков. Благодаря паттерну Observer, который лежит в основе RX-компонентов, все эти данные собираются в одном месте. По мере выполнения всех задач мы всегда можем получить результат работы любого фонового потока.
Для работы с сетью у нас используется классическая связка Retrofit 2 + OkHttp 3. С одного осмотра получается 40—300 фотографий, да ещё и видео, всего около 300 Мб, так что по сети приходится передавать очень большие объёмы данных. Как вы понимаете, чем старее и потрёпанней автомобиль, тем больше получается фотографий, а для подавляющего большинства машин достаточно 70-150 снимков. Если машина совсем старая и «убитая», то она осматривается по упрощённой схеме, а повреждения просто не регистрируются.
Для хранения медиа-данных мы выбрали Amazon AWS. Поскольку бэкенд должен вовремя узнавать о новых файлах, то одновременно с загрузкой в хранилище на сервер отправляются уведомления с метаданными по каждому файлу.
Как уже говорилось, интернет при осмотре доступен не всегда. А уж быстрый интернет — чуть ли не роскошь. Поэтому приложение имеет оффлайн- и онлайн-режим работы. Пока связи нет, инспектора может спокойно собирать данные, заполнять формы, снимать фото и видео. Информация накапливается в базе данных на смартфоне. А как только сеть появляется, начинается поэтапная отправка данных через thread pool, асинхронно в несколько потоков, вне зависимости от того, какая доля чек-листов уже заполнена. И когда инспектор завершает осмотр и нажимает кнопку «Отправить», большая часть информации уже находится в хранилище. Для управления последовательностью задач и контроля их выполнения мы разработали набор инструментов JobQuery.
OBD (On-Board Diagnostic)
Давно прошли времена, когда автомобиль можно было починить с помощью одного лишь домкрата и набора ключей с отвёртками. Современные автомобили напичканы электроникой, в том числе датчиками системы OBD — это шина бортовой диагностики. И нам грех было не воспользоваться этим инструментом. Но в открытом доступе оказалось крайне мало технических материалов по OBD. Есть лишь несколько небольших open-source проектов, которые позволяют наладить базовое взаимодействие с разными OBD-модулями. Изначально мы и взяли за основу один из таких проектов, по ходу дела расширяя его возможности, хотя трудностей хватало с избытком.
Нет какого-то универсального протокола обмена данными, по которому можно диагностировать специфические ошибки (например, подушки безопасности), у каждого производителя свой протокол. Также используются дополнительные протоколы с метаданными, которые отличаются у разных марок. Даже один и тот же код ошибки у разных производителей может иметь разные значения. При таком бардаке нужно иметь информацию о базовом наборе кодов ошибок по каждому производителю, и в зависимости от того, какой автомобиль к тебе приехал, сопоставлять коды, модель и бренд.
Но когда мы начали опрашивать наших клиентов — автодилеров, — нужны ли им расшифровки кодов ошибок, то выяснилось, что они уже знают наизусть ключевые коды, и в зависимости от их содержания могут сами предположить, какие проблемы у автомобиля. Поэтому пока мы остановились на том, что будем предоставлять исключительно коды ошибок без расшифровки. Кстати, если кто знает мощную библиотеку для работы с obd2 — будем благодарны за информацию в комментариях!
Что в итоге?
Мобильное приложение сильно облегчило инспекторам жизнь. Настолько, что вместо 4 часов на осмотр одного автомобиля в среднем уходит 1—1,5 часа. Благодаря развитию чек-листов и системы подсказок инспекторы стали выявлять гораздо больше дефектов, то есть дилеры получают более точные описания состояния автомобилей. Наконец, инспекторы больше не привязаны к Wi-Fi и могут выезжать на осмотр буквально в любую точку мира.
Дальнейшие планы
С точки зрения развития архитектуры приложения мы сейчас работаем над унификацией справочников повреждений, чтобы быстро добавлять новые инструкции по осмотру транспортных средств без выпуска нового релиза приложения.
Также мы поддались моде и экспериментируем с использованием нейросети для постпроцессинговой обработки, чтобы выявлять недостаточно качественные фотографии, сделанные инспекторами. Конечно, нейросеть качество не улучшит, но, по крайне мере, сможет задним числом показать инспектору, где он не уследил за фокусировкой, чтобы в следующий раз был внимательнее. Глядишь, скоро искусственный интеллект начнёт учить инспекторов искусству композиции и работе со светом.
И третье направление по улучшению приложения: мы формируем базу знаний по особенностям и недостаткам конкретных моделей конкретных производителей. Например, у этой модели VIN на кузове расположен там-то, у другой модели с таким двигателем после определённого пробега начинают стучать клапаны, у третьей модели постоянно ржавеет крышка багажника, и тому подобное. Тогда инспектор, осматривая автомобиль, по которому есть такой набор данных, будет получать на разных этапах подсказки, на что нужно обратить внимание.
А ещё мы переходим на смартфоны Huawei. Sony Z3 уже не выпускается, и каким-бы надёжным он ни был, рано или поздно всё ломается. Так что после новой итерации чтения обзоров и варварских тестов мы выбрали Huawei P10 Lite.
Автор: Сергей Ставицкий