diff --git a/src/device/controllers/device.controller.ts b/src/device/controllers/device.controller.ts index 6ded947..6a844d9 100644 --- a/src/device/controllers/device.controller.ts +++ b/src/device/controllers/device.controller.ts @@ -22,6 +22,7 @@ import { ControlDeviceDto, BatchControlDevicesDto, BatchStatusDevicesDto, + BatchFactoryResetDevicesDto, } from '../dtos/control.device.dto'; import { CheckRoomGuard } from 'src/guards/room.guard'; import { CheckUserHavePermission } from 'src/guards/user.device.permission.guard'; @@ -291,4 +292,21 @@ export class DeviceController { ); } } + @ApiBearerAuth() + @UseGuards(JwtAuthGuard) + @Post('factory/reset/:deviceUuid') + async batchFactoryResetDevices( + @Body() batchFactoryResetDevicesDto: BatchFactoryResetDevicesDto, + ) { + try { + return await this.deviceService.batchFactoryResetDevices( + batchFactoryResetDevicesDto, + ); + } catch (error) { + throw new HttpException( + error.message || 'Internal server error', + error.status || HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } } diff --git a/src/device/dtos/control.device.dto.ts b/src/device/dtos/control.device.dto.ts index 7634fd0..d917a96 100644 --- a/src/device/dtos/control.device.dto.ts +++ b/src/device/dtos/control.device.dto.ts @@ -45,3 +45,12 @@ export class BatchStatusDevicesDto { }) devicesUuid: string; } +export class BatchFactoryResetDevicesDto { + @ApiProperty({ + description: 'devicesUuid', + required: true, + }) + @IsArray() + @IsNotEmpty() + public devicesUuid: [string]; +} diff --git a/src/device/services/device.service.ts b/src/device/services/device.service.ts index 8e4377e..82c813a 100644 --- a/src/device/services/device.service.ts +++ b/src/device/services/device.service.ts @@ -24,6 +24,7 @@ import { } from '../dtos/get.device.dto'; import { BatchControlDevicesDto, + BatchFactoryResetDevicesDto, BatchStatusDevicesDto, ControlDeviceDto, } from '../dtos/control.device.dto'; @@ -288,6 +289,24 @@ export class DeviceService { ); } } + async factoryResetDeviceTuya( + deviceUuid: string, + ): Promise { + try { + const path = `/v2.0/cloud/thing/${deviceUuid}/reset`; + const response = await this.tuya.request({ + method: 'POST', + path, + }); + + return response as controlDeviceInterface; + } catch (error) { + throw new HttpException( + 'Error factory resetting device from Tuya', + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } async controlDeviceTuya( deviceUuid: string, controlDeviceDto: ControlDeviceDto, @@ -413,6 +432,58 @@ export class DeviceService { } } } + async batchFactoryResetDevices( + batchFactoryResetDevicesDto: BatchFactoryResetDevicesDto, + ) { + const { devicesUuid } = batchFactoryResetDevicesDto; + + try { + // Check if all devices have the same product UUID + await this.checkAllDevicesHaveSameProductUuid(devicesUuid); + + // Perform all operations concurrently + const results = await Promise.allSettled( + devicesUuid.map(async (deviceUuid) => { + const deviceDetails = await this.getDeviceByDeviceUuid(deviceUuid); + const result = await this.factoryResetDeviceTuya( + deviceDetails.deviceTuyaUuid, + ); + return { deviceUuid, result }; + }), + ); + + // Separate successful and failed operations + const successResults = []; + const failedResults = []; + + for (const result of results) { + if (result.status === 'fulfilled') { + const { deviceUuid, result: operationResult } = result.value; + + if (operationResult.success) { + // Add to success results if operationResult.success is true + successResults.push({ deviceUuid, result: operationResult }); + } else { + // Add to failed results if operationResult.success is false + failedResults.push({ deviceUuid, error: operationResult.msg }); + } + } else { + // Add to failed results if promise is rejected + failedResults.push({ + deviceUuid: devicesUuid[results.indexOf(result)], + error: result.reason.message, + }); + } + } + + return { successResults, failedResults }; + } catch (error) { + throw new HttpException( + error.message || 'Device Not Found', + error.status || HttpStatus.NOT_FOUND, + ); + } + } async getDeviceDetailsByDeviceId(deviceUuid: string, userUuid: string) { try { const userDevicePermission = await this.getUserDevicePermission(