Обновить API
193
API.md
193
API.md
@@ -11,6 +11,7 @@
|
|||||||
3. [Настройки графика и работы экскаватора](#device_settings)
|
3. [Настройки графика и работы экскаватора](#device_settings)
|
||||||
4. [Аналитика и Цифровой двойник](#analytics)
|
4. [Аналитика и Цифровой двойник](#analytics)
|
||||||
5. [Видеоархив, Карты и Очистка данных](#video_archive)
|
5. [Видеоархив, Карты и Очистка данных](#video_archive)
|
||||||
|
6. [Подробные примеры использования API (с ответами и их интерпретацией)](#examples)
|
||||||
---
|
---
|
||||||
|
|
||||||
<a name="auth"></a>
|
<a name="auth"></a>
|
||||||
@@ -126,3 +127,195 @@ requests.post(f"{BASE_URL}/devices/{device_id}/schedule-exceptions/", headers=he
|
|||||||
| `POST`| `/devices/<device_id>/clear-data/` | **Опасная операция.** Очистка данных устройства. JSON: `{"mode": "all"}` или `{"mode": "date", "date": "..."}`. |
|
| `POST`| `/devices/<device_id>/clear-data/` | **Опасная операция.** Очистка данных устройства. JSON: `{"mode": "all"}` или `{"mode": "date", "date": "..."}`. |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<a name="examples"></a>
|
||||||
|
## 6. Подробные примеры использования API (с ответами и их интерпретацией)
|
||||||
|
|
||||||
|
Ниже приведены расширенные примеры того, как обращаться к эндпоинтам и как правильно читать возвращаемые данные.
|
||||||
|
|
||||||
|
### Пример 6.1: Получение информации об устройстве и его настройках
|
||||||
|
|
||||||
|
**Запрос (Python):**
|
||||||
|
```python
|
||||||
|
# Получаем базовую информацию об экскаваторе
|
||||||
|
response = requests.get(f"{BASE_URL}/devices/43/", headers=headers)
|
||||||
|
device_data = response.json()
|
||||||
|
|
||||||
|
# Получаем настроенные для него материалы
|
||||||
|
mat_response = requests.get(f"{BASE_URL}/devices/43/materials/", headers=headers)
|
||||||
|
materials_data = mat_response.json()
|
||||||
|
```
|
||||||
|
|
||||||
|
**Ответ API (Устройство):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 43,
|
||||||
|
"name": "Excavator fd7f",
|
||||||
|
"mac_address": "24f40acefd7f",
|
||||||
|
"last_seen": "2026-04-23T15:18:35.744056+03:00",
|
||||||
|
"is_active": true,
|
||||||
|
"bucket_volume": 2.5,
|
||||||
|
"max_cycle_time_sec": 60,
|
||||||
|
"downtime_threshold_sec": 300,
|
||||||
|
"organization_name": "Дзержинск карьер",
|
||||||
|
"has_multiple_shifts": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Ответ API (Материалы):**
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"name": "Грунт",
|
||||||
|
"is_default": true,
|
||||||
|
"bulk_density": 1650.0,
|
||||||
|
"true_density": 2600.0,
|
||||||
|
"loosening_factor": 1.58
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Интерпретация:**
|
||||||
|
* Устройство `Excavator fd7f` активно работает в организации «Дзержинск карьер». Связь с ним была совсем недавно (`last_seen`).
|
||||||
|
* Физический **объем ковша** (`bucket_volume`) — 2.5 кубометра.
|
||||||
|
* Если экскаватор не двигается более 300 секунд (`downtime_threshold_sec`), система засчитывает это как **простой**.
|
||||||
|
* У машины включен режим **работы по сменам** (`has_multiple_shifts: true`).
|
||||||
|
* По умолчанию машина работает с материалом «Грунт» (`is_default: true`). При расчете массы ИИ будет использовать объемный вес 1650 кг/м³ и коэффициент разрыхления 1.58 (`loosening_factor`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Пример 6.2: Запрос суточной аналитики (Цифровой двойник)
|
||||||
|
|
||||||
|
**Запрос (Python):**
|
||||||
|
```python
|
||||||
|
params = {
|
||||||
|
"device_id": 43,
|
||||||
|
"start_date": "2026-04-23T00:00:00Z",
|
||||||
|
"end_date": "2026-04-23T23:59:59Z"
|
||||||
|
}
|
||||||
|
response = requests.get(f"{BASE_URL}/analytics/", headers=headers, params=params)
|
||||||
|
analytics_data = response.json()
|
||||||
|
```
|
||||||
|
|
||||||
|
**Ответ API (Аналитика, сокращенно):**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"total_mileage_km": 1.95756,
|
||||||
|
"total_duration_sec": 68399.0,
|
||||||
|
"cycle_count_total": 675,
|
||||||
|
"cycle_count_vehicle": 266,
|
||||||
|
"cycle_count_ground": 409,
|
||||||
|
"estimated_volume_total": 1687.5,
|
||||||
|
"estimated_mass_total": 2784375.0,
|
||||||
|
"shift_stats": {
|
||||||
|
"Дневная": {
|
||||||
|
"cycles_total": 675,
|
||||||
|
"actual_downtime": 5233.1,
|
||||||
|
"volume_vehicle": 665.0
|
||||||
|
},
|
||||||
|
"Ночная": {
|
||||||
|
"cycles_total": 0,
|
||||||
|
"actual_downtime": 0,
|
||||||
|
"volume_vehicle": 0.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"averages": {
|
||||||
|
"vehicle": {"empty_sec": 5.1, "full_sec": 10.6, "unload_sec": 6.5, "total_sec": 22.1},
|
||||||
|
"ground": {"empty_sec": 8.3, "full_sec": 4.5, "unload_sec": 5.4, "total_sec": 18.3}
|
||||||
|
},
|
||||||
|
"durations_by_class_sec": {
|
||||||
|
"full_bucket": 4019.7,
|
||||||
|
"unloading_vehicle": 2036.9,
|
||||||
|
"unloading_ground": 4897.2,
|
||||||
|
"empty_bucket": 9006.3,
|
||||||
|
"actual_downtime": 5233.1,
|
||||||
|
"no_data": 43205.6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Интерпретация:**
|
||||||
|
Данный эндпоинт отдает готовую сводку за запрошенный период:
|
||||||
|
* Экскаватор проехал почти **2 км** (`total_mileage_km`).
|
||||||
|
* За день сделано **675 рабочих циклов** (`cycle_count_total`). Из них полезная работа — загрузка в транспорт/самосвал (`cycle_count_vehicle`) составила 266 ковшей, а перекидка в отвал/на землю (`cycle_count_ground`) — 409 ковшей.
|
||||||
|
* Перемещено около **1687 кубометров** или ~2784 тонн породы.
|
||||||
|
* В блоке `shift_stats` видно, что вся работа пришлась исключительно на смену «Дневная». В «Ночную» машину не заводили (0 циклов).
|
||||||
|
* Блок `averages` показывает, что средний цикл загрузки в транспорт занимает **22.1 секунды**, где 10.6 сек уходит на поворот с полным ковшом, а 6.5 сек — на выгрузку.
|
||||||
|
* Блок `durations_by_class_sec` детально расписывает хронометраж. `actual_downtime` (фактический простой с включенным двигателем) составил ~1.45 часа (5233 сек). Параметр `no_data` (экскаватор выключен или нет связи) составил около 12 часов.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Пример 6.3: Работа с видеоархивом (Синхронизация видео и графика)
|
||||||
|
|
||||||
|
Частый сценарий — оператор кликает на событие в графике аналитики, и плеер должен перемотать видео точно на этот момент.
|
||||||
|
|
||||||
|
**Шаг 1: Запрос доступных папок за день (Python):**
|
||||||
|
```python
|
||||||
|
response = requests.get(f"{BASE_URL}/devices/43/folders/", headers=headers)
|
||||||
|
folders = response.json()
|
||||||
|
```
|
||||||
|
**Ответ:**
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 5495,
|
||||||
|
"received_at": "2026-04-23T15:18:28.541403+03:00",
|
||||||
|
"video_file": "/media/devices/43/2026/04/23/15/video_...mp4",
|
||||||
|
"file_count": 4350,
|
||||||
|
"original_width": 480,
|
||||||
|
"original_height": 640
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
*Интерпретация:* Видео на сервере нарезается часовыми кусками (папками). Внутри этого часа ИИ обработал 4350 кадров (поле `file_count`).
|
||||||
|
|
||||||
|
**Шаг 2: Поиск точного кадра по Timestamp (Python):**
|
||||||
|
```python
|
||||||
|
params = {"timestamp": "2026-04-23T15:03:02Z"}
|
||||||
|
response = requests.get(f"{BASE_URL}/devices/43/video-frame/", headers=headers, params=params)
|
||||||
|
frame_data = response.json()
|
||||||
|
```
|
||||||
|
**Ответ:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"video_url": "http://ex.neimarker.ru/media/devices/43/2026/04/23/15/video_7d4b6624.mp4",
|
||||||
|
"seek_seconds": 182.875,
|
||||||
|
"folder_id": 5495,
|
||||||
|
"frame_index": 4389
|
||||||
|
}
|
||||||
|
```
|
||||||
|
*Интерпретация:* API нашел, в каком видеофайле находится запрошенное время (`timestamp`). Фронтенду/приложению нужно загрузить `video_url` и перемотать плеер на `182.875` секунды (`seek_seconds`), чтобы показать нужный момент работы или нарушения.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Пример 6.4: Получение трека (маршрута) для карты
|
||||||
|
|
||||||
|
**Запрос (Python):**
|
||||||
|
```python
|
||||||
|
params = {
|
||||||
|
"start_date": "2026-04-23T03:17:00Z",
|
||||||
|
"end_date": "2026-04-23T03:30:00Z"
|
||||||
|
}
|
||||||
|
response = requests.get(f"{BASE_URL}/devices/43/trajectory/", headers=headers, params=params)
|
||||||
|
trajectory = response.json()
|
||||||
|
```
|
||||||
|
|
||||||
|
**Ответ API:**
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"ts": "2026-04-23T03:17:00.796000Z",
|
||||||
|
"lat": 56.23502833333334,
|
||||||
|
"lon": 43.63613999999999
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-04-23T03:18:00.997000Z",
|
||||||
|
"lat": 56.23502833333334,
|
||||||
|
"lon": 43.63613999999999
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Интерпретация:**
|
||||||
|
Массив точек с широтой (`lat`) и долготой (`lon`), привязанных к меткам времени (`ts`). Эти данные идеально подходят для отрисовки полилинии (Polyline) маршрута движения экскаватора в гео-информационных системах, 1С (через интеграцию карт) или на веб-картах (Yandex Maps, Leaflet). Точки отдаются с фильтрацией погрешностей GPS (выбросов).
|
||||||
Reference in New Issue
Block a user