- Add legacyAPI.js service for authentication and deployment management
- Add deployments.js routes for device listing
- Add FEATURE-SENSORS-SYSTEM.md spec
- Add bug report: set_deployment missing deployment_id in response
- Add test scripts for Legacy API (create_deployment, find_deployments)
- Update beneficiaries.js to return deploymentId
BUG: Legacy API set_deployment returns {"ok": 1} but does NOT return
deployment_id. Waiting for Robert to fix this before we can auto-create
deployments for new beneficiaries.
321 lines
10 KiB
Markdown
321 lines
10 KiB
Markdown
# FEATURE: Sensors Management System
|
||
|
||
**ID:** FEATURE-SENSORS
|
||
**Status:** 🟡 In Progress
|
||
**Priority:** High
|
||
**Created:** 2026-01-19
|
||
|
||
---
|
||
|
||
## Overview
|
||
|
||
Система управления BLE-сенсорами WP для мониторинга пожилых людей (beneficiaries).
|
||
Сенсоры измеряют активность в помещении и передают данные через WiFi на Legacy API.
|
||
|
||
**Схема архитектуры:**
|
||
https://diagrams.love/canvas?schema=cmkm6nt6x0063ll5lqaq49lbt
|
||
|
||
---
|
||
|
||
## Сущности
|
||
|
||
### Beneficiary (Подопечный)
|
||
- Пожилой человек, за которым ухаживают
|
||
- Хранится в: **WellNuo API** (PostgreSQL)
|
||
- Поля: `firstName`, `lastName`, `avatar`, `dateOfBirth`
|
||
|
||
### Deployment (Домовладение)
|
||
- Место проживания beneficiary в Legacy API
|
||
- Хранится в: **Legacy API** (eluxnetworks.net)
|
||
- Поля: `address`, `timezone`, `devices[]`, `beneficiary_id`
|
||
- Связь: 1 Beneficiary = 1 Deployment
|
||
|
||
### Device (WP Sensor)
|
||
- Физический BLE/WiFi сенсор
|
||
- Хранится в: **Legacy API**
|
||
- Поля:
|
||
- `well_id` — уникальный ID устройства
|
||
- `mac` — MAC адрес
|
||
- `location` — где установлен (текстовое поле, редактируемое)
|
||
- `description` — описание (текстовое поле, редактируемое)
|
||
- `deployment_id` — привязка к домовладению
|
||
- `status` — online/warning/offline (вычисляется по lastSeen)
|
||
|
||
---
|
||
|
||
## API
|
||
|
||
### WellNuo API (Primary)
|
||
**Base URL:** `https://wellnuo.smartlaunchhub.com/api`
|
||
**Auth:** Bearer JWT token
|
||
|
||
Используется для:
|
||
- Авторизация пользователей
|
||
- CRUD beneficiaries
|
||
- Подписки и платежи
|
||
- Профиль пользователя
|
||
|
||
### Legacy API (External)
|
||
**Base URL:** `https://eluxnetworks.net/function/well-api/api`
|
||
**Auth:** Form-encoded (user_name, token)
|
||
|
||
⚠️ **Внешний сервис — нет доступа к коду, только API**
|
||
|
||
#### Ключевые endpoints для устройств:
|
||
|
||
| Endpoint | Описание | Параметры |
|
||
|----------|----------|-----------|
|
||
| `device_list_by_deployment` | Список устройств deployment | deployment_id |
|
||
| `device_form` | Создать/обновить устройство | well_id, device_mac, location, description, deployment_id |
|
||
| `device_set_group` | Установить группу | device_id, group_id |
|
||
| `request_devices` | Получить online устройства | deployment_id, fresh=true |
|
||
|
||
#### Формат device_form:
|
||
```
|
||
POST /function/well-api/api
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
function=device_form
|
||
user_name={{user_name}}
|
||
token={{token}}
|
||
well_id=497
|
||
device_mac=142B2F81A14C
|
||
location=Спальня, у кровати
|
||
description=Основной сенсор
|
||
deployment_id=22
|
||
```
|
||
|
||
---
|
||
|
||
## Bluetooth Flow
|
||
|
||
### BLE Manager
|
||
**Файл:** `services/ble/BLEManager.ts`
|
||
**Библиотека:** `react-native-ble-plx`
|
||
|
||
### UUID и протокол:
|
||
```typescript
|
||
SERVICE_UUID: '4fafc201-1fb5-459e-8fcc-c5c9c331914b'
|
||
CHAR_UUID: 'beb5483e-36e1-4688-b7f5-ea07361b26a8'
|
||
```
|
||
|
||
### BLE команды:
|
||
| Команда | Формат | Описание |
|
||
|---------|--------|----------|
|
||
| PIN Unlock | `pin\|7856` | Разблокировка устройства |
|
||
| Get WiFi List | `w` | Получить доступные WiFi |
|
||
| Set WiFi | `W\|SSID,PASSWORD` | Установить WiFi |
|
||
| Get WiFi Status | `a` | Текущее подключение |
|
||
| Reboot | `s` | Перезагрузка |
|
||
| Disconnect | `D` | Отключение BLE |
|
||
|
||
### Таймауты:
|
||
- Сканирование: 10 сек
|
||
- Команда: 5 сек
|
||
|
||
### Формат ответа WiFi List:
|
||
```
|
||
SSID1,-55;SSID2,-70;SSID3,-80
|
||
```
|
||
|
||
---
|
||
|
||
## Экраны
|
||
|
||
### 1. Equipment Screen
|
||
**Путь:** `/(tabs)/beneficiaries/:id/equipment`
|
||
**Файл:** `app/(tabs)/beneficiaries/[id]/equipment.tsx`
|
||
|
||
**Функции:**
|
||
- Summary card (total/online/warning/offline)
|
||
- Список подключённых сенсоров (из API)
|
||
- BLE сканирование поблизости
|
||
- Detach сенсор
|
||
|
||
**Текущие ограничения:**
|
||
- ❌ НЕТ редактирования location/description
|
||
|
||
### 2. Add Sensor Screen
|
||
**Путь:** `/(tabs)/beneficiaries/:id/add-sensor`
|
||
**Файл:** `app/(tabs)/beneficiaries/[id]/add-sensor.tsx`
|
||
|
||
**Функции:**
|
||
- Инструкции по добавлению (4 шага)
|
||
- BLE сканирование
|
||
- Список найденных устройств с RSSI
|
||
|
||
### 3. Setup WiFi Screen
|
||
**Путь:** `/(tabs)/beneficiaries/:id/setup-wifi`
|
||
**Файл:** `app/(tabs)/beneficiaries/[id]/setup-wifi.tsx`
|
||
|
||
**Функции:**
|
||
- Получить WiFi список от сенсора (BLE)
|
||
- Выбор сети и ввод пароля
|
||
- Подключение и привязка к beneficiary
|
||
|
||
### 4. Device Settings Screen
|
||
**Путь:** `/(tabs)/beneficiaries/:id/device-settings/:deviceId`
|
||
**Файл:** `app/(tabs)/beneficiaries/[id]/device-settings/[deviceId].tsx`
|
||
|
||
**Функции:**
|
||
- Просмотр Well ID, MAC, Deployment ID
|
||
- Текущий WiFi статус
|
||
- Изменение WiFi
|
||
- Перезагрузка
|
||
|
||
**Текущие ограничения:**
|
||
- ❌ НЕТ редактирования location/description
|
||
|
||
---
|
||
|
||
## Что нужно доработать
|
||
|
||
### TASK-1: Добавить редактирование location/description
|
||
|
||
**Проблема:**
|
||
Сейчас `location` и `description` показываются в UI (equipment.tsx:454-456), но нет возможности их редактировать.
|
||
|
||
**Решение:**
|
||
1. Добавить в Device Settings Screen форму для редактирования
|
||
2. Создать метод `updateDevice()` в api.ts
|
||
3. Использовать Legacy API endpoint `device_form`
|
||
|
||
**Файлы для изменения:**
|
||
- `services/api.ts` — добавить `updateDeviceMetadata(deviceId, location, description)`
|
||
- `app/(tabs)/beneficiaries/[id]/device-settings/[deviceId].tsx` — добавить форму
|
||
|
||
**API вызов:**
|
||
```typescript
|
||
async updateDeviceMetadata(
|
||
deviceId: string,
|
||
wellId: number,
|
||
mac: string,
|
||
location: string,
|
||
description: string
|
||
) {
|
||
const creds = await this.getLegacyCredentials();
|
||
const formData = new URLSearchParams({
|
||
function: 'device_form',
|
||
user_name: creds.userName,
|
||
token: creds.token,
|
||
editing_device_id: deviceId,
|
||
well_id: wellId.toString(),
|
||
device_mac: mac,
|
||
location: location,
|
||
description: description,
|
||
});
|
||
// POST to Legacy API
|
||
}
|
||
```
|
||
|
||
### TASK-2: Показывать placeholder для пустого location
|
||
|
||
**Проблема:**
|
||
Если location пустой — ничего не показывается.
|
||
|
||
**Решение:**
|
||
В equipment.tsx вместо:
|
||
```tsx
|
||
{sensor.location && (
|
||
<Text style={styles.deviceLocation}>{sensor.location}</Text>
|
||
)}
|
||
```
|
||
|
||
Сделать:
|
||
```tsx
|
||
<TouchableOpacity onPress={() => openLocationEditor(sensor)}>
|
||
<Text style={styles.deviceLocation}>
|
||
{sensor.location || 'Tap to set location'}
|
||
</Text>
|
||
</TouchableOpacity>
|
||
```
|
||
|
||
### TASK-3: Quick edit location из Equipment Screen
|
||
|
||
**Проблема:**
|
||
Сейчас для редактирования location нужно заходить в Device Settings.
|
||
|
||
**Решение:**
|
||
Добавить inline редактирование или ActionSheet с опцией "Edit Location".
|
||
|
||
---
|
||
|
||
## Ключевые файлы
|
||
|
||
| Файл | Описание |
|
||
|------|----------|
|
||
| `services/ble/BLEManager.ts` | BLE менеджер |
|
||
| `services/ble/types.ts` | Типы BLE |
|
||
| `contexts/BLEContext.tsx` | Global BLE state |
|
||
| `services/api.ts` | API методы |
|
||
| `types/index.ts` | WPSensor тип (строки 47-59) |
|
||
| `app/(tabs)/beneficiaries/[id]/equipment.tsx` | Equipment Screen |
|
||
| `app/(tabs)/beneficiaries/[id]/add-sensor.tsx` | Add Sensor |
|
||
| `app/(tabs)/beneficiaries/[id]/setup-wifi.tsx` | Setup WiFi |
|
||
| `app/(tabs)/beneficiaries/[id]/device-settings/[deviceId].tsx` | Device Settings |
|
||
| `api/Wellnuo_API.postman_collection.json` | Postman коллекция |
|
||
|
||
---
|
||
|
||
## Статусы сенсора
|
||
|
||
Вычисляются на клиенте по `lastSeen`:
|
||
|
||
| Статус | Условие | Цвет |
|
||
|--------|---------|------|
|
||
| `online` | lastSeen < 5 мин | Зелёный |
|
||
| `warning` | 5 мин < lastSeen < 60 мин | Жёлтый |
|
||
| `offline` | lastSeen > 60 мин | Красный |
|
||
|
||
---
|
||
|
||
## Mock режим
|
||
|
||
Когда приложение работает в iOS Simulator, используется `MockBLEManager` с тестовыми данными:
|
||
|
||
```javascript
|
||
{
|
||
id: 'mock-743',
|
||
name: 'WP_497_81a14c',
|
||
mac: '142B2F81A14C',
|
||
rssi: -55,
|
||
wellId: 497,
|
||
}
|
||
```
|
||
|
||
Это позволяет разрабатывать без физического устройства.
|
||
|
||
---
|
||
|
||
## Implementation Steps
|
||
|
||
### Phase 1: API метод для обновления устройства
|
||
- [ ] Создать `updateDeviceMetadata()` в api.ts
|
||
- [ ] Тестировать через curl/Postman
|
||
|
||
### Phase 2: UI для редактирования в Device Settings
|
||
- [ ] Добавить TextInput для location
|
||
- [ ] Добавить TextInput для description
|
||
- [ ] Кнопка Save
|
||
- [ ] Loading state при сохранении
|
||
|
||
### Phase 3: Quick edit из Equipment Screen
|
||
- [ ] Добавить ActionSheet с опцией "Edit Location"
|
||
- [ ] Или inline edit по тапу
|
||
|
||
### Phase 4: Валидация и UX
|
||
- [ ] Показывать placeholder для пустого location
|
||
- [ ] Ограничить длину текста (если есть лимит API)
|
||
- [ ] Показывать success/error feedback
|
||
|
||
---
|
||
|
||
## Verification Checklist
|
||
|
||
- [ ] Сенсоры загружаются из Legacy API
|
||
- [ ] BLE сканирование находит WP_* устройства
|
||
- [ ] WiFi настройка работает через BLE
|
||
- [ ] Location/description сохраняется в Legacy API
|
||
- [ ] Location отображается в Equipment Screen
|
||
- [ ] Mock режим работает в симуляторе
|