- Add updateDeviceMetadata and attachDeviceToDeployment API methods - Device Settings: editable location/description fields with save - Equipment screen: location placeholder and quick navigation to settings - Add Sensor: multi-select with checkboxes, select all/deselect all - Setup WiFi: batch processing of multiple sensors sequentially - BatchSetupProgress: animated progress bar, step indicators, auto-scroll - SetupResultsScreen: success/failed/skipped summary with retry options - Error handling: modal with Retry/Skip/Cancel All buttons - Documentation: SENSORS_SYSTEM.md with full BLE protocol and flows Implemented via Ralphy CLI autonomous agent in ~43 minutes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
356 lines
9.8 KiB
Markdown
356 lines
9.8 KiB
Markdown
# PRD: Sensors Management System
|
|
|
|
## Context
|
|
|
|
WellNuo app for elderly care. BLE/WiFi sensors monitor beneficiaries (elderly people) at home.
|
|
Each user can have multiple beneficiaries. Each beneficiary has one deployment (household) with up to 5 sensors.
|
|
|
|
**Architecture:**
|
|
- User → Beneficiary (WellNuo API) → deploymentId → Deployment (Legacy API) → Devices
|
|
- BLE for sensor setup, WiFi for data transmission
|
|
- Legacy API at `https://eluxnetworks.net/function/well-api/api` (external, read-only code access)
|
|
|
|
**Documentation:** `docs/SENSORS_SYSTEM.md`
|
|
**Feature Spec:** `specs/wellnuo/FEATURE-SENSORS-SYSTEM.md`
|
|
|
|
---
|
|
|
|
## Tasks
|
|
|
|
### Phase 1: API Layer
|
|
|
|
- [x] **TASK-1.1: Add updateDeviceMetadata method to api.ts**
|
|
|
|
File: `services/api.ts`
|
|
|
|
Add method to update device location and description via Legacy API.
|
|
|
|
```typescript
|
|
async updateDeviceMetadata(
|
|
wellId: number,
|
|
mac: string,
|
|
deploymentId: number,
|
|
location: string,
|
|
description: string
|
|
): Promise<boolean>
|
|
```
|
|
|
|
Implementation:
|
|
1. Get Legacy API credentials via `getLegacyCredentials()`
|
|
2. Build form data with: `function=device_form`, `user_name`, `token`, `well_id`, `device_mac`, `location`, `description`, `deployment_id`
|
|
3. POST to `https://eluxnetworks.net/function/well-api/api`
|
|
4. Return true on success, false on error
|
|
|
|
Reference: `docs/SENSORS_SYSTEM.md` lines 266-280 for API format.
|
|
|
|
---
|
|
|
|
### Phase 2: Device Settings UI
|
|
|
|
- [x] **TASK-2.1: Add location/description editing to Device Settings screen**
|
|
|
|
File: `app/(tabs)/beneficiaries/[id]/device-settings/[deviceId].tsx`
|
|
|
|
Add editable fields for sensor location and description:
|
|
|
|
1. Add state variables: `location`, `description`, `isSaving`
|
|
2. Add two TextInput fields below device info section
|
|
3. Add "Save" button that calls `api.updateDeviceMetadata()`
|
|
4. Show loading indicator during save
|
|
5. Show success/error toast after save
|
|
6. Pre-fill fields with current values from device data
|
|
|
|
UI requirements:
|
|
- TextInput for location (placeholder: "e.g., Bedroom, near bed")
|
|
- TextInput for description (placeholder: "e.g., Main activity sensor")
|
|
- Button: "Save Changes" (disabled when no changes or saving)
|
|
- Toast: "Settings saved" on success
|
|
|
|
---
|
|
|
|
### Phase 3: Equipment Screen Improvements
|
|
|
|
- [x] **TASK-3.1: Show placeholder for empty location in Equipment screen**
|
|
|
|
File: `app/(tabs)/beneficiaries/[id]/equipment.tsx`
|
|
|
|
Find the sensor list rendering (around line 454) and update:
|
|
|
|
Before:
|
|
```tsx
|
|
{sensor.location && (
|
|
<Text style={styles.deviceLocation}>{sensor.location}</Text>
|
|
)}
|
|
```
|
|
|
|
After:
|
|
```tsx
|
|
<Text style={[styles.deviceLocation, !sensor.location && styles.deviceLocationEmpty]}>
|
|
{sensor.location || 'Tap to set location'}
|
|
</Text>
|
|
```
|
|
|
|
Add style `deviceLocationEmpty` with `opacity: 0.5, fontStyle: 'italic'`
|
|
|
|
- [x] **TASK-3.2: Add quick navigation to Device Settings from Equipment screen**
|
|
|
|
File: `app/(tabs)/beneficiaries/[id]/equipment.tsx`
|
|
|
|
Make the location text tappable to navigate to Device Settings:
|
|
|
|
1. Wrap location Text in TouchableOpacity
|
|
2. onPress: navigate to `/beneficiaries/${id}/device-settings/${device.id}`
|
|
3. Import `useRouter` from `expo-router` if not already imported
|
|
|
|
---
|
|
|
|
### Phase 4: Batch Sensor Setup - Selection UI
|
|
|
|
- [x] **TASK-4.1: Add checkbox selection to Add Sensor screen**
|
|
|
|
File: `app/(tabs)/beneficiaries/[id]/add-sensor.tsx`
|
|
|
|
After BLE scan, show checkboxes for selecting multiple sensors:
|
|
|
|
1. Add state: `selectedDevices: Set<string>` (device IDs)
|
|
2. After scan, select ALL devices by default
|
|
3. Render each device with checkbox (use Checkbox from react-native or custom)
|
|
4. Add "Select All" / "Deselect All" toggle at top
|
|
5. Show count: "3 of 5 selected"
|
|
6. Change button from "Connect" to "Setup Selected (N)"
|
|
7. Pass selected devices to Setup WiFi screen via route params
|
|
|
|
UI layout:
|
|
```
|
|
[ ] Select All
|
|
|
|
[x] WP_497_81a14c -55 dBm ✓
|
|
[x] WP_498_82b25d -62 dBm ✓
|
|
[ ] WP_499_83c36e -78 dBm
|
|
|
|
[Setup Selected (2)]
|
|
```
|
|
|
|
- [x] **TASK-4.2: Update navigation to pass selected devices**
|
|
|
|
File: `app/(tabs)/beneficiaries/[id]/add-sensor.tsx`
|
|
|
|
When navigating to setup-wifi screen, pass selected devices:
|
|
|
|
```typescript
|
|
router.push({
|
|
pathname: `/(tabs)/beneficiaries/${id}/setup-wifi`,
|
|
params: {
|
|
devices: JSON.stringify(selectedDevicesArray),
|
|
beneficiaryId: id
|
|
}
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
### Phase 5: Batch Sensor Setup - WiFi Configuration
|
|
|
|
- [x] **TASK-5.1: Refactor Setup WiFi screen for batch processing**
|
|
|
|
File: `app/(tabs)/beneficiaries/[id]/setup-wifi.tsx`
|
|
|
|
Update to handle multiple devices:
|
|
|
|
1. Parse `devices` from route params (JSON array of WPDevice objects)
|
|
2. Get WiFi list from FIRST device only (all sensors at same location = same WiFi)
|
|
3. After user enters password, process ALL devices sequentially
|
|
4. Add state for batch progress tracking
|
|
|
|
New state:
|
|
```typescript
|
|
interface DeviceSetupState {
|
|
deviceId: string;
|
|
deviceName: string;
|
|
status: 'pending' | 'connecting' | 'unlocking' | 'setting_wifi' | 'attaching' | 'rebooting' | 'success' | 'error';
|
|
error?: string;
|
|
}
|
|
const [setupStates, setSetupStates] = useState<DeviceSetupState[]>([]);
|
|
```
|
|
|
|
- [x] **TASK-5.2: Implement batch setup processing logic**
|
|
|
|
File: `app/(tabs)/beneficiaries/[id]/setup-wifi.tsx`
|
|
|
|
Create `processBatchSetup` function:
|
|
|
|
```typescript
|
|
async function processBatchSetup(ssid: string, password: string) {
|
|
for (const device of devices) {
|
|
updateStatus(device.id, 'connecting');
|
|
|
|
// 1. Connect BLE
|
|
const connected = await bleManager.connectDevice(device.id);
|
|
if (!connected) {
|
|
updateStatus(device.id, 'error', 'Could not connect');
|
|
continue; // Skip to next device
|
|
}
|
|
|
|
// 2. Unlock with PIN
|
|
updateStatus(device.id, 'unlocking');
|
|
await bleManager.sendCommand(device.id, 'pin|7856');
|
|
|
|
// 3. Set WiFi
|
|
updateStatus(device.id, 'setting_wifi');
|
|
await bleManager.setWiFi(device.id, ssid, password);
|
|
|
|
// 4. Attach to deployment via Legacy API
|
|
updateStatus(device.id, 'attaching');
|
|
await api.attachDeviceToDeployment(device.wellId, device.mac, deploymentId);
|
|
|
|
// 5. Reboot
|
|
updateStatus(device.id, 'rebooting');
|
|
await bleManager.rebootDevice(device.id);
|
|
|
|
updateStatus(device.id, 'success');
|
|
}
|
|
}
|
|
```
|
|
|
|
- [x] **TASK-5.3: Add progress UI for batch setup**
|
|
|
|
File: `app/(tabs)/beneficiaries/[id]/setup-wifi.tsx`
|
|
|
|
Show progress for each device:
|
|
|
|
```
|
|
Connecting to "Home_Network"...
|
|
|
|
WP_497_81a14c
|
|
✓ Connected
|
|
✓ Unlocked
|
|
✓ WiFi configured
|
|
● Attaching to Maria...
|
|
|
|
WP_498_82b25d
|
|
✓ Connected
|
|
○ Waiting...
|
|
|
|
WP_499_83c36e
|
|
○ Pending
|
|
```
|
|
|
|
Use icons: ✓ (success), ● (in progress), ○ (pending), ✗ (error)
|
|
|
|
---
|
|
|
|
### Phase 6: Error Handling
|
|
|
|
- [x] **TASK-6.1: Add error handling UI with retry/skip options**
|
|
|
|
File: `app/(tabs)/beneficiaries/[id]/setup-wifi.tsx`
|
|
|
|
When a device fails:
|
|
|
|
1. Pause batch processing
|
|
2. Show error message with device name
|
|
3. Show three buttons: [Retry] [Skip] [Cancel All]
|
|
4. On Retry: try this device again
|
|
5. On Skip: mark as skipped, continue to next device
|
|
6. On Cancel All: abort entire process, show results
|
|
|
|
```tsx
|
|
{currentError && (
|
|
<View style={styles.errorContainer}>
|
|
<Text style={styles.errorTitle}>
|
|
Failed: {currentError.deviceName}
|
|
</Text>
|
|
<Text style={styles.errorMessage}>
|
|
{currentError.message}
|
|
</Text>
|
|
<View style={styles.errorButtons}>
|
|
<Button title="Retry" onPress={handleRetry} />
|
|
<Button title="Skip" onPress={handleSkip} />
|
|
<Button title="Cancel All" onPress={handleCancelAll} />
|
|
</View>
|
|
</View>
|
|
)}
|
|
```
|
|
|
|
- [x] **TASK-6.2: Add results screen after batch setup**
|
|
|
|
File: `app/(tabs)/beneficiaries/[id]/setup-wifi.tsx`
|
|
|
|
After all devices processed, show summary:
|
|
|
|
```
|
|
Setup Complete
|
|
|
|
Successfully connected:
|
|
✓ WP_497_81a14c
|
|
✓ WP_498_82b25d
|
|
|
|
Failed:
|
|
✗ WP_499_83c36e - Connection timeout
|
|
[Retry This Sensor]
|
|
|
|
Skipped:
|
|
⊘ WP_500_84d47f
|
|
|
|
[Done]
|
|
```
|
|
|
|
"Done" button navigates back to Equipment screen.
|
|
|
|
---
|
|
|
|
### Phase 7: API Method for Device Attachment
|
|
|
|
- [x] **TASK-7.1: Add attachDeviceToDeployment method to api.ts**
|
|
|
|
File: `services/api.ts`
|
|
|
|
Add method to register a new device with Legacy API:
|
|
|
|
```typescript
|
|
async attachDeviceToDeployment(
|
|
wellId: number,
|
|
mac: string,
|
|
deploymentId: number,
|
|
location?: string,
|
|
description?: string
|
|
): Promise<{ success: boolean; deviceId?: number; error?: string }>
|
|
```
|
|
|
|
Implementation:
|
|
1. Call Legacy API `device_form` with deployment_id set
|
|
2. Return device ID from response on success
|
|
3. Return error message on failure
|
|
|
|
This is used during batch setup to link each sensor to the beneficiary's deployment.
|
|
|
|
---
|
|
|
|
## Verification Checklist
|
|
|
|
After all tasks complete, verify:
|
|
|
|
- [x] Can view sensors list for any beneficiary
|
|
- [x] Can scan and find WP_* sensors via BLE
|
|
- [x] Can select multiple sensors with checkboxes
|
|
- [x] Can configure WiFi for all selected sensors
|
|
- [x] Progress UI shows status for each device
|
|
- [x] Errors show retry/skip options
|
|
- [x] Results screen shows success/failure summary
|
|
- [x] Can edit sensor location in Device Settings
|
|
- [x] Location placeholder shows in Equipment screen
|
|
- [x] Can tap location to go to Device Settings
|
|
- [x] Mock BLE works in iOS Simulator
|
|
|
|
---
|
|
|
|
## Notes for AI Agent
|
|
|
|
1. **Read documentation first**: `docs/SENSORS_SYSTEM.md` has full context
|
|
2. **Check existing code**: Files may already have partial implementations
|
|
3. **BLE Manager**: Use `services/ble/BLEManager.ts` for real device, `MockBLEManager.ts` for simulator
|
|
4. **Legacy API auth**: Use `getLegacyCredentials()` method in api.ts
|
|
5. **Error handling**: Always wrap BLE operations in try/catch
|
|
6. **TypeScript**: Project uses strict TypeScript, ensure proper types
|
|
7. **Testing**: Use iOS Simulator with Mock BLE for testing
|