Skip to content
59 changes: 41 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ EdgeTech supports buoy systems with two physical units connected by a line:
- The start unit (`startUnit: null`) initiates processing
- The end unit (`endUnit: null`) is skipped (processed as part of start unit)
- If end unit is missing, the start unit is skipped with a warning
- **Circular two-unit protection**: If the same two devices are each configured as start with the other as end (e.g. A.endUnit=B and B.endUnit=A), only one gearset is created. The duplicate start is skipped (canonical lead is the device with the smaller serial number), and a warning is logged.

---

Expand Down Expand Up @@ -358,21 +359,37 @@ After filtering, we compare EdgeTech data with our existing Earth Ranger records
- Standard: `{serialNumber}_{hashedUserId}`
- Action: Create deployment gear payload with new UUID as `set_id`

**2. UPDATE (Location Changes)**
**2. RE-DEPLOY (Same units, new deployment)**
- Buoy exists in **both** EdgeTech and Earth Ranger, and ER gear is still `status: "deployed"`
- EdgeTech **`dateDeployed`** is **more than 1 minute after** the ER gear’s deployment time (so we treat it as a new deployment, not an update)
- Action: **Haul** the existing gear (close it), then **Deploy** a new gear set with a new `set_id`
- **Processing order**: Haul payload is sent first, then the new deployment payload, so the previous gear is closed before the new one is created
- **Why**: When the same serial(s) are deployed again (e.g. same two-unit pair with a new `dateDeployed`), we close the previous deployment in ER/Buoy and create a new one instead of updating the old gear in place
- **Haul timestamp for re-deployments**: When a buoy is hauled and redeployed within seconds, the `currentState.dateRecovered` is cleared by the redeploy. In this case, the haul payload’s `recorded_at` is sourced from the most recent `dateRecovered` in `changeRecords` to avoid colliding with the deploy’s `recorded_at` (which uses `dateDeployed`). Recovery location (`recoveredLatDeg`/`recoveredLonDeg`) is also recovered from `changeRecords` in the same way.

**2a. DEPLOY (Recovery from missed deployment)**
- Buoy exists in **both** EdgeTech and Earth Ranger, but ER gear `status` is **not** `"deployed"` (e.g. `"hauled"`)
- EdgeTech shows `isDeployed: true`
- **Why**: This handles the case where a previous re-deployment haul succeeded but the deploy failed (e.g. `recorded_at` collision). On subsequent processor runs, the hauled ER gear + deployed EdgeTech state is recognized as a missed deployment.
- Action: Create deployment gear payload with new UUID as `set_id` (no haul needed since gear is already hauled)

**3. UPDATE (Location Changes)**
- Buoy exists in both systems
- EdgeTech `lastUpdated` > Earth Ranger `last_updated`, OR location changed
- Location has changed (primary device coordinates differ from ER)
- Buoy still marked as `isDeployed: true` and `isDeleted: false`
- Action: Create update gear payload using existing ER gear's `set_id`
- **Not** a re-deployment (EdgeTech `dateDeployed` is not more than 1 minute after ER gear’s deployment)
- **Note**: Buoys are initially identified for update when `lastUpdated > last_updated` OR location changed, but during payload generation, updates are only sent when the location has actually changed. Metadata-only updates (newer timestamp, same location) are skipped.
- Action: Create update gear payload using existing ER gear’s `set_id`

**3. HAUL (Retrievals)**
**4. HAUL (Retrievals)**
- Buoy exists in both systems, but EdgeTech **explicitly** marks it as:
- `isDeleted: true`, OR
- `isDeployed: false`
- Earth Ranger gear must still show `status: "deployed"`
- **Important**: Absence from EdgeTech data does NOT trigger a haul
- Action: Create haul gear payload using existing ER gear's `set_id`

**4. NO-OP (Skip)**
**5. NO-OP (Skip)**
- Buoy exists in both systems
- No location change detected
- Same `lastUpdated` timestamp
Expand Down Expand Up @@ -420,6 +437,7 @@ er_gear = er_gears_devices_id_to_gear.get(primary_key) \
| Scenario | ER Gear Found? | set_id Source |
|----------|----------------|---------------|
| **New Deployment** | No | Generate new UUID: `str(uuid4())` |
| **Re-deployment** | Yes | Haul: use ER gear's `display_id`. Deploy: generate new UUID |
| **Update Existing** | Yes | Use ER gear's `id` field (UUID) |
| **Haul Existing** | Yes | Use ER gear's `display_id` field |

Expand Down Expand Up @@ -859,8 +877,9 @@ When EdgeTech explicitly marks a buoy as `isDeleted: true` or `isDeployed: false
```

**Location Priority for Hauls**:
1. Recovery location from EdgeTech (`recoveredLatDeg`/`recoveredLonDeg`) if available
2. Fallback to last deployed location from Earth Ranger
1. Recovery location from EdgeTech `currentState` (`recoveredLatDeg`/`recoveredLonDeg`) if available
2. Recovery location from EdgeTech `changeRecords` (for re-deployments where `currentState` was overwritten)
3. Fallback to last deployed location from Earth Ranger

**Note**: All devices in the gear set use the same recovery location since there's only one recovery point.

Expand Down Expand Up @@ -956,21 +975,23 @@ Result: Entire system skipped if either unit missing
┌─────────────────────────────────────────────────────────────┐
│ 4. IDENTIFY OPERATIONS │
│ DEPLOY: In EdgeTech (deployed), not in ER │
│ UPDATE: In both, EdgeTech newer + location changed │
│ HAUL: In both, EdgeTech isDeleted/!isDeployed │
│ (Absence from EdgeTech does NOT trigger haul) │
│ DEPLOY: In EdgeTech (deployed), not in ER │
│ RE-DEPLOY: In both, EdgeTech dateDeployed > ER + 1 min │
│ → Haul existing gear, then deploy new │
│ RECOVERY: ER gear hauled but EdgeTech isDeployed=true │
│ → Deploy new gear (haul already done) │
│ UPDATE: In both, EdgeTech newer + location changed │
│ HAUL: In both, EdgeTech isDeleted/!isDeployed │
│ (Absence from EdgeTech does NOT trigger haul) │
└────────────────┬────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 5. GENERATE GEAR PAYLOADS │
│ For each operation: │
│ - Resolve set_id (new UUID or existing ER ID) │
│ - Resolve device_id (new UUID or existing source ID) │
│ - Extract locations │
│ - Set device_status (deployed/hauled) │
│ - Build gear payload JSON │
│ 5. GENERATE GEAR PAYLOADS (order matters) │
│ a) Hauls first (close existing gears) │
│ b) Deployments (new gear sets) │
│ c) Updates (location/status changes) │
│ For each: set_id, device_id, locations, device_status │
└────────────────┬────────────────────────────────────────────┘
Expand Down Expand Up @@ -1113,6 +1134,8 @@ This integration provides robust synchronization between EdgeTech's Trap Tracker
✅ **Efficient database dump** mechanism for bulk data retrieval
✅ **Intelligent filtering** to process active and explicitly hauled buoys
✅ **Explicit status-based haul detection** (not inferred from absence)
✅ **Re-deployment handling**: when EdgeTech `dateDeployed` is meaningfully later than ER’s deployment, we close the previous gear and create a new one (hauls sent before new deployments). Haul timestamps and recovery locations are sourced from `changeRecords` when a rapid haul+redeploy clears `currentState`.
✅ **Recovery from missed deployments**: if a re-deployment haul succeeded but the deploy failed, subsequent runs detect the hauled ER gear vs deployed EdgeTech state and create the missing deployment
✅ **Set ID resolution** to correctly update existing vs create new gear sets
✅ **Support for complex systems** including two-unit lines
✅ **Standardized gear payload format** for the Buoy API
Expand Down
Loading
Loading