post: operationId: linkDTU summary: Link a DTU to a station description: | Permission: **ADMIN, OWNER** Links a DTU hardware unit to an existing monitoring station by serial number and PIN. The DTU must not already be linked to another station. ### Error response mapping (US-26) The backend returns errors in the standard `ApiError` format: ```json { "code": , "message": "", "details": [...] } ``` | Code | Backend `message` field | BA Expected Message | Action | |------|------------------------|-------------------|--------| | `180215` | *validation error detail* | Field-level inline errors (required, min 4, max 50, alphanum) | Show inline validation errors per AC-26.2/3/4 | | `180228` | `"station is not active"` | Station is not active | Show station inactive error | | `180229` | `"station not found"` | Station not found | Show station not found error | | `180230` | `"DTU is already linked to another station"` | "This DTU is already linked to another station." | Show inline error on dtu_serial field per AC-26.5 | | `180231` | `"DTU does not belong to the station's supplier"` | "This DTU does not belong to the station's supplier." | Show inline error on dtu_serial field per AC-26.6 | | `180232` | `"DTU serial or PIN rejected by supplier system: "` | "The DTU Serial Number or PIN is incorrect. Please check and try again." | Show inline error per AC-26.7 ⚠️ Bug: never triggered (see note below) | | `100204` | `"add datalogger to supplier timeout: "` | "Unable to validate the DTU. Please try again or contact the system administrator." | Show notification — supplier add timeout per AC-26.7 | | `180233` | *(not yet implemented)* | *(not defined in BA)* | Show notification — supplier validate timeout (separated from add timeout for FE handling) | | `180244` | `"add datalogger failed: "` | *(not defined in BA — internal catch-all)* | Show generic error notification | > **Note (180232 bug)**: Code path `ErrBizDTUInvalidSerialOrPin` exists in source but is **never triggered** because no provider (`growatt`, `luxpower`) wraps the sentinel `ErrInvalidDatalogger`. All non-timeout supplier errors (including wrong serial/PIN) currently fall into `180244` instead. This will be fixed separately in `nova_service`. > > **Vendor-side validation detail**: Growatt calls `POST /device/datalogger/validate` first. If validation fails, it returns an error like `"growatt: api error : "`. Luxpower calls `POST /web/config/datalog/add` directly, returning error via `MsgCode`/`Msg`. Both errors currently route to `180244`. tags: [station] security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: "../../components.yaml#/components/schemas/LinkDTURequest" example: station_id: "6656c2b3f1a2b3c4d5e6f888" dtu_serial: "DTU123456789" dtu_pin: "PIN5678XY" responses: "200": description: DTU linked — DTO returned directly. content: application/json: schema: $ref: "../../components.yaml#/components/schemas/LinkDTUResponse" example: dtu_id: "9e5b8a7a-5a3a-4d6f-9b13-3b8e0db0f2d1" station_id: "6656c2b3f1a2b3c4d5e6f888" dtu_serial: "DTU123456789" status: "Connected" supplier: "growatt" devices: - device_id: "4c2d4c26-e9de-4d5d-bd31-91367ad4f916" device_serial: "DEV001" supplier: "growatt" station_id: "6656c2b3f1a2b3c4d5e6f888" "400": $ref: "../../components.yaml#/components/responses/Failure"