From c387c5984d708f307ba343bcb5fc45fe6137da3c Mon Sep 17 00:00:00 2001 From: faris Aljohari <83524184+farisaljohari@users.noreply.github.com> Date: Tue, 1 Oct 2024 17:16:50 -0500 Subject: [PATCH] finished update schedule endpoint --- .../controllers/schedule.controller.ts | 31 +++++++- src/schedule/dtos/schedule.dto.ts | 45 +++++++++++ src/schedule/services/schedule.service.ts | 75 ++++++++++++++++++- 3 files changed, 148 insertions(+), 3 deletions(-) diff --git a/src/schedule/controllers/schedule.controller.ts b/src/schedule/controllers/schedule.controller.ts index c14c6fe..63bf182 100644 --- a/src/schedule/controllers/schedule.controller.ts +++ b/src/schedule/controllers/schedule.controller.ts @@ -17,6 +17,7 @@ import { AddScheduleDto, EnableScheduleDto, GetScheduleDeviceDto, + UpdateScheduleDto, } from '../dtos/schedule.dto'; import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard'; @@ -36,7 +37,7 @@ export class ScheduleController { @Body() addScheduleDto: AddScheduleDto, ) { try { - const device = await this.scheduleService.addDeviceSchedule( + const schedule = await this.scheduleService.addDeviceSchedule( deviceUuid, addScheduleDto, ); @@ -45,7 +46,7 @@ export class ScheduleController { statusCode: HttpStatus.CREATED, success: true, message: 'schedule added successfully', - data: device, + data: schedule, }; } catch (error) { throw new HttpException( @@ -118,4 +119,30 @@ export class ScheduleController { ); } } + @ApiBearerAuth() + @UseGuards(JwtAuthGuard) + @Put(':deviceUuid') + async updateDeviceSchedule( + @Param('deviceUuid') deviceUuid: string, + @Body() updateScheduleDto: UpdateScheduleDto, + ) { + try { + const schedule = await this.scheduleService.updateDeviceSchedule( + deviceUuid, + updateScheduleDto, + ); + + return { + statusCode: HttpStatus.CREATED, + success: true, + message: 'schedule updated successfully', + data: schedule, + }; + } catch (error) { + throw new HttpException( + error.message || 'Internal server error', + error.status || HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } } diff --git a/src/schedule/dtos/schedule.dto.ts b/src/schedule/dtos/schedule.dto.ts index 550519c..09b2156 100644 --- a/src/schedule/dtos/schedule.dto.ts +++ b/src/schedule/dtos/schedule.dto.ts @@ -91,3 +91,48 @@ export class GetScheduleDeviceDto { @IsNotEmpty() public category: string; } + +export class UpdateScheduleDto { + @ApiProperty({ + description: 'scheduleId', + required: true, + }) + @IsString() + @IsNotEmpty() + public scheduleId: string; + @ApiProperty({ + description: 'category', + required: true, + }) + @IsString() + @IsNotEmpty() + public category: string; + + @ApiProperty({ + description: 'time', + required: true, + }) + @IsString() + @IsNotEmpty() + public time: string; + + @ApiProperty({ + description: 'function', + required: true, + type: FunctionDto, + }) + @ValidateNested() + @Type(() => FunctionDto) + public function: FunctionDto; + + @ApiProperty({ + description: 'days', + enum: WorkingDays, + isArray: true, + required: true, + }) + @IsArray() + @IsEnum(WorkingDays, { each: true }) + @IsNotEmpty() + public days: WorkingDays[]; +} diff --git a/src/schedule/services/schedule.service.ts b/src/schedule/services/schedule.service.ts index c4717e6..634d120 100644 --- a/src/schedule/services/schedule.service.ts +++ b/src/schedule/services/schedule.service.ts @@ -1,7 +1,11 @@ import { Injectable, HttpException, HttpStatus } from '@nestjs/common'; import { TuyaContext } from '@tuya/tuya-connector-nodejs'; import { ConfigService } from '@nestjs/config'; -import { AddScheduleDto, EnableScheduleDto } from '../dtos/schedule.dto'; +import { + AddScheduleDto, + EnableScheduleDto, + UpdateScheduleDto, +} from '../dtos/schedule.dto'; import { addScheduleDeviceInterface, getDeviceScheduleInterface, @@ -282,4 +286,73 @@ export class ScheduleService { ...(withProductDevice && { relations: ['productDevice'] }), }); } + async updateDeviceSchedule( + deviceUuid: string, + updateScheduleDto: UpdateScheduleDto, + ) { + try { + const deviceDetails = await this.getDeviceByDeviceUuid(deviceUuid); + + if (!deviceDetails || !deviceDetails.deviceTuyaUuid) { + throw new HttpException('Device Not Found', HttpStatus.NOT_FOUND); + } + + // Corrected condition for supported device types + if ( + deviceDetails.productDevice.prodType !== ProductType.THREE_G && + deviceDetails.productDevice.prodType !== ProductType.ONE_G && + deviceDetails.productDevice.prodType !== ProductType.TWO_G && + deviceDetails.productDevice.prodType !== ProductType.WH + ) { + throw new HttpException( + 'This device is not supported for schedule', + HttpStatus.BAD_REQUEST, + ); + } + await this.updateScheduleDeviceInTuya( + deviceDetails.deviceTuyaUuid, + updateScheduleDto, + ); + } catch (error) { + throw new HttpException( + error.message || 'Error While Updating Schedule', + error.status || HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } + async updateScheduleDeviceInTuya( + deviceId: string, + updateScheduleDto: UpdateScheduleDto, + ): Promise { + try { + const convertedTime = convertTimestampToDubaiTime(updateScheduleDto.time); + const loops = getScheduleStatus(updateScheduleDto.days); + + const path = `/v2.0/cloud/timer/device/${deviceId}`; + const response = await this.tuya.request({ + method: 'PUT', + path, + body: { + timer_id: updateScheduleDto.scheduleId, + time: convertedTime.time, + timezone_id: 'Asia/Dubai', + loops: `${loops}`, + functions: [ + { + code: updateScheduleDto.function.code, + value: updateScheduleDto.function.value, + }, + ], + category: `category_${updateScheduleDto.category}`, + }, + }); + + return response as addScheduleDeviceInterface; + } catch (error) { + throw new HttpException( + 'Error updating schedule from Tuya', + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } }