mirror of
https://github.com/SyncrowIOT/backend.git
synced 2026-10-24 09:07:55 +00:00
Merge branch 'dev' into SP-197-be-retrieve-devices-in-the-gateway
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
HttpException,
|
||||
HttpStatus,
|
||||
UseGuards,
|
||||
Req,
|
||||
} from '@nestjs/common';
|
||||
import { ApiTags, ApiBearerAuth } from '@nestjs/swagger';
|
||||
import {
|
||||
@@ -22,6 +23,8 @@ import {
|
||||
import { ControlDeviceDto } from '../dtos/control.device.dto';
|
||||
import { CheckRoomGuard } from 'src/guards/room.guard';
|
||||
import { CheckGroupGuard } from 'src/guards/group.guard';
|
||||
import { CheckUserHavePermission } from 'src/guards/user.device.permission.guard';
|
||||
import { CheckUserHaveControllablePermission } from 'src/guards/user.device.controllable.permission.guard';
|
||||
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
|
||||
|
||||
@ApiTags('Device Module')
|
||||
@@ -37,10 +40,13 @@ export class DeviceController {
|
||||
@Get('room')
|
||||
async getDevicesByRoomId(
|
||||
@Query() getDeviceByRoomUuidDto: GetDeviceByRoomUuidDto,
|
||||
@Req() req: any,
|
||||
) {
|
||||
try {
|
||||
const userUuid = req.user.uuid;
|
||||
return await this.deviceService.getDevicesByRoomId(
|
||||
getDeviceByRoomUuidDto,
|
||||
userUuid,
|
||||
);
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
@@ -55,7 +61,15 @@ export class DeviceController {
|
||||
@Post('room')
|
||||
async addDeviceInRoom(@Body() addDeviceInRoomDto: AddDeviceInRoomDto) {
|
||||
try {
|
||||
return await this.deviceService.addDeviceInRoom(addDeviceInRoomDto);
|
||||
const device =
|
||||
await this.deviceService.addDeviceInRoom(addDeviceInRoomDto);
|
||||
|
||||
return {
|
||||
statusCode: HttpStatus.CREATED,
|
||||
success: true,
|
||||
message: 'device added in room successfully',
|
||||
data: device,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
error.message || 'Internal server error',
|
||||
@@ -68,10 +82,13 @@ export class DeviceController {
|
||||
@Get('group')
|
||||
async getDevicesByGroupId(
|
||||
@Query() getDeviceByGroupIdDto: GetDeviceByGroupIdDto,
|
||||
@Req() req: any,
|
||||
) {
|
||||
try {
|
||||
const userUuid = req.user.uuid;
|
||||
return await this.deviceService.getDevicesByGroupId(
|
||||
getDeviceByGroupIdDto,
|
||||
userUuid,
|
||||
);
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
@@ -94,11 +111,18 @@ export class DeviceController {
|
||||
}
|
||||
}
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseGuards(JwtAuthGuard, CheckUserHavePermission)
|
||||
@Get(':deviceUuid')
|
||||
async getDeviceDetailsByDeviceId(@Param('deviceUuid') deviceUuid: string) {
|
||||
async getDeviceDetailsByDeviceId(
|
||||
@Param('deviceUuid') deviceUuid: string,
|
||||
@Req() req: any,
|
||||
) {
|
||||
try {
|
||||
return await this.deviceService.getDeviceDetailsByDeviceId(deviceUuid);
|
||||
const userUuid = req.user.uuid;
|
||||
return await this.deviceService.getDeviceDetailsByDeviceId(
|
||||
deviceUuid,
|
||||
userUuid,
|
||||
);
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
error.message || 'Internal server error',
|
||||
@@ -107,7 +131,7 @@ export class DeviceController {
|
||||
}
|
||||
}
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseGuards(JwtAuthGuard, CheckUserHavePermission)
|
||||
@Get(':deviceUuid/functions')
|
||||
async getDeviceInstructionByDeviceId(
|
||||
@Param('deviceUuid') deviceUuid: string,
|
||||
@@ -124,7 +148,7 @@ export class DeviceController {
|
||||
}
|
||||
}
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseGuards(JwtAuthGuard, CheckUserHavePermission)
|
||||
@Get(':deviceUuid/functions/status')
|
||||
async getDevicesInstructionStatus(@Param('deviceUuid') deviceUuid: string) {
|
||||
try {
|
||||
@@ -138,11 +162,17 @@ export class DeviceController {
|
||||
}
|
||||
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Post('control')
|
||||
async controlDevice(@Body() controlDeviceDto: ControlDeviceDto) {
|
||||
@UseGuards(JwtAuthGuard, CheckUserHaveControllablePermission)
|
||||
@Post(':deviceUuid/control')
|
||||
async controlDevice(
|
||||
@Body() controlDeviceDto: ControlDeviceDto,
|
||||
@Param('deviceUuid') deviceUuid: string,
|
||||
) {
|
||||
try {
|
||||
return await this.deviceService.controlDevice(controlDeviceDto);
|
||||
return await this.deviceService.controlDevice(
|
||||
controlDeviceDto,
|
||||
deviceUuid,
|
||||
);
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
error.message || 'Internal server error',
|
||||
|
||||
@@ -5,15 +5,14 @@ import { ConfigModule } from '@nestjs/config';
|
||||
import { ProductRepositoryModule } from '@app/common/modules/product/product.repository.module';
|
||||
import { ProductRepository } from '@app/common/modules/product/repositories';
|
||||
import { DeviceRepositoryModule } from '@app/common/modules/device';
|
||||
import {
|
||||
DeviceRepository,
|
||||
DeviceUserTypeRepository,
|
||||
} from '@app/common/modules/device/repositories';
|
||||
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
||||
import { PermissionTypeRepository } from '@app/common/modules/permission/repositories';
|
||||
import { SpaceRepository } from '@app/common/modules/space/repositories';
|
||||
import { GroupDeviceRepository } from '@app/common/modules/group-device/repositories';
|
||||
import { GroupRepository } from '@app/common/modules/group/repositories';
|
||||
import { GroupRepositoryModule } from '@app/common/modules/group/group.repository.module';
|
||||
import { DeviceUserPermissionRepository } from '@app/common/modules/device-user-permission/repositories';
|
||||
import { UserRepository } from '@app/common/modules/user/repositories';
|
||||
@Module({
|
||||
imports: [
|
||||
ConfigModule,
|
||||
@@ -25,12 +24,13 @@ import { GroupRepositoryModule } from '@app/common/modules/group/group.repositor
|
||||
providers: [
|
||||
DeviceService,
|
||||
ProductRepository,
|
||||
DeviceUserTypeRepository,
|
||||
DeviceUserPermissionRepository,
|
||||
PermissionTypeRepository,
|
||||
SpaceRepository,
|
||||
DeviceRepository,
|
||||
GroupDeviceRepository,
|
||||
GroupRepository,
|
||||
UserRepository,
|
||||
],
|
||||
exports: [DeviceService],
|
||||
})
|
||||
|
||||
@@ -2,14 +2,6 @@ import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsNotEmpty, IsString } from 'class-validator';
|
||||
|
||||
export class ControlDeviceDto {
|
||||
@ApiProperty({
|
||||
description: 'deviceUuid',
|
||||
required: true,
|
||||
})
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
public deviceUuid: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'code',
|
||||
required: true,
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
HttpException,
|
||||
HttpStatus,
|
||||
NotFoundException,
|
||||
BadRequestException,
|
||||
} from '@nestjs/common';
|
||||
import { TuyaContext } from '@tuya/tuya-connector-nodejs';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
@@ -18,7 +17,6 @@ import {
|
||||
GetDeviceDetailsFunctionsStatusInterface,
|
||||
GetDeviceDetailsInterface,
|
||||
controlDeviceInterface,
|
||||
updateDeviceFirmwareInterface,
|
||||
} from '../interfaces/get.device.interface';
|
||||
import {
|
||||
GetDeviceByGroupIdDto,
|
||||
@@ -29,6 +27,8 @@ 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/product-type.enum';
|
||||
import { PermissionType } from '@app/common/constants/permission-type.enum';
|
||||
import { In } from 'typeorm';
|
||||
|
||||
@Injectable()
|
||||
export class DeviceService {
|
||||
@@ -50,13 +50,25 @@ export class DeviceService {
|
||||
|
||||
async getDevicesByRoomId(
|
||||
getDeviceByRoomUuidDto: GetDeviceByRoomUuidDto,
|
||||
userUuid: string,
|
||||
): Promise<GetDeviceDetailsInterface[]> {
|
||||
try {
|
||||
const devices = await this.deviceRepository.find({
|
||||
where: {
|
||||
spaceDevice: { uuid: getDeviceByRoomUuidDto.roomUuid },
|
||||
permission: {
|
||||
userUuid,
|
||||
permissionType: {
|
||||
type: In([PermissionType.READ, PermissionType.CONTROLLABLE]),
|
||||
},
|
||||
},
|
||||
},
|
||||
relations: ['spaceDevice', 'productDevice'],
|
||||
relations: [
|
||||
'spaceDevice',
|
||||
'productDevice',
|
||||
'permission',
|
||||
'permission.permissionType',
|
||||
],
|
||||
});
|
||||
const devicesData = await Promise.all(
|
||||
devices.map(async (device) => {
|
||||
@@ -67,9 +79,11 @@ export class DeviceService {
|
||||
uuid: device.uuid,
|
||||
productUuid: device.productDevice.uuid,
|
||||
productType: device.productDevice.prodType,
|
||||
permissionType: device.permission[0].permissionType.type,
|
||||
} as GetDeviceDetailsInterface;
|
||||
}),
|
||||
);
|
||||
|
||||
return devicesData;
|
||||
} catch (error) {
|
||||
// Handle the error here
|
||||
@@ -80,11 +94,29 @@ export class DeviceService {
|
||||
}
|
||||
}
|
||||
|
||||
async getDevicesByGroupId(getDeviceByGroupIdDto: GetDeviceByGroupIdDto) {
|
||||
async getDevicesByGroupId(
|
||||
getDeviceByGroupIdDto: GetDeviceByGroupIdDto,
|
||||
userUuid: string,
|
||||
) {
|
||||
try {
|
||||
const groupDevices = await this.groupDeviceRepository.find({
|
||||
where: { group: { uuid: getDeviceByGroupIdDto.groupUuid } },
|
||||
relations: ['device'],
|
||||
where: {
|
||||
group: { uuid: getDeviceByGroupIdDto.groupUuid },
|
||||
device: {
|
||||
permission: {
|
||||
userUuid,
|
||||
permissionType: {
|
||||
type: PermissionType.READ || PermissionType.CONTROLLABLE,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
relations: [
|
||||
'device',
|
||||
'device.productDevice',
|
||||
'device.permission',
|
||||
'device.permission.permissionType',
|
||||
],
|
||||
});
|
||||
const devicesData = await Promise.all(
|
||||
groupDevices.map(async (device) => {
|
||||
@@ -92,9 +124,10 @@ export class DeviceService {
|
||||
...(await this.getDeviceDetailsByDeviceIdTuya(
|
||||
device.device.deviceTuyaUuid,
|
||||
)),
|
||||
uuid: device.uuid,
|
||||
uuid: device.device.uuid,
|
||||
productUuid: device.device.productDevice.uuid,
|
||||
productType: device.device.productDevice.prodType,
|
||||
permissionType: device.device.permission[0].permissionType.type,
|
||||
} as GetDeviceDetailsInterface;
|
||||
}),
|
||||
);
|
||||
@@ -107,7 +140,6 @@ export class DeviceService {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async addDeviceInRoom(addDeviceInRoomDto: AddDeviceInRoomDto) {
|
||||
try {
|
||||
const device = await this.getDeviceDetailsByDeviceIdTuya(
|
||||
@@ -118,12 +150,11 @@ export class DeviceService {
|
||||
throw new Error('Product UUID is missing for the device.');
|
||||
}
|
||||
|
||||
await this.deviceRepository.save({
|
||||
return await this.deviceRepository.save({
|
||||
deviceTuyaUuid: addDeviceInRoomDto.deviceTuyaUuid,
|
||||
spaceDevice: { uuid: addDeviceInRoomDto.roomUuid },
|
||||
productDevice: { uuid: device.productUuid },
|
||||
});
|
||||
return { message: 'device added in room successfully' };
|
||||
} catch (error) {
|
||||
if (error.code === '23505') {
|
||||
throw new HttpException(
|
||||
@@ -161,12 +192,9 @@ export class DeviceService {
|
||||
}
|
||||
}
|
||||
|
||||
async controlDevice(controlDeviceDto: ControlDeviceDto) {
|
||||
async controlDevice(controlDeviceDto: ControlDeviceDto, deviceUuid: string) {
|
||||
try {
|
||||
const deviceDetails = await this.getDeviceByDeviceUuid(
|
||||
controlDeviceDto.deviceUuid,
|
||||
false,
|
||||
);
|
||||
const deviceDetails = await this.getDeviceByDeviceUuid(deviceUuid, false);
|
||||
|
||||
if (!deviceDetails || !deviceDetails.deviceTuyaUuid) {
|
||||
throw new NotFoundException('Device Not Found');
|
||||
@@ -185,7 +213,10 @@ export class DeviceService {
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
throw new HttpException('Device Not Found', HttpStatus.NOT_FOUND);
|
||||
throw new HttpException(
|
||||
error.message || 'Device Not Found',
|
||||
error.status || HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
}
|
||||
async controlDeviceTuya(
|
||||
@@ -213,8 +244,19 @@ export class DeviceService {
|
||||
}
|
||||
}
|
||||
|
||||
async getDeviceDetailsByDeviceId(deviceUuid: string) {
|
||||
async getDeviceDetailsByDeviceId(deviceUuid: string, userUuid: string) {
|
||||
try {
|
||||
const userDevicePermission = await this.getUserDevicePermission(
|
||||
userUuid,
|
||||
deviceUuid,
|
||||
);
|
||||
|
||||
const deviceDetails = await this.deviceRepository.findOne({
|
||||
where: {
|
||||
uuid: deviceUuid,
|
||||
},
|
||||
relations: ['productDevice'],
|
||||
});
|
||||
const deviceDetails = await this.getDeviceByDeviceUuid(deviceUuid);
|
||||
|
||||
if (!deviceDetails) {
|
||||
@@ -230,9 +272,13 @@ export class DeviceService {
|
||||
uuid: deviceDetails.uuid,
|
||||
productUuid: deviceDetails.productDevice.uuid,
|
||||
productType: deviceDetails.productDevice.prodType,
|
||||
permissionType: userDevicePermission,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new HttpException('Device Not Found', HttpStatus.NOT_FOUND);
|
||||
throw new HttpException(
|
||||
error.message || 'Device Not Found',
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
}
|
||||
async getDeviceDetailsByDeviceIdTuya(
|
||||
@@ -255,6 +301,7 @@ export class DeviceService {
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { productName, productId, id, ...rest } = camelCaseResponse.result;
|
||||
|
||||
return {
|
||||
...rest,
|
||||
productUuid: product.uuid,
|
||||
@@ -465,4 +512,13 @@ export class DeviceService {
|
||||
);
|
||||
}
|
||||
}
|
||||
private async getUserDevicePermission(userUuid: string, deviceUuid: string) {
|
||||
const device = await this.deviceRepository.findOne({
|
||||
where: {
|
||||
uuid: deviceUuid,
|
||||
},
|
||||
relations: ['permission', 'permission.permissionType'],
|
||||
});
|
||||
return device.permission[0].permissionType.type;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user