1. Обзор API
Данный API предназначен для мобильного приложения “Battery Wizard”, используемого инженерами для проведения технического обслуживания аккумуляторных батарей на объектах. API реализует взаимодействие приложения с сервером: проверку актуальной версии приложения, авторизацию пользователей, получение новостных сообщений, загрузку результатов измерений и другие функции. Все обмены данными выполняются в формате JSON[^1], передача осуществляется по протоколу HTTPS с использованием методов HTTP[^2] (GET или POST в зависимости от типа запроса). Базовый URL для обращений к API: https://api.batterywizard.ru/api/v1/ (в данной документации описаны методы версии v1).
Аутентификация: Для доступа к защищенным методам API применяется токен[^3] сессионной авторизации. Пользователь получает токен при входе в систему (см. раздел 2.1) и должен указывать его при последующих запросах (в виде параметра token). Сервер проверяет валидность токена для каждого запроса и возвращает код ошибки 403 при отсутствии доступа. Токен представляет собой строку длиной 12 символов, генерируемую случайным образом при каждом входе пользователя. Для каждой комбинации пользователя и устройства (идентифицируемого UUID[^4]) поддерживается один актуальный токен: при повторной авторизации с того же устройства предыдущий токен переносится в архив и заменяется новым[1][2].
Формат ответов: Все ответы методов содержат стандартные поля статуса: флаг успешности ok (булево значение), числовой code статуса HTTP (200 при успехе, либо код ошибки) и текстовое поле message с описанием ошибки (пустая строка при успешном запросе)[3]. Дополнительные данные возвращаются в отдельных полях, специфичных для каждого метода (подробно описаны в соответствующих разделах). Ниже приведён пример общего формата ответа при успешном запросе:
{
«ok»: true,
«code»: 200,
«message»: «»,
«…»: «…»
}
Коды ошибок, используемые API: 400 – ошибка клиента (например, неверные параметры запроса или конфликт данных), 403 – доступ запрещён (например, отсутствует или неверен токен), 500 – внутренняя ошибка сервера (например, сбой при работе с базой данных). Клиентскому приложению рекомендуется обрабатывать поле code и при значениях, отличных от 200, отображать пользователю сообщение из поля message (если оно не пустое).
1.1. Требования к запросам
Для всех запросов к API требуется указать параметр api, идентифицирующий версию или ключ API (например, api=v1 или другой согласованный идентификатор). Этот параметр должен присутствовать в URL запроса (для GET) либо в теле JSON (для POST). При его отсутствии сервер отклонит запрос с кодом 403 (доступ запрещён). Также необходимо указывать корректный заголовок Content-Type: application/json для запросов с телом в формате JSON – ответы сервера всегда возвращаются с MIME-типом JSON[4].
2. Аутентификация и сессия
Функции аутентификации позволяют приложению зарегистрировать пользователя в системе и получить токен доступа, а также проверять действительность текущей сессии пользователя. Эти методы обеспечивают контроль доступа к остальным (закрытым) функциям API.
2.1. Запрос авторизации (Login)
URL: /api/v1/user/auth
Метод: POST (принимаются данные формы или JSON)
Данный метод выполняет вход пользователя в систему по его учетным данным. Необходимо передать логин пользователя и пароль, а также идентификатор API. Optionally, the client application can also provide device-specific parameters. Параметры запроса:
- api – строка с версией или ключом API (обязательный параметр).
- login (или альтернативно username) – имя пользователя для входа.
- password – пароль пользователя в открытом виде (API принимает соединения по HTTPS, что обеспечивает шифрование).
- uuid – опционально: уникальный идентификатор устройства (например, UUID мобильного устройства). Если передан, сервер использует его для привязки токена к данному устройству.
- os – опционально: название операционной системы устройства (например, «Android» или «iOS»; по умолчанию «unknown»).
- version – опционально: версия приложения, из которой выполняется вход (например, «1.0.3»; по умолчанию «0.0.0»).
При вызове метода с указанными данными, сервер проводит проверку учетных данных. Если логин не найден, пароль неверен либо учетная запись пользователя отключена, запрос будет отклонён с кодом 403 и сообщением об ошибке («Access denied»). В случае успешной аутентификации сервер сгенерирует новый токен сеанса и вернёт JSON с параметрами пользователя. Ниже приведён пример ответа при успешном входе:
{
«ok»: true,
«code»: 200,
«message»: «»,
«token»: «NQpX7Dc4a9Bf»,
«name»: «user_example»,
«phone»: «+71234567890»,
«tariff»: «Standard»,
«tariffId»: 2,
«serial»: «SN12534734»,
«expired»: «31.12.2025»
}
Каждое поле содержит важную информацию о сессии пользователя:
- token – сессионный токен, который необходимо использовать для доступа к защищённым методам API. Это случайная строка длиной 12 символов (в примере: «NQpX7Dc4a9Bf»).
- name – имя пользователя (логин), под которым выполнен вход.
- phone – привязанный номер телефона пользователя (формат международный, может использоваться для идентификации инженера).
- tariff – наименование текущего тарифного плана или типа аккаунта пользователя (например, бесплатный или платный план).
- tariffId – числовой идентификатор тарифа в системе.
- serial – серийный номер измерительного прибора, закреплённого за пользователем (если применимо). В системе Battery Wizard каждому инженеру может соответствовать устройство для тестирования АКБ; его серийный номер отображается здесь для справки[5][6].
- expired – дата окончания действия текущей подписки или тарифа (формат ДД.ММ.ГГГГ). После этой даты доступ пользователя может быть ограничен, если не продлена подписка.
Если авторизация прошла успешно, сервер возвращает код 200 и заполненные поля, как показано выше[7]. Клиентское приложение должно сохранить выданный токен и использовать его для всех дальнейших запросов, требующих авторизации.
Примечание: Токен следует хранить в безопасном месте на устройстве (например, в защищённом хранилище) и не разглашать. При выходе пользователя из аккаунта токен можно считать недействительным (в текущей версии API нет отдельного метода «logout», токен просто перестаёт использоваться клиентом, а на сервере его можно аннулировать при необходимости).
2.2. Проверка статуса сессии (Status)
URL: /api/v1/user/status
Метод: GET (также допускается POST)
Данный метод служит для проверки валидности текущего сессионного токена и получения основной информации о профиле пользователя. Обычно приложение вызывает его при каждом запуске (если у него уже сохранён токен) или периодически, чтобы убедиться, что сессия ещё активна и не истекла подписка.
Параметры запроса:
- token – сессионный токен пользователя (строка), полученный при авторизации. Должен передаваться либо как параметр URL, либо в теле JSON-запроса.
Сервер проверяет, существует ли указанный токен и соответствует ли он активной сессии. Если токен не найден или недействителен, возвращается ответ с ok: false и кодом 403 (доступ запрещён), что означает необходимость повторного входа пользователя. При успешной проверке возвращается ответ аналогичный по структуре ответу метода авторизации: поля name, phone, tariff, tariffId, serial, expired и др. будут содержать актуальные данные профиля пользователя на момент проверки. Пример успешного ответа:
{
«ok»: true,
«code»: 200,
«message»: «»,
«token»: «NQpX7Dc4a9Bf»,
«name»: «user_example»,
«phone»: «+71234567890»,
«tariff»: «Standard»,
«tariffId»: 2,
«serial»: «SN12534734»,
«expired»: «31.12.2025»
}
Обратите внимание, что поле token в ответе дублирует отправленный токен, подтверждая его валидность. Приложение может сопоставить полученную информацию с локально сохранёнными данными пользователя (например, отображать имя/телефон, проверять срок действия подписки). Если code = 403, следует запросить повторную авторизацию у пользователя (вернуться к вызову метода 2.1). В случае кода 200 приложение может продолжать работу, используя текущий токен.
2.3. Механизм хранения токенов
На сервере система реализует комбинированное хранение токенов: в базе данных и файловой системе. Каждый выданный токен привязан к учетной записи пользователя и устройству. При авторизации вызывается функция, которая обновляет таблицу Tokens базы данных: если для данного пользователя уже существует запись с тем же UUID устройства, старая запись перемещается в таблицу Tokens_Log (архив токенов), после чего в таблице Tokens сохраняется текущий токен с отметкой времени входа[8][9]. Благодаря этому на одно устройство и одного пользователя приходится только один актуальный токен, что упрощает управление сессиями.
Помимо базы данных, токен сохраняется в виде файлов: для каждого токена создаётся файл /token/<TokenID>.txt, содержащий имя пользователя, а для каждого пользователя – файл с текущим токеном /session/<Username>.txt, содержащий идентификатор токена[10]. При обращении к защищённым методам (таким как status, pay, upload) сервер сначала проверяет наличие файла токена. Если файл не найден (например, токен несуществующий или был отозван), запрос сразу отвергается (код 403) без проверки в базе данных. Это решение ускоряет проверку прав доступа, снижая нагрузку на БД. Однако, основной источник правдивой информации остаётся база данных – при необходимости сервер может синхронизировать состояние сессий, сравнивая записи.
Разработчикам приложения важно знать, что токены в текущей версии API не имеют автоматического времени истечения сессии (expiry) на сервере, помимо ограничения по тарифу (expired). То есть, токен будет оставаться действительным, пока не отозван явно (например, при повторной авторизации на том же устройстве) или пока не истечёт срок действия тарифа пользователя. Поэтому приложению следует контролировать дату expired: если срок прошёл, можно предупредить пользователя о необходимости продления услуги (см. раздел 5). В дальнейшем возможна реализация серверной механики истечения токена (logout/таймаут сессии), но в данной версии этого нет.
3. Проверка обновления приложения
Мобильное приложение Battery Wizard при запуске должно проверять, актуальная ли у пользователя версия программного обеспечения. Для этого служит метод appdata, возвращающий номер актуальной сборки приложения на сервере.
URL: /api/v1/appdata
Метод: GET (публичный метод, не требует токена)
При вызове этого эндпоинта сервер возвращает JSON с текущим номером сборки (релиза) приложения, который установлен на сервере. Формат ответа очень простой:
{
«ok»: true,
«actualBuild»: 102
}
Поле actualBuild содержит целочисленное значение – номер сборки последней актуальной версии мобильного приложения[11]. Этот номер устанавливается на сервере вручную при каждом выпуске новой версии приложения. Механизм использования: при старте своего приложения вы должны выполнить запрос к /appdata и сравнить полученный номер с номером сборки текущей установленной версии приложения (в самой программе). Если значение actualBuild на сервере больше, чем версия у пользователя, значит выпущено обновление. В этом случае приложение должно уведомить пользователя и, например, предложить перейти на сайт за новой версией.
Примечание: Для удобства пользователей необходимо предусмотреть страницу на основном сайте (batterywizard.ru) или ином ресурсе, откуда можно скачать актуальную версию APK/приложения. API возвращает только номер версии; непосредственно ссылку для скачивания приложение должно знать заранее или получить из другого источника. Рекомендуется в диалоге обновления давать кнопку, открывающую браузер на страницу скачивания обновления.
Метод appdata возвращает ok: true даже если версия актуальна (сервер просто сообщает номер). Возможные ошибки при запросе этого метода могут быть связаны только с недоступностью сервера или внутренними проблемами; параметров он не требует, кроме стандартного api. Таким образом, приложение может безопасно вызывать его при каждом запуске без риска для данных пользователя.
4. Новости и оповещения
В приложении предусмотрен раздел новостей или оповещений, позволяющий доводить до сведения пользователей важную информацию: релизы, изменения в инструкциях, новые функции и т.п. Для получения этих данных с сервера служит метод news.
URL: /api/v1/news
Метод: GET (требуется активный токен сессии)
Параметры запроса:
- token – сессионный токен пользователя. Хотя текущая реализация сервера может вернуть новости и без токена, рекомендуется всегда передавать токен для удостоверения доступа. В будущих версиях API этот метод может требовать обязательную авторизацию.
Ответ: при успешном запросе возвращается JSON с массивом новостей. Поля ответа:
- ok – флаг успеха (true при удачном получении новостей).
- code – код 200 при успехе, либо код ошибки (например, 403, если токен недействителен).
- message – сообщение об ошибке или дополнительная информация. В случае успеха обычно содержит техническую метку или дату последнего обновления новостей (например, сервер может вернуть в message дату актуальности новостей). В тестовом примере ответ содержит строку «07.07.2023» в этом поле[12][13].
- news – массив объектов, каждая запись массива представляет одну новость.
Элементы массива news имеют следующие поля:
- title – заголовок новости (краткое название события)[14].
- date – дата публикации новости в формате ДД.ММ.ГГГГ[14].
- content – содержимое новости в формате HTML (может включать текст с форматированием, ссылки, списки и пр.)[15].
Пример фрагмента ответа с одной новостью:
«news»: [
{
«title»: «Запуск Beta версии Android приложения»,
«date»: «03.03.2025»,
«content»: «<div>3 марта состоялся запуск Beta версии нового Android приложения. Пользователи могут протестировать функционал и оставить свои отзывы…</div>»
},
{
«title»: «Обновление инструкции по эксплуатации»,
«date»: «05.03.2025»,
«content»: «<div>5 марта была опубликована обновленная инструкция по эксплуатации на сайте <a href=\»https://batterywizard.ru/conbat-rta-wizard-manual/\»>batterywizard.ru</a>…</div>»
}
]
В данном примере приведены две новости. Вторая новость иллюстрирует, что в поле content может содержаться HTML-разметка, в том числе ссылки (<a href=»…»>). Клиентскому приложению следует корректно отображать содержимое: либо в виде встроенного веб-контента, либо распарсив допустимый HTML (например, с помощью WebView или соответствующих компонентов). Если HTML не поддерживается, можно отфильтровать теги и показать простой текст, однако наличие ссылок означает, что пользователю может потребоваться переход на внешний ресурс (как в примере со ссылкой на инструкцию).
При возникновении ошибки (например, неправильный токен) поле news может отсутствовать, а поля ok будет false и message содержать описание проблемы. В обычных условиях, при правильно переданном токене, метод возвращает код 200 и список новостей (возможно пустой массив, если новостей нет).
5. Получение ссылки на оплату (Платежный виджет)
Если функциональность приложения предполагает платные тарифы или подписки, пользователям необходимо предоставить возможность оплаты. API Battery Wizard включает метод pay, который возвращает ссылку на платежный веб-виджет для проведения оплаты текущего пользователя.
URL: /api/v1/user/pay
Метод: POST (требуется авторизация токеном)
Параметры запроса:
- token – сессионный токен пользователя (строка).
Метод проверяет валидность токена и формирует ответ с URL платёжного сервиса. В случае успеха возвращается JSON со следующими полями[16]:
- ok – true (если токен принят и ссылка сформирована).
- code – 200 при успешном выполнении.
- message – пустая строка или сообщение (обычно не используется при успехе; в тестовой реализации пусто).
- url – строка, содержащая URL платёжного виджета.
Пример успешного ответа:
{
«ok»: true,
«code»: 200,
«message»: «»,
«url»: «https://ecomtest.sberbank.ru/ecomm/gw/partner/api/v1/»
}
Значение url указывает адрес, по которому доступен платежный интерфейс для пользователя. В приведённом примере указан тестовый стенд Сбербанка (URL для тестовой среды)[17][18]. В боевом окружении здесь будет рабочий URL платёжной системы. Приложению следует открыть данный адрес либо во встроенном браузере (WebView), либо во внешнем браузере устройства, чтобы пользователь смог ввести платёжные данные и завершить транзакцию. По завершении оплаты (успешной или неуспешной) платёжный виджет обычно перенаправит пользователя на указанный в настройках магазина URL успеха/неудачи. Обработка результата оплаты (например, обновление статуса подписки пользователя) происходит на стороне сервера; мобильному приложению достаточно отобразить веб-страницу оплаты и при необходимости узнать результат (например, опросом сервера или получением уведомления).
В случае, если токен недействителен или у пользователя нет прав для проведения оплаты, сервер вернёт ok: false с кодом 403 и сообщением об ошибке («Forbidden»). Такое может случиться, например, если истёк срок сессии или аккаунт не требует оплаты. Приложению в этом случае следует предложить повторно войти или сообщить, что оплата не требуется.
Примечание: Метод pay не выполняет самих финансовых операций, а лишь предоставляет ссылку. Безопасность платежей обеспечивается сторонним виджетом (банковским или иным). Убедитесь, что переходите по защищённому протоколу HTTPS и проверяете сертификаты при интеграции веб-контента, чтобы исключить перехват данных.
6. Загрузка результатов измерений (Upload)
Одной из ключевых возможностей приложения является передача на сервер результатов измерений, полученных инженером при проверке аккумуляторных батарей. Эти данные могут содержать файлы отчётов с приборов, фотографии и другие файлы небольшого размера. Для этого предназначен метод upload, позволяющий отправить файл на сервер для сохранения и последующей обработки.
URL: /api/v1/user/upload
Метод: POST (требуется авторизация)
Данный метод ожидает загрузку файла (обычно в формате, специфичном для результатов измерения) вместе с токеном пользователя. Поддерживается два варианта отправки: — Multipart/form-data: через веб-форму с полем файла. — Raw JSON: отправка файла в виде закодированных данных (например, Base64) в параметре JSON.
Чтобы упростить интеграцию, рекомендуется использовать multipart-запрос, так как он поддерживается большинством HTTP-клиентов при отправке файлов.
Параметры запроса:
- token – токен сессии (строка). Можно передать как поле формы (в multipart) или как часть JSON.
- upload_file – файл, прикреплённый к запросу (в multipart-запросе). Имя поля должно быть именно upload_file (так ожидает серверный код). Либо, как альтернатива, можно использовать имя поля file – сервер обработает и такой вариант для обратной совместимости.
- Если используется JSON: параметр file может содержать содержимое файла в виде строки (например, Base64-представление). Однако, практичнее использовать multipart, чтобы не перегружать JSON.
Форматы файлов: сервер допускает загрузку файлов следующих типов: RTA, PDF, TXT, FBO[19]. Эти расширения должны быть в имени файла; иные типы будут отклонены. Расширения RTA и FBO относятся к специализированным форматам тестовых данных оборудования (например, результаты измерений в собственном формате приборов). PDF и TXT могут использоваться для отчётов или сопутствующей информации. Имя файла на устройстве может быть произвольным, но важно наличие правильного расширения.
Ограничения размера: файл не должен быть слишком маленьким или слишком большим. Сервер отвергает файлы размером менее 5 байт и более ≈80 КБ (80 000 байт)[20]. Таким образом, минимальный содержательный файл – 5 байт, максимальный – ориентировочно 0,08 МБ. Попытка отправить файл большего размера приведёт к ошибке. Примечание: ограничение по максимальному размеру может быть изменено в конфигурации сервера; текущий порог взят исходя из ожидаемых размеров текстовых файлов результатов измерений. Если в будущем потребуется передавать файлы большего объёма (например, фотографии), возможно появление отдельного метода или увеличение допустимого лимита.
Обработка данных: при получении файла сервер осуществляет следующие действия: 1. Проверяет наличие токена и находит соответствующего пользователя (если токен невалиден – ответ 403 Forbidden). 2. Принимает файл: если файл не был фактически прикреплён или передан (например, забыли поле или файл пустой), то сохранит вместо него служебный файл с надписью «Empty data» и информацией о среде запроса (для отладки). В нормальной ситуации файл должен быть непустым. 3. Формирует уникальное имя для сохранения файла на сервере. Имя генерируется на основе текущей даты/времени и расширения файла. Например, файл может быть сохранён как 2025-08-22_10_51_55.RTA. Все загруженные файлы пользователей сохраняются в персональные директории на сервере (путь /upload/<Username>/), недоступные напрямую из веба (доступ осуществляется только через программные методы или панели для администраторов). 4. Проверяет, существует ли точно такой же файл у данного пользователя, чтобы избежать дублирования. Для этого вычисляется CRC32[^5] хэш содержимого файла и сверяется с базой данных: если уже есть запись с таким хешем и именем, сервер может распознать файл как дубликат ранее загруженного. 5. Сохраняет запись о файле в базе данных. В базе предусмотрены две связанные таблицы: — File – хранит информацию об уникальных файлах (имя, расширение, системный путь, веб-путь, размер, CRC32 и т.д.). Вставка в нее производится по принципу ON DUPLICATE KEY UPDATE, то есть если файл с таким CRC уже был, обновляются метаданные; иначе создаётся новая запись[21][22]. — Files – хранит информацию о загрузках/измерениях, привязанных к пользователю и оборудованию. Каждая запись в этой таблице ссылается на запись в File. Сюда добавляются поля, связанные с контекстом измерения: время создания (загрузки), ID пользователя, ID компании и тестера (если применимо), а также дата/время теста, извлечённая из имени файла (если имя содержит метку времени)[23][24].
- Если файл успешно сохранён и записи обновлены, сервер инициирует автоматический разбор содержимого файла. В системе Battery Wizard реализован отдельный скрипт на языке Perl[^6], который занимается парсингом файлов формата RTA/FBO и извлечением данных измерений. Сразу после загрузки файл ставится в очередь на обработку: вызывается функция runPerlScript для нового файла[25]. Скрипт анализирует файл, заполняет в базе подробные результаты (например, поклеточные напряжения, длительности, ёмкости и т.д.), которые потом могут использоваться в отчетах. Этот процесс выполняется асинхронно, но запуск происходит во время вызова upload. В ответе метода результат парсинга напрямую не возвращается, однако при отладке лог сохраняется на сервере (stdout скрипта).
- Формируется ответ клиенту о результате загрузки.
Ответ сервера: Если все этапы прошли успешно, клиент получает подтверждение с кодом 200. Пример успешного ответа:
{
«ok»: true,
«code»: 200,
«message»: «Uploaded»,
«id»: «12345»
}
Поле id – это идентификатор новой записи о загрузке в системе (ID из таблицы Files). Его можно рассматривать как уникальный номер измерения/отчёта. В дальнейшем (при появлении соответствующих методов) по этому идентификатору можно будет запросить детали результатов измерения, сгенерировать отчёт и пр. Пока что приложение может не использовать это значение, кроме как для внутренней проверки. Главное – факт получения ответа с ok: true означает, что файл успешно сохранён и поставлен в обработку[26].
Если произошла ошибка на каком-либо этапе, поведение следующее: — При известной ошибке входных данных (например, отсутствует файл, недопустимое расширение, неподходящий размер) сервер возвращает ok: false с кодом 400 или 403, а поле message содержит описание проблемы (на английском языке). Например, для слишком большого файла придёт сообщение «Invalid file size … Allowed size is between 5 and 80000 bytes.»[20], для неподдерживаемого расширения – «Invalid file extension ‘XYZ'». Эти сообщения помогут разработчику или продвинутому пользователю понять причину отказа.
— При сбое на сервере (например, ошибка базы данных во время сохранения) сервер вернёт ok: false с кодом 500 и сообщением «Database error: …»` с техническим текстом ошибки. В обычной работе такие ситуации маловероятны, но их нужно обработать (отобразить пользователю общее сообщение о неудаче загрузки).
— При неверном токене – 403 Forbidden (как и в других защищённых методах). Это указывает на необходимость повторной авторизации.
Разработчику следует предусмотреть вывод пользователю понятных сообщений на основе поля message. Например, при ошибке расширения сказать: «Недопустимый формат файла. Разрешены: RTA, PDF, TXT, FBO», при ошибке размера: «Файл слишком большой/маленький» и т.п., возможно, локализовав сообщение. Также стоит учитывать, что успех загрузки не гарантирует мгновенной обработки – она может занять несколько секунд. Если в приложении требуется подтверждение обработки, можно реализовать индикатор или запрос состояния (отдельным методом, которого пока нет, либо ожиданием). В текущей версии можно считать, что если upload вернул ok:true, сервер принял файл и выполнит все необходимые действия.
7. Глоссарий
[^1]: JSON (JavaScript Object Notation) – текстовый формат обмена данными, широко используемый в веб-сервисах. В JSON данные представлены в виде пар «ключ: значение» и поддерживаются структуры массивов и вложенных объектов. В контексте данного API все запросы и ответы формируются в формате JSON.
[^2]: HTTP (HyperText Transfer Protocol) – протокол передачи гипертекста, лежащий в основе взаимодействия веб-клиента и сервера. Методы HTTP, упоминаемые в документе (GET, POST), определяют тип запроса: получение данных или отправка (соответственно). Код ответа HTTP (например, 200, 403) указывает результат обработки запроса.
[^3]: Токен (token) – уникальная строка, служащая маркером авторизованной сессии пользователя. Предоставляется сервером при успешной аутентификации и используется клиентом для подтверждения своего статуса в дальнейших запросах. Токен в API Battery Wizard состоит из 12 случайных символов и ассоциирован с конкретным пользователем (и его устройством).
[^4]: UUID (Universally Unique Identifier) – универсально уникальный идентификатор, 128-битное число, представленное в виде строкового формата. Часто используется для идентификации устройств, сессий и т.п. В данном API ожидается, что приложение при авторизации передаст UUID устройства, чтобы сервер мог различать авторизации с разных устройств одного пользователя.
[^5]: CRC32 – алгоритм вычисления контрольной суммы (хэша) для данных, выдающий 32-битное значение. Используется для быстрой проверки идентичности данных. В API Battery Wizard CRC32 используется для определения дубликатов файлов: если два файла имеют одинаковый CRC32, они, вероятно, идентичны по содержанию.
[^6]: Perl – высокоуровневый язык программирования, часто используемый для текстового парсинга и администрирования. В системе Battery Wizard скрипт на Perl применяется для обработки загруженных файлов измерений, извлечения данных и заполнения базы данных. Такая архитектура выбрана, вероятно, из соображений повторного использования существующих парсеров или удобства работы с форматом файлов результатов измерений.
[2] wizard_online_structure.sql
