diff --git a/libs/common/src/firebase/devices-status/services/devices-status.service.ts b/libs/common/src/firebase/devices-status/services/devices-status.service.ts index 1d201d3..4b0b0f7 100644 --- a/libs/common/src/firebase/devices-status/services/devices-status.service.ts +++ b/libs/common/src/firebase/devices-status/services/devices-status.service.ts @@ -24,7 +24,6 @@ import { PowerClampEnergyEnum } from '@app/common/constants/power.clamp.enargy.e import { PresenceSensorEnum } from '@app/common/constants/presence.sensor.enum'; import { OccupancyService } from '@app/common/helper/services/occupancy.service'; import { AqiDataService } from '@app/common/helper/services/aqi.data.service'; -import { DataSource, QueryRunner } from 'typeorm'; @Injectable() export class DeviceStatusFirebaseService { private tuya: TuyaContext; @@ -36,7 +35,6 @@ export class DeviceStatusFirebaseService { private readonly occupancyService: OccupancyService, private readonly aqiDataService: AqiDataService, private deviceStatusLogRepository: DeviceStatusLogRepository, - private readonly dataSource: DataSource, ) { const accessKey = this.configService.get('auth-config.ACCESS_KEY'); const secretKey = this.configService.get('auth-config.SECRET_KEY'); @@ -81,46 +79,28 @@ export class DeviceStatusFirebaseService { async addDeviceStatusToFirebase( addDeviceStatusDto: AddDeviceStatusDto, ): Promise { - const queryRunner = this.dataSource.createQueryRunner(); - await queryRunner.connect(); - await queryRunner.startTransaction(); try { const device = await this.getDeviceByDeviceTuyaUuid( addDeviceStatusDto.deviceTuyaUuid, - queryRunner, ); if (device?.uuid) { - const result = await this.createDeviceStatusFirebase( - { - deviceUuid: device.uuid, - ...addDeviceStatusDto, - productType: device.productDevice.prodType, - }, - queryRunner, - ); - await queryRunner.commitTransaction(); - return result; + return await this.createDeviceStatusFirebase({ + deviceUuid: device.uuid, + ...addDeviceStatusDto, + productType: device.productDevice.prodType, + }); } // Return null if device not found or no UUID - await queryRunner.rollbackTransaction(); return null; } catch (error) { - await queryRunner.rollbackTransaction(); + // Handle the error silently, perhaps log it internally or ignore it return null; - } finally { - await queryRunner.release(); } } - async getDeviceByDeviceTuyaUuid( - deviceTuyaUuid: string, - queryRunner?: QueryRunner, - ) { - const repo = queryRunner - ? queryRunner.manager.getRepository(this.deviceRepository.target) - : this.deviceRepository; - return await repo.findOne({ + async getDeviceByDeviceTuyaUuid(deviceTuyaUuid: string) { + return await this.deviceRepository.findOne({ where: { deviceTuyaUuid, isActive: true, @@ -128,7 +108,6 @@ export class DeviceStatusFirebaseService { relations: ['productDevice'], }); } - async getDevicesInstructionStatus(deviceUuid: string) { try { const deviceDetails = await this.getDeviceByDeviceUuid(deviceUuid); @@ -174,14 +153,9 @@ export class DeviceStatusFirebaseService { } async getDeviceByDeviceUuid( deviceUuid: string, - withProductDevice = true, - queryRunner?: QueryRunner, + withProductDevice: boolean = true, ) { - const repo = queryRunner - ? queryRunner.manager.getRepository(this.deviceRepository.target) - : this.deviceRepository; - - return await repo.findOne({ + return await this.deviceRepository.findOne({ where: { uuid: deviceUuid, isActive: true, @@ -189,20 +163,21 @@ export class DeviceStatusFirebaseService { ...(withProductDevice && { relations: ['productDevice'] }), }); } - async createDeviceStatusFirebase( addDeviceStatusDto: AddDeviceStatusDto, - queryRunner?: QueryRunner, ): Promise { const dataRef = ref( this.firebaseDb, `device-status/${addDeviceStatusDto.deviceUuid}`, ); - // Step 1: Update Firebase Realtime Database + // Use a transaction to handle concurrent updates await runTransaction(dataRef, (existingData) => { - if (!existingData) existingData = {}; + if (!existingData) { + existingData = {}; + } + // Assign default values if fields are not present if (!existingData.deviceTuyaUuid) { existingData.deviceTuyaUuid = addDeviceStatusDto.deviceTuyaUuid; } @@ -216,15 +191,18 @@ export class DeviceStatusFirebaseService { existingData.status = []; } - // Merge incoming status with existing status + // Create a map to track existing status codes const statusMap = new Map( existingData.status.map((item) => [item.code, item.value]), ); + // Update or add status codes + 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, @@ -233,9 +211,9 @@ export class DeviceStatusFirebaseService { return existingData; }); - // Step 2: Save device status log entries - const newLogs = addDeviceStatusDto.log.properties.map((property) => - this.deviceStatusLogRepository.create({ + // Save logs to your repository + const newLogs = addDeviceStatusDto.log.properties.map((property) => { + return this.deviceStatusLogRepository.create({ deviceId: addDeviceStatusDto.deviceUuid, deviceTuyaId: addDeviceStatusDto.deviceTuyaUuid, productId: addDeviceStatusDto.log.productId, @@ -244,19 +222,10 @@ export class DeviceStatusFirebaseService { value: property.value, eventId: addDeviceStatusDto.log.dataId, eventTime: new Date(property.time).toISOString(), - }), - ); + }); + }); + await this.deviceStatusLogRepository.save(newLogs); - if (queryRunner) { - const repo = queryRunner.manager.getRepository( - this.deviceStatusLogRepository.target, - ); - await repo.save(newLogs); - } else { - await this.deviceStatusLogRepository.save(newLogs); - } - - // Step 3: Trigger additional data services if (addDeviceStatusDto.productType === ProductType.PC) { const energyCodes = new Set([ PowerClampEnergyEnum.ENERGY_CONSUMED, @@ -300,8 +269,7 @@ export class DeviceStatusFirebaseService { addDeviceStatusDto.deviceUuid, ); } - - // Step 4: Return updated Firebase status + // Return the updated data const snapshot: DataSnapshot = await get(dataRef); return snapshot.val(); } diff --git a/libs/common/src/helper/services/aqi.data.service.ts b/libs/common/src/helper/services/aqi.data.service.ts index c8f5c1a..3e19b6c 100644 --- a/libs/common/src/helper/services/aqi.data.service.ts +++ b/libs/common/src/helper/services/aqi.data.service.ts @@ -36,18 +36,9 @@ export class AqiDataService { procedureFileName: string, params: (string | number | null)[], ): Promise { - const queryRunner = this.dataSource.createQueryRunner(); - await queryRunner.connect(); - try { - const query = this.loadQuery(procedureFolderName, procedureFileName); - await queryRunner.query(query, params); - console.log(`Procedure ${procedureFileName} executed successfully.`); - } catch (err) { - console.error(`Failed to execute procedure ${procedureFileName}:`, err); - throw err; - } finally { - await queryRunner.release(); - } + const query = this.loadQuery(procedureFolderName, procedureFileName); + await this.dataSource.query(query, params); + console.log(`Procedure ${procedureFileName} executed successfully.`); } private loadQuery(folderName: string, fileName: string): string { diff --git a/libs/common/src/helper/services/occupancy.service.ts b/libs/common/src/helper/services/occupancy.service.ts index b3d50cf..ea99b7c 100644 --- a/libs/common/src/helper/services/occupancy.service.ts +++ b/libs/common/src/helper/services/occupancy.service.ts @@ -57,18 +57,9 @@ export class OccupancyService { procedureFileName: string, params: (string | number | null)[], ): Promise { - const queryRunner = this.dataSource.createQueryRunner(); - await queryRunner.connect(); - try { - const query = this.loadQuery(procedureFolderName, procedureFileName); - await queryRunner.query(query, params); - console.log(`Procedure ${procedureFileName} executed successfully.`); - } catch (err) { - console.error(`Failed to execute procedure ${procedureFileName}:`, err); - throw err; - } finally { - await queryRunner.release(); - } + const query = this.loadQuery(procedureFolderName, procedureFileName); + await this.dataSource.query(query, params); + console.log(`Procedure ${procedureFileName} executed successfully.`); } private loadQuery(folderName: string, fileName: string): string { diff --git a/libs/common/src/helper/services/power.clamp.service.ts b/libs/common/src/helper/services/power.clamp.service.ts index 6cb667b..7c83208 100644 --- a/libs/common/src/helper/services/power.clamp.service.ts +++ b/libs/common/src/helper/services/power.clamp.service.ts @@ -46,21 +46,12 @@ export class PowerClampService { procedureFileName: string, params: (string | number | null)[], ): Promise { - const queryRunner = this.dataSource.createQueryRunner(); - await queryRunner.connect(); - try { - const query = this.loadQuery( - 'fact_device_energy_consumed', - procedureFileName, - ); - await queryRunner.query(query, params); - console.log(`Procedure ${procedureFileName} executed successfully.`); - } catch (err) { - console.error(`Failed to execute procedure ${procedureFileName}:`, err); - throw err; - } finally { - await queryRunner.release(); - } + const query = this.loadQuery( + 'fact_device_energy_consumed', + procedureFileName, + ); + await this.dataSource.query(query, params); + console.log(`Procedure ${procedureFileName} executed successfully.`); } private loadQuery(folderName: string, fileName: string): string {