diff --git a/libs/common/src/constants/permission-type.enum copy.ts b/libs/common/src/constants/permission-type.enum copy.ts new file mode 100644 index 0000000..f0d24ad --- /dev/null +++ b/libs/common/src/constants/permission-type.enum copy.ts @@ -0,0 +1,8 @@ +export enum ProductType { + AC = 'AC', + GW = 'GW', + CPS = 'CPS', + DL = 'DL', + WPS = 'WPS', + TH_G = '3G', +} diff --git a/src/device/controllers/device.controller.ts b/src/device/controllers/device.controller.ts index a3bbadd..986f23a 100644 --- a/src/device/controllers/device.controller.ts +++ b/src/device/controllers/device.controller.ts @@ -150,4 +150,17 @@ export class DeviceController { ); } } + @ApiBearerAuth() + @UseGuards(JwtAuthGuard) + @Get('getaway/:gatewayUuid/devices') + async getDevicesInGetaway(@Param('gatewayUuid') gatewayUuid: string) { + try { + return await this.deviceService.getDevicesInGetaway(gatewayUuid); + } catch (error) { + throw new HttpException( + error.message || 'Internal server error', + error.status || HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } } diff --git a/src/device/services/device.service.ts b/src/device/services/device.service.ts index 39bc0ce..310c2e6 100644 --- a/src/device/services/device.service.ts +++ b/src/device/services/device.service.ts @@ -26,6 +26,7 @@ import { ControlDeviceDto } from '../dtos/control.device.dto'; import { convertKeysToCamelCase } from '@app/common/helper/camelCaseConverter'; import { DeviceRepository } from '@app/common/modules/device/repositories'; import { GroupDeviceRepository } from '@app/common/modules/group-device/repositories'; +import { ProductType } from '@app/common/constants/permission-type.enum copy'; @Injectable() export class DeviceService { @@ -160,11 +161,9 @@ export class DeviceService { async controlDevice(controlDeviceDto: ControlDeviceDto) { try { - const deviceDetails = await this.deviceRepository.findOne({ - where: { - uuid: controlDeviceDto.deviceUuid, - }, - }); + const deviceDetails = await this.getDeviceByDeviceUuid( + controlDeviceDto.deviceUuid, + ); if (!deviceDetails || !deviceDetails.deviceTuyaUuid) { throw new NotFoundException('Device Not Found'); @@ -213,11 +212,7 @@ export class DeviceService { async getDeviceDetailsByDeviceId(deviceUuid: string) { try { - const deviceDetails = await this.deviceRepository.findOne({ - where: { - uuid: deviceUuid, - }, - }); + const deviceDetails = await this.getDeviceByDeviceUuid(deviceUuid); if (!deviceDetails) { throw new NotFoundException('Device Not Found'); @@ -256,7 +251,7 @@ export class DeviceService { }); // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { productName, productId, ...rest } = camelCaseResponse.result; + const { productName, productId, id, ...rest } = camelCaseResponse.result; return { ...rest, productUuid: product.uuid, @@ -273,12 +268,7 @@ export class DeviceService { deviceUuid: string, ): Promise { try { - const deviceDetails = await this.deviceRepository.findOne({ - where: { - uuid: deviceUuid, - }, - relations: ['productDevice'], - }); + const deviceDetails = await this.getDeviceByDeviceUuid(deviceUuid); if (!deviceDetails) { throw new NotFoundException('Device Not Found'); @@ -323,12 +313,7 @@ export class DeviceService { } async getDevicesInstructionStatus(deviceUuid: string) { try { - const deviceDetails = await this.deviceRepository.findOne({ - where: { - uuid: deviceUuid, - }, - relations: ['productDevice'], - }); + const deviceDetails = await this.getDeviceByDeviceUuid(deviceUuid); if (!deviceDetails) { throw new NotFoundException('Device Not Found'); @@ -370,4 +355,64 @@ export class DeviceService { ); } } + async getDevicesInGetaway(gatewayUuid: string) { + try { + const deviceDetails = await this.getDeviceByDeviceUuid(gatewayUuid); + + if (!deviceDetails) { + throw new NotFoundException('Device Not Found'); + } else if (deviceDetails.productDevice.prodType !== ProductType.GW) { + throw new NotFoundException('This is not a gateway device'); + } + + const response = await this.getDevicesInGetawayTuya( + deviceDetails.deviceTuyaUuid, + ); + + return { + uuid: deviceDetails.uuid, + productUuid: deviceDetails.productDevice.uuid, + productType: deviceDetails.productDevice.prodType, + device: response, + }; + } catch (error) { + throw new HttpException( + error.message || 'Device Not Found', + HttpStatus.NOT_FOUND, + ); + } + } + async getDevicesInGetawayTuya( + deviceId: string, + ): Promise { + try { + const path = `/v1.0/devices/${deviceId}/sub-devices`; + const response: any = await this.tuya.request({ + method: 'GET', + path, + }); + const camelCaseResponse = response.result.map((device: any) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { product_id, category, id, ...rest } = device; + const camelCaseDevice = convertKeysToCamelCase({ ...rest }); + return camelCaseDevice as GetDeviceDetailsInterface[]; + }); + + return camelCaseResponse; + } catch (error) { + throw new HttpException( + 'Error fetching device details from Tuya', + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } + + private async getDeviceByDeviceUuid(deviceUuid: string) { + return await this.deviceRepository.findOne({ + where: { + uuid: deviceUuid, + }, + relations: ['productDevice'], + }); + } }