mirror of
https://github.com/SyncrowIOT/backend.git
synced 2026-10-25 22:57:55 +00:00
get devices
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import { ControllerRoute } from '@app/common/constants/controller-route';
|
||||
import { Controller, Get, Param, UseGuards } from '@nestjs/common';
|
||||
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { SubspaceDeviceService } from '../services/space-device.service';
|
||||
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
|
||||
import { GetSpaceParam } from '../dtos';
|
||||
import { BaseResponseDto } from '@app/common/dto/base.response.dto';
|
||||
|
||||
@ApiTags('Space Module')
|
||||
@Controller({
|
||||
version: '1',
|
||||
path: ControllerRoute.SPACE_DEVICES.ROUTE,
|
||||
})
|
||||
export class SubSpaceDeviceController {
|
||||
constructor(private readonly spaceDeviceService: SubspaceDeviceService) {}
|
||||
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiOperation({
|
||||
summary: ControllerRoute.SPACE_DEVICES.ACTIONS.LIST_SPACE_DEVICE_SUMMARY,
|
||||
description:
|
||||
ControllerRoute.SPACE_DEVICES.ACTIONS.LIST_SPACE_DEVICE_DESCRIPTION,
|
||||
})
|
||||
@Get()
|
||||
async listDevicesInSpace(
|
||||
@Param() params: GetSpaceParam,
|
||||
): Promise<BaseResponseDto> {
|
||||
return await this.spaceDeviceService.listDevicesInSpace(params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import { TuyaService } from '@app/common/integrations/tuya/tuya.service';
|
||||
import { CommunityRepository } from '@app/common/modules/community/repositories';
|
||||
import { SpaceRepository } from '@app/common/modules/space/repositories';
|
||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
import { GetDeviceDetailsInterface } from 'src/device/interfaces/get.device.interface';
|
||||
import { GetSpaceParam } from '../dtos';
|
||||
import { BaseResponseDto } from '@app/common/dto/base.response.dto';
|
||||
import { SuccessResponseDto } from '@app/common/dto/success.response.dto';
|
||||
import { convertKeysToCamelCase } from '@app/common/helper/camelCaseConverter';
|
||||
import { ProductRepository } from '@app/common/modules/product/repositories';
|
||||
|
||||
@Injectable()
|
||||
export class SubspaceDeviceService {
|
||||
constructor(
|
||||
private readonly spaceRepository: SpaceRepository,
|
||||
private readonly tuyaService: TuyaService,
|
||||
private readonly productRepository: ProductRepository,
|
||||
private readonly communityRepository: CommunityRepository,
|
||||
) {}
|
||||
|
||||
async listDevicesInSpace(params: GetSpaceParam): Promise<BaseResponseDto> {
|
||||
const { spaceUuid, communityUuid } = params;
|
||||
|
||||
const space = await this.validateCommunityAndSpace(
|
||||
communityUuid,
|
||||
spaceUuid,
|
||||
);
|
||||
|
||||
const detailedDevices = await Promise.all(
|
||||
space.devices.map(async (device) => {
|
||||
const tuyaDetails = await this.getDeviceDetailsByDeviceIdTuya(
|
||||
device.deviceTuyaUuid,
|
||||
);
|
||||
|
||||
return {
|
||||
uuid: device.uuid,
|
||||
deviceTuyaUuid: device.deviceTuyaUuid,
|
||||
productUuid: device.productDevice.uuid,
|
||||
productType: device.productDevice.prodType,
|
||||
isActive: device.isActive,
|
||||
createdAt: device.createdAt,
|
||||
updatedAt: device.updatedAt,
|
||||
...tuyaDetails,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
return new SuccessResponseDto({
|
||||
data: detailedDevices,
|
||||
message: 'Successfully retrieved list of devices',
|
||||
});
|
||||
}
|
||||
|
||||
private async validateCommunityAndSpace(
|
||||
communityUuid: string,
|
||||
spaceUuid: string,
|
||||
) {
|
||||
const community = await this.communityRepository.findOne({
|
||||
where: { uuid: communityUuid },
|
||||
});
|
||||
if (!community) {
|
||||
this.throwNotFound('Community', communityUuid);
|
||||
}
|
||||
|
||||
const space = await this.spaceRepository.findOne({
|
||||
where: { uuid: spaceUuid, community: { uuid: communityUuid } },
|
||||
relations: ['devices', 'devices.productDevice'],
|
||||
});
|
||||
if (!space) {
|
||||
this.throwNotFound('Space', spaceUuid);
|
||||
}
|
||||
return space;
|
||||
}
|
||||
|
||||
private throwNotFound(entity: string, uuid: string) {
|
||||
throw new HttpException(
|
||||
`${entity} with ID ${uuid} not found`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
private async getDeviceDetailsByDeviceIdTuya(
|
||||
deviceId: string,
|
||||
): Promise<GetDeviceDetailsInterface> {
|
||||
try {
|
||||
// Fetch details from TuyaService
|
||||
const tuyaDeviceDetails =
|
||||
await this.tuyaService.getDeviceDetails(deviceId);
|
||||
|
||||
// Convert keys to camel case
|
||||
const camelCaseResponse = convertKeysToCamelCase(tuyaDeviceDetails);
|
||||
|
||||
const product = await this.productRepository.findOne({
|
||||
where: {
|
||||
prodId: camelCaseResponse.productId,
|
||||
},
|
||||
});
|
||||
|
||||
// Exclude specific keys and add `productUuid`
|
||||
const { ...rest } = camelCaseResponse;
|
||||
return {
|
||||
...rest,
|
||||
productUuid: product?.uuid,
|
||||
} as GetDeviceDetailsInterface;
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
'Error fetching device details from Tuya',
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,10 @@ import {
|
||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
import { DeviceSubSpaceParam, GetSubSpaceParam } from '../../dtos';
|
||||
import { CommunityRepository } from '@app/common/modules/community/repositories';
|
||||
import { convertKeysToCamelCase } from '@app/common/helper/camelCaseConverter';
|
||||
import { TuyaService } from '@app/common/integrations/tuya/tuya.service';
|
||||
import { ProductRepository } from '@app/common/modules/product/repositories';
|
||||
import { GetDeviceDetailsInterface } from '../../../device/interfaces/get.device.interface';
|
||||
|
||||
@Injectable()
|
||||
export class SubspaceDeviceService {
|
||||
@@ -16,6 +20,8 @@ export class SubspaceDeviceService {
|
||||
private readonly communityRepository: CommunityRepository,
|
||||
private readonly subspaceRepository: SubspaceRepository,
|
||||
private readonly deviceRepository: DeviceRepository,
|
||||
private readonly tuyaService: TuyaService,
|
||||
private readonly productRepository: ProductRepository,
|
||||
) {}
|
||||
|
||||
async listDevicesInSubspace(
|
||||
@@ -26,12 +32,31 @@ export class SubspaceDeviceService {
|
||||
await this.validateCommunityAndSpace(communityUuid, spaceUuid);
|
||||
|
||||
const subspace = await this.findSubspaceWithDevices(subSpaceUuid);
|
||||
|
||||
const detailedDevices = await Promise.all(
|
||||
subspace.devices.map(async (device) => {
|
||||
const tuyaDetails = await this.getDeviceDetailsByDeviceIdTuya(
|
||||
device.deviceTuyaUuid,
|
||||
);
|
||||
|
||||
return {
|
||||
uuid: device.uuid,
|
||||
deviceTuyaUuid: device.deviceTuyaUuid,
|
||||
productUuid: device.productDevice.uuid,
|
||||
productType: device.productDevice.prodType,
|
||||
isActive: device.isActive,
|
||||
createdAt: device.createdAt,
|
||||
updatedAt: device.updatedAt,
|
||||
...tuyaDetails,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
return new SuccessResponseDto({
|
||||
data: subspace.devices,
|
||||
data: detailedDevices,
|
||||
message: 'Successfully retrieved list of devices',
|
||||
});
|
||||
}
|
||||
|
||||
async associateDeviceToSubspace(params: DeviceSubSpaceParam) {
|
||||
const { subSpaceUuid, deviceUuid, spaceUuid, communityUuid } = params;
|
||||
|
||||
@@ -91,7 +116,7 @@ export class SubspaceDeviceService {
|
||||
private async findSubspaceWithDevices(subSpaceUuid: string) {
|
||||
const subspace = await this.subspaceRepository.findOne({
|
||||
where: { uuid: subSpaceUuid },
|
||||
relations: ['devices'],
|
||||
relations: ['devices', 'devices.productDevice'],
|
||||
});
|
||||
if (!subspace) {
|
||||
this.throwNotFound('Subspace', subSpaceUuid);
|
||||
@@ -125,4 +150,35 @@ export class SubspaceDeviceService {
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
private async getDeviceDetailsByDeviceIdTuya(
|
||||
deviceId: string,
|
||||
): Promise<GetDeviceDetailsInterface> {
|
||||
try {
|
||||
// Fetch details from TuyaService
|
||||
const tuyaDeviceDetails =
|
||||
await this.tuyaService.getDeviceDetails(deviceId);
|
||||
|
||||
// Convert keys to camel case
|
||||
const camelCaseResponse = convertKeysToCamelCase(tuyaDeviceDetails);
|
||||
|
||||
const product = await this.productRepository.findOne({
|
||||
where: {
|
||||
prodId: camelCaseResponse.productId,
|
||||
},
|
||||
});
|
||||
|
||||
// Exclude specific keys and add `productUuid`
|
||||
const { ...rest } = camelCaseResponse;
|
||||
return {
|
||||
...rest,
|
||||
productUuid: product?.uuid,
|
||||
} as GetDeviceDetailsInterface;
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
'Error fetching device details from Tuya',
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import {
|
||||
UserSpaceRepository,
|
||||
} from '@app/common/modules/user/repositories';
|
||||
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
||||
import { TuyaService } from '@app/common/integrations/tuya/tuya.service';
|
||||
import { ProductRepository } from '@app/common/modules/product/repositories';
|
||||
|
||||
@Module({
|
||||
imports: [ConfigModule, SpaceRepositoryModule],
|
||||
@@ -34,6 +36,8 @@ import { DeviceRepository } from '@app/common/modules/device/repositories';
|
||||
],
|
||||
providers: [
|
||||
SpaceService,
|
||||
TuyaService,
|
||||
ProductRepository,
|
||||
SubSpaceService,
|
||||
SubspaceDeviceService,
|
||||
SpaceRepository,
|
||||
|
||||
Reference in New Issue
Block a user