mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-11-27 10:54:54 +00:00
Compare commits
1 Commits
SP-1780-be
...
SP-1779-be
| Author | SHA1 | Date | |
|---|---|---|---|
| 58ba81fb4f |
@ -15,7 +15,6 @@ export enum ProductType {
|
||||
WL = 'WL',
|
||||
GD = 'GD',
|
||||
CUR = 'CUR',
|
||||
CUR_2 = 'CUR_2',
|
||||
PC = 'PC',
|
||||
FOUR_S = '4S',
|
||||
SIX_S = '6S',
|
||||
|
||||
@ -190,26 +190,24 @@ export class CommunityService {
|
||||
.distinct(true);
|
||||
|
||||
if (includeSpaces) {
|
||||
qb.leftJoinAndSelect(
|
||||
'c.spaces',
|
||||
'space',
|
||||
'space.disabled = :disabled AND space.spaceName != :orphanSpaceName',
|
||||
{ disabled: false, orphanSpaceName: ORPHAN_SPACE_NAME },
|
||||
)
|
||||
qb.leftJoinAndSelect('c.spaces', 'space', 'space.disabled = false')
|
||||
.leftJoinAndSelect('space.parent', 'parent')
|
||||
.leftJoinAndSelect(
|
||||
'space.children',
|
||||
'children',
|
||||
'children.disabled = :disabled',
|
||||
{ disabled: false },
|
||||
);
|
||||
// .leftJoinAndSelect('space.spaceModel', 'spaceModel')
|
||||
)
|
||||
// .leftJoinAndSelect('space.spaceModel', 'spaceModel')
|
||||
.andWhere('space.spaceName != :orphanSpaceName', {
|
||||
orphanSpaceName: ORPHAN_SPACE_NAME,
|
||||
})
|
||||
.andWhere('space.disabled = :disabled', { disabled: false });
|
||||
}
|
||||
|
||||
if (search) {
|
||||
qb.andWhere(
|
||||
`c.name ILIKE :search ${includeSpaces ? 'OR space.space_name ILIKE :search' : ''}`,
|
||||
{ search },
|
||||
`c.name ILIKE '%${search}%' ${includeSpaces ? "OR space.space_name ILIKE '%" + search + "%'" : ''}`,
|
||||
);
|
||||
}
|
||||
|
||||
@ -217,21 +215,12 @@ export class CommunityService {
|
||||
|
||||
const { baseResponseDto, paginationResponseDto } =
|
||||
await customModel.findAll({ ...pageable, modelName: 'community' }, qb);
|
||||
if (includeSpaces) {
|
||||
baseResponseDto.data = baseResponseDto.data.map((community) => ({
|
||||
...community,
|
||||
spaces: this.spaceService.buildSpaceHierarchy(community.spaces || []),
|
||||
}));
|
||||
}
|
||||
return new PageResponse<CommunityDto>(
|
||||
baseResponseDto,
|
||||
paginationResponseDto,
|
||||
);
|
||||
} catch (error) {
|
||||
// Generic error handling
|
||||
if (error instanceof HttpException) {
|
||||
throw error;
|
||||
}
|
||||
throw new HttpException(
|
||||
error.message || 'An error occurred while fetching communities.',
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
interface BaseCommand {
|
||||
code: string;
|
||||
value: any;
|
||||
}
|
||||
export interface ControlCur2Command extends BaseCommand {
|
||||
code: 'control';
|
||||
value: 'open' | 'close' | 'stop';
|
||||
}
|
||||
export interface ControlCur2PercentCommand extends BaseCommand {
|
||||
code: 'percent_control';
|
||||
value: 10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 90 | 100;
|
||||
}
|
||||
export interface ControlCur2AccurateCalibrationCommand extends BaseCommand {
|
||||
code: 'accurate_calibration';
|
||||
value: 'start' | 'end'; // Assuming this is a numeric value for calibration
|
||||
}
|
||||
export interface ControlCur2TDirectionConCommand extends BaseCommand {
|
||||
code: 'control_t_direction_con';
|
||||
value: 'forward' | 'back';
|
||||
}
|
||||
export interface ControlCur2QuickCalibrationCommand extends BaseCommand {
|
||||
code: 'tr_timecon';
|
||||
value: number; // between 10 and 120
|
||||
}
|
||||
export interface ControlCur2MotorModeCommand extends BaseCommand {
|
||||
code: 'elec_machinery_mode';
|
||||
value: 'strong_power' | 'dry_contact';
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
import {
|
||||
ControlCur2AccurateCalibrationCommand,
|
||||
ControlCur2Command,
|
||||
ControlCur2PercentCommand,
|
||||
ControlCur2QuickCalibrationCommand,
|
||||
ControlCur2TDirectionConCommand,
|
||||
} from 'src/device/commands/cur2-commands';
|
||||
|
||||
export enum ScheduleProductType {
|
||||
CUR_2 = 'CUR_2',
|
||||
}
|
||||
export const DeviceFunctionMap: {
|
||||
[T in ScheduleProductType]: (body: DeviceFunction[T]) => any;
|
||||
} = {
|
||||
[ScheduleProductType.CUR_2]: ({ code, value }) => {
|
||||
return [
|
||||
{
|
||||
code,
|
||||
value,
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
type DeviceFunction = {
|
||||
[ScheduleProductType.CUR_2]:
|
||||
| ControlCur2Command
|
||||
| ControlCur2PercentCommand
|
||||
| ControlCur2AccurateCalibrationCommand
|
||||
| ControlCur2TDirectionConCommand
|
||||
| ControlCur2QuickCalibrationCommand;
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
|
||||
import { TuyaContext } from '@tuya/tuya-connector-nodejs';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import {
|
||||
AddScheduleDto,
|
||||
EnableScheduleDto,
|
||||
@ -11,14 +11,14 @@ import {
|
||||
getDeviceScheduleInterface,
|
||||
} from '../interfaces/get.schedule.interface';
|
||||
|
||||
import { ProductType } from '@app/common/constants/product-type.enum';
|
||||
import { convertKeysToCamelCase } from '@app/common/helper/camelCaseConverter';
|
||||
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
||||
import { ProductType } from '@app/common/constants/product-type.enum';
|
||||
import { convertTimestampToDubaiTime } from '@app/common/helper/convertTimestampToDubaiTime';
|
||||
import {
|
||||
getEnabledDays,
|
||||
getScheduleStatus,
|
||||
} from '@app/common/helper/getScheduleStatus';
|
||||
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
||||
|
||||
@Injectable()
|
||||
export class ScheduleService {
|
||||
@ -49,11 +49,22 @@ export class ScheduleService {
|
||||
}
|
||||
|
||||
// Corrected condition for supported device types
|
||||
this.ensureProductTypeSupportedForSchedule(
|
||||
ProductType[deviceDetails.productDevice.prodType],
|
||||
);
|
||||
|
||||
return this.enableScheduleDeviceInTuya(
|
||||
if (
|
||||
deviceDetails.productDevice.prodType !== ProductType.THREE_G &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.ONE_G &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.TWO_G &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.WH &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.ONE_1TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.TWO_2TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.THREE_3TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.GD
|
||||
) {
|
||||
throw new HttpException(
|
||||
'This device is not supported for schedule',
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
}
|
||||
return await this.enableScheduleDeviceInTuya(
|
||||
deviceDetails.deviceTuyaUuid,
|
||||
enableScheduleDto,
|
||||
);
|
||||
@ -64,6 +75,29 @@ export class ScheduleService {
|
||||
);
|
||||
}
|
||||
}
|
||||
async enableScheduleDeviceInTuya(
|
||||
deviceId: string,
|
||||
enableScheduleDto: EnableScheduleDto,
|
||||
): Promise<addScheduleDeviceInterface> {
|
||||
try {
|
||||
const path = `/v2.0/cloud/timer/device/${deviceId}/state`;
|
||||
const response = await this.tuya.request({
|
||||
method: 'PUT',
|
||||
path,
|
||||
body: {
|
||||
enable: enableScheduleDto.enable,
|
||||
timer_id: enableScheduleDto.scheduleId,
|
||||
},
|
||||
});
|
||||
|
||||
return response as addScheduleDeviceInterface;
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
'Error while updating schedule from Tuya',
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
async deleteDeviceSchedule(deviceUuid: string, scheduleId: string) {
|
||||
try {
|
||||
const deviceDetails = await this.getDeviceByDeviceUuid(deviceUuid);
|
||||
@ -73,10 +107,21 @@ export class ScheduleService {
|
||||
}
|
||||
|
||||
// Corrected condition for supported device types
|
||||
this.ensureProductTypeSupportedForSchedule(
|
||||
ProductType[deviceDetails.productDevice.prodType],
|
||||
);
|
||||
|
||||
if (
|
||||
deviceDetails.productDevice.prodType !== ProductType.THREE_G &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.ONE_G &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.TWO_G &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.WH &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.ONE_1TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.TWO_2TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.THREE_3TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.GD
|
||||
) {
|
||||
throw new HttpException(
|
||||
'This device is not supported for schedule',
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
}
|
||||
return await this.deleteScheduleDeviceInTuya(
|
||||
deviceDetails.deviceTuyaUuid,
|
||||
scheduleId,
|
||||
@ -88,6 +133,25 @@ export class ScheduleService {
|
||||
);
|
||||
}
|
||||
}
|
||||
async deleteScheduleDeviceInTuya(
|
||||
deviceId: string,
|
||||
scheduleId: string,
|
||||
): Promise<addScheduleDeviceInterface> {
|
||||
try {
|
||||
const path = `/v2.0/cloud/timer/device/${deviceId}/batch?timer_ids=${scheduleId}`;
|
||||
const response = await this.tuya.request({
|
||||
method: 'DELETE',
|
||||
path,
|
||||
});
|
||||
|
||||
return response as addScheduleDeviceInterface;
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
'Error while deleting schedule from Tuya',
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
async addDeviceSchedule(deviceUuid: string, addScheduleDto: AddScheduleDto) {
|
||||
try {
|
||||
const deviceDetails = await this.getDeviceByDeviceUuid(deviceUuid);
|
||||
@ -96,10 +160,22 @@ export class ScheduleService {
|
||||
throw new HttpException('Device Not Found', HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
this.ensureProductTypeSupportedForSchedule(
|
||||
ProductType[deviceDetails.productDevice.prodType],
|
||||
);
|
||||
|
||||
// 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 &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.ONE_1TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.TWO_2TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.THREE_3TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.GD
|
||||
) {
|
||||
throw new HttpException(
|
||||
'This device is not supported for schedule',
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
}
|
||||
await this.addScheduleDeviceInTuya(
|
||||
deviceDetails.deviceTuyaUuid,
|
||||
addScheduleDto,
|
||||
@ -111,6 +187,40 @@ export class ScheduleService {
|
||||
);
|
||||
}
|
||||
}
|
||||
async addScheduleDeviceInTuya(
|
||||
deviceId: string,
|
||||
addScheduleDto: AddScheduleDto,
|
||||
): Promise<addScheduleDeviceInterface> {
|
||||
try {
|
||||
const convertedTime = convertTimestampToDubaiTime(addScheduleDto.time);
|
||||
const loops = getScheduleStatus(addScheduleDto.days);
|
||||
|
||||
const path = `/v2.0/cloud/timer/device/${deviceId}`;
|
||||
const response = await this.tuya.request({
|
||||
method: 'POST',
|
||||
path,
|
||||
body: {
|
||||
time: convertedTime.time,
|
||||
timezone_id: 'Asia/Dubai',
|
||||
loops: `${loops}`,
|
||||
functions: [
|
||||
{
|
||||
code: addScheduleDto.function.code,
|
||||
value: addScheduleDto.function.value,
|
||||
},
|
||||
],
|
||||
category: `category_${addScheduleDto.category}`,
|
||||
},
|
||||
});
|
||||
|
||||
return response as addScheduleDeviceInterface;
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
'Error adding schedule from Tuya',
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
async getDeviceScheduleByCategory(deviceUuid: string, category: string) {
|
||||
try {
|
||||
const deviceDetails = await this.getDeviceByDeviceUuid(deviceUuid);
|
||||
@ -119,10 +229,21 @@ export class ScheduleService {
|
||||
throw new HttpException('Device Not Found', HttpStatus.NOT_FOUND);
|
||||
}
|
||||
// Corrected condition for supported device types
|
||||
this.ensureProductTypeSupportedForSchedule(
|
||||
ProductType[deviceDetails.productDevice.prodType],
|
||||
);
|
||||
|
||||
if (
|
||||
deviceDetails.productDevice.prodType !== ProductType.THREE_G &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.ONE_G &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.TWO_G &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.WH &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.ONE_1TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.TWO_2TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.THREE_3TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.GD
|
||||
) {
|
||||
throw new HttpException(
|
||||
'This device is not supported for schedule',
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
}
|
||||
const schedules = await this.getScheduleDeviceInTuya(
|
||||
deviceDetails.deviceTuyaUuid,
|
||||
category,
|
||||
@ -149,82 +270,7 @@ export class ScheduleService {
|
||||
);
|
||||
}
|
||||
}
|
||||
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
|
||||
this.ensureProductTypeSupportedForSchedule(
|
||||
ProductType[deviceDetails.productDevice.prodType],
|
||||
);
|
||||
|
||||
await this.updateScheduleDeviceInTuya(
|
||||
deviceDetails.deviceTuyaUuid,
|
||||
updateScheduleDto,
|
||||
);
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
error.message || 'Error While Updating Schedule',
|
||||
error.status || HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private getDeviceByDeviceUuid(
|
||||
deviceUuid: string,
|
||||
withProductDevice: boolean = true,
|
||||
) {
|
||||
return this.deviceRepository.findOne({
|
||||
where: {
|
||||
uuid: deviceUuid,
|
||||
isActive: true,
|
||||
},
|
||||
...(withProductDevice && { relations: ['productDevice'] }),
|
||||
});
|
||||
}
|
||||
|
||||
private async addScheduleDeviceInTuya(
|
||||
deviceId: string,
|
||||
addScheduleDto: AddScheduleDto,
|
||||
): Promise<addScheduleDeviceInterface> {
|
||||
try {
|
||||
const convertedTime = convertTimestampToDubaiTime(addScheduleDto.time);
|
||||
const loops = getScheduleStatus(addScheduleDto.days);
|
||||
|
||||
const path = `/v2.0/cloud/timer/device/${deviceId}`;
|
||||
const response = await this.tuya.request({
|
||||
method: 'POST',
|
||||
path,
|
||||
body: {
|
||||
time: convertedTime.time,
|
||||
timezone_id: 'Asia/Dubai',
|
||||
loops: `${loops}`,
|
||||
functions: [
|
||||
{
|
||||
...addScheduleDto.function,
|
||||
},
|
||||
],
|
||||
category: `category_${addScheduleDto.category}`,
|
||||
},
|
||||
});
|
||||
|
||||
return response as addScheduleDeviceInterface;
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
'Error adding schedule from Tuya',
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async getScheduleDeviceInTuya(
|
||||
async getScheduleDeviceInTuya(
|
||||
deviceId: string,
|
||||
category: string,
|
||||
): Promise<getDeviceScheduleInterface> {
|
||||
@ -245,8 +291,57 @@ export class ScheduleService {
|
||||
);
|
||||
}
|
||||
}
|
||||
async getDeviceByDeviceUuid(
|
||||
deviceUuid: string,
|
||||
withProductDevice: boolean = true,
|
||||
) {
|
||||
return await this.deviceRepository.findOne({
|
||||
where: {
|
||||
uuid: deviceUuid,
|
||||
isActive: true,
|
||||
},
|
||||
...(withProductDevice && { relations: ['productDevice'] }),
|
||||
});
|
||||
}
|
||||
async updateDeviceSchedule(
|
||||
deviceUuid: string,
|
||||
updateScheduleDto: UpdateScheduleDto,
|
||||
) {
|
||||
try {
|
||||
const deviceDetails = await this.getDeviceByDeviceUuid(deviceUuid);
|
||||
|
||||
private async updateScheduleDeviceInTuya(
|
||||
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 &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.ONE_1TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.TWO_2TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.THREE_3TG &&
|
||||
deviceDetails.productDevice.prodType !== ProductType.GD
|
||||
) {
|
||||
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<addScheduleDeviceInterface> {
|
||||
@ -281,69 +376,4 @@ export class ScheduleService {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async enableScheduleDeviceInTuya(
|
||||
deviceId: string,
|
||||
enableScheduleDto: EnableScheduleDto,
|
||||
): Promise<addScheduleDeviceInterface> {
|
||||
try {
|
||||
const path = `/v2.0/cloud/timer/device/${deviceId}/state`;
|
||||
const response = await this.tuya.request({
|
||||
method: 'PUT',
|
||||
path,
|
||||
body: {
|
||||
enable: enableScheduleDto.enable,
|
||||
timer_id: enableScheduleDto.scheduleId,
|
||||
},
|
||||
});
|
||||
|
||||
return response as addScheduleDeviceInterface;
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
'Error while updating schedule from Tuya',
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async deleteScheduleDeviceInTuya(
|
||||
deviceId: string,
|
||||
scheduleId: string,
|
||||
): Promise<addScheduleDeviceInterface> {
|
||||
try {
|
||||
const path = `/v2.0/cloud/timer/device/${deviceId}/batch?timer_ids=${scheduleId}`;
|
||||
const response = await this.tuya.request({
|
||||
method: 'DELETE',
|
||||
path,
|
||||
});
|
||||
|
||||
return response as addScheduleDeviceInterface;
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
'Error while deleting schedule from Tuya',
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private ensureProductTypeSupportedForSchedule(deviceType: ProductType): void {
|
||||
if (
|
||||
![
|
||||
ProductType.THREE_G,
|
||||
ProductType.ONE_G,
|
||||
ProductType.TWO_G,
|
||||
ProductType.WH,
|
||||
ProductType.ONE_1TG,
|
||||
ProductType.TWO_2TG,
|
||||
ProductType.THREE_3TG,
|
||||
ProductType.GD,
|
||||
ProductType.CUR_2,
|
||||
].includes(deviceType)
|
||||
) {
|
||||
throw new HttpException(
|
||||
'This device is not supported for schedule',
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -681,7 +681,7 @@ export class SpaceService {
|
||||
}
|
||||
}
|
||||
|
||||
buildSpaceHierarchy(spaces: SpaceEntity[]): SpaceEntity[] {
|
||||
private buildSpaceHierarchy(spaces: SpaceEntity[]): SpaceEntity[] {
|
||||
const map = new Map<string, SpaceEntity>();
|
||||
|
||||
// Step 1: Create a map of spaces by UUID
|
||||
|
||||
Reference in New Issue
Block a user