mirror of
https://github.com/SyncrowIOT/backend.git
synced 2026-10-23 08:07:55 +00:00
Merge branch 'dev' of https://github.com/SyncrowIOT/backend into dev
This commit is contained in:
@@ -10,7 +10,13 @@ import { GetDeviceDetailsFunctionsStatusInterface } from 'src/device/interfaces/
|
||||
import { TuyaContext } from '@tuya/tuya-connector-nodejs';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { firebaseDataBase } from '../../firebase.config';
|
||||
import { Database, DataSnapshot, get, ref, set } from 'firebase/database';
|
||||
import {
|
||||
Database,
|
||||
DataSnapshot,
|
||||
get,
|
||||
ref,
|
||||
runTransaction,
|
||||
} from 'firebase/database';
|
||||
import { DeviceStatusLogRepository } from '@app/common/modules/device-status-log/repositories';
|
||||
@Injectable()
|
||||
export class DeviceStatusFirebaseService {
|
||||
@@ -154,39 +160,48 @@ export class DeviceStatusFirebaseService {
|
||||
this.firebaseDb,
|
||||
`device-status/${addDeviceStatusDto.deviceUuid}`,
|
||||
);
|
||||
const snapshot: DataSnapshot = await get(dataRef);
|
||||
const existingData = snapshot.val() || {};
|
||||
|
||||
// Assign default values if fields are not present
|
||||
if (!existingData.deviceTuyaUuid) {
|
||||
existingData.deviceTuyaUuid = addDeviceStatusDto.deviceTuyaUuid;
|
||||
}
|
||||
if (!existingData.productUuid) {
|
||||
existingData.productUuid = addDeviceStatusDto.productUuid;
|
||||
}
|
||||
if (!existingData.productType) {
|
||||
existingData.productType = addDeviceStatusDto.productType;
|
||||
}
|
||||
if (!existingData.status) {
|
||||
existingData.status = [];
|
||||
}
|
||||
// Use a transaction to handle concurrent updates
|
||||
await runTransaction(dataRef, (existingData) => {
|
||||
if (!existingData) {
|
||||
existingData = {};
|
||||
}
|
||||
|
||||
// Create a map to track existing status codes
|
||||
const statusMap = new Map(
|
||||
existingData.status.map((item) => [item.code, item.value]),
|
||||
);
|
||||
// Assign default values if fields are not present
|
||||
if (!existingData.deviceTuyaUuid) {
|
||||
existingData.deviceTuyaUuid = addDeviceStatusDto.deviceTuyaUuid;
|
||||
}
|
||||
if (!existingData.productUuid) {
|
||||
existingData.productUuid = addDeviceStatusDto.productUuid;
|
||||
}
|
||||
if (!existingData.productType) {
|
||||
existingData.productType = addDeviceStatusDto.productType;
|
||||
}
|
||||
if (!existingData.status) {
|
||||
existingData.status = [];
|
||||
}
|
||||
|
||||
// Update or add status codes
|
||||
// Create a map to track existing status codes
|
||||
const statusMap = new Map(
|
||||
existingData.status.map((item) => [item.code, item.value]),
|
||||
);
|
||||
|
||||
for (const statusItem of addDeviceStatusDto.status) {
|
||||
statusMap.set(statusItem.code, statusItem.value);
|
||||
}
|
||||
// Update or add status codes
|
||||
|
||||
// Convert the map back to an array format
|
||||
existingData.status = Array.from(statusMap, ([code, value]) => ({
|
||||
code,
|
||||
value,
|
||||
}));
|
||||
for (const statusItem of addDeviceStatusDto.status) {
|
||||
statusMap.set(statusItem.code, statusItem.value);
|
||||
}
|
||||
|
||||
// Convert the map back to an array format
|
||||
existingData.status = Array.from(statusMap, ([code, value]) => ({
|
||||
code,
|
||||
value,
|
||||
}));
|
||||
|
||||
return existingData;
|
||||
});
|
||||
|
||||
// Save logs to your repository
|
||||
const newLogs = addDeviceStatusDto.log.properties.map((property) => {
|
||||
return this.deviceStatusLogRepository.create({
|
||||
deviceId: addDeviceStatusDto.deviceUuid,
|
||||
@@ -200,10 +215,9 @@ export class DeviceStatusFirebaseService {
|
||||
});
|
||||
});
|
||||
await this.deviceStatusLogRepository.save(newLogs);
|
||||
// Save the updated data to Firebase
|
||||
await set(dataRef, existingData);
|
||||
|
||||
// Return the updated data
|
||||
return existingData;
|
||||
const snapshot: DataSnapshot = await get(dataRef);
|
||||
return snapshot.val();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1021,10 +1021,13 @@ export class DeviceService {
|
||||
}
|
||||
}
|
||||
|
||||
const spaceHierarchy = await this.getFullSpaceHierarchy(
|
||||
const spaceHierarchy = await this.getParentHierarchy(
|
||||
device?.spaceDevice,
|
||||
);
|
||||
const orderedHierarchy = spaceHierarchy.reverse();
|
||||
const orderedHierarchy = [
|
||||
device?.spaceDevice,
|
||||
...spaceHierarchy.reverse(),
|
||||
];
|
||||
|
||||
return {
|
||||
spaces: orderedHierarchy.map((space) => ({
|
||||
@@ -1515,4 +1518,32 @@ export class DeviceService {
|
||||
}
|
||||
return project;
|
||||
}
|
||||
|
||||
async getParentHierarchy(
|
||||
space: SpaceEntity,
|
||||
): Promise<{ uuid: string; spaceName: string }[]> {
|
||||
try {
|
||||
const targetSpace = await this.spaceRepository.findOne({
|
||||
where: { uuid: space.uuid },
|
||||
relations: ['parent'],
|
||||
});
|
||||
|
||||
if (!targetSpace) {
|
||||
throw new HttpException('Space not found', HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
const ancestors = await this.fetchAncestors(targetSpace);
|
||||
|
||||
return ancestors.map((parentSpace) => ({
|
||||
uuid: parentSpace.uuid,
|
||||
spaceName: parentSpace.spaceName,
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error('Error fetching parent hierarchy:', error.message);
|
||||
throw new HttpException(
|
||||
'Error fetching parent hierarchy',
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,10 +32,10 @@ export class SpaceDeviceService {
|
||||
);
|
||||
}
|
||||
|
||||
// Fetch space hierarchy **once** and reverse it to get an ordered hierarchy
|
||||
const spaceHierarchy =
|
||||
await this.validationService.getFullSpaceHierarchy(space);
|
||||
const orderedHierarchy = spaceHierarchy.reverse();
|
||||
await this.validationService.getParentHierarchy(space);
|
||||
|
||||
const orderedHierarchy = [space, ...spaceHierarchy.reverse()];
|
||||
|
||||
// Fetch Tuya details for each device in parallel using Promise.allSettled
|
||||
const deviceDetailsPromises = space.devices.map((device) =>
|
||||
|
||||
@@ -222,4 +222,32 @@ export class ValidationService {
|
||||
|
||||
return descendants;
|
||||
}
|
||||
|
||||
async getParentHierarchy(
|
||||
space: SpaceEntity,
|
||||
): Promise<{ uuid: string; spaceName: string }[]> {
|
||||
try {
|
||||
const targetSpace = await this.spaceRepository.findOne({
|
||||
where: { uuid: space.uuid },
|
||||
relations: ['parent'],
|
||||
});
|
||||
|
||||
if (!targetSpace) {
|
||||
throw new HttpException('Space not found', HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
const ancestors = await this.fetchAncestors(targetSpace);
|
||||
|
||||
return ancestors.map((parentSpace) => ({
|
||||
uuid: parentSpace.uuid,
|
||||
spaceName: parentSpace.spaceName,
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error('Error fetching parent hierarchy:', error.message);
|
||||
throw new HttpException(
|
||||
'Error fetching parent hierarchy',
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user