mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-11-27 10:24:55 +00:00
fix: enhance device status handling by integrating device cache for improved performance
This commit is contained in:
@ -8,7 +8,10 @@ import { TuyaWebSocketService } from './services/tuya.web.socket.service';
|
||||
import { OneSignalService } from './services/onesignal.service';
|
||||
import { DeviceMessagesService } from './services/device.messages.service';
|
||||
import { DeviceRepositoryModule } from '../modules/device/device.repository.module';
|
||||
import { DeviceNotificationRepository } from '../modules/device/repositories';
|
||||
import {
|
||||
DeviceNotificationRepository,
|
||||
DeviceRepository,
|
||||
} from '../modules/device/repositories';
|
||||
import { DeviceStatusFirebaseModule } from '../firebase/devices-status/devices-status.module';
|
||||
import { CommunityPermissionService } from './services/community.permission.service';
|
||||
import { CommunityRepository } from '../modules/community/repositories';
|
||||
@ -27,6 +30,7 @@ import { SosHandlerService } from './services/sos.handler.service';
|
||||
DeviceNotificationRepository,
|
||||
CommunityRepository,
|
||||
SosHandlerService,
|
||||
DeviceRepository,
|
||||
],
|
||||
exports: [
|
||||
HelperHashService,
|
||||
|
||||
@ -16,35 +16,53 @@ export class SosHandlerService {
|
||||
);
|
||||
}
|
||||
|
||||
async handleSosEventFirebase(devId: string, logData: any): Promise<void> {
|
||||
async handleSosEventFirebase(
|
||||
devId: string,
|
||||
logData: any,
|
||||
deviceCache: Map<string, any>,
|
||||
): Promise<void> {
|
||||
try {
|
||||
await this.deviceStatusFirebaseService.addDeviceStatusToFirebase({
|
||||
deviceTuyaUuid: devId,
|
||||
status: [{ code: 'sos', value: true }],
|
||||
log: logData,
|
||||
});
|
||||
await this.deviceStatusFirebaseService.addBatchDeviceStatusToOurDb([
|
||||
await this.deviceStatusFirebaseService.addDeviceStatusToFirebase(
|
||||
{
|
||||
deviceTuyaUuid: devId,
|
||||
status: [{ code: 'sos', value: true }],
|
||||
log: logData,
|
||||
},
|
||||
]);
|
||||
deviceCache,
|
||||
);
|
||||
|
||||
await this.deviceStatusFirebaseService.addBatchDeviceStatusToOurDb(
|
||||
[
|
||||
{
|
||||
deviceTuyaUuid: devId,
|
||||
status: [{ code: 'sos', value: true }],
|
||||
log: logData,
|
||||
},
|
||||
],
|
||||
deviceCache,
|
||||
);
|
||||
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
await this.deviceStatusFirebaseService.addDeviceStatusToFirebase({
|
||||
deviceTuyaUuid: devId,
|
||||
status: [{ code: 'sos', value: false }],
|
||||
log: logData,
|
||||
});
|
||||
await this.deviceStatusFirebaseService.addBatchDeviceStatusToOurDb([
|
||||
await this.deviceStatusFirebaseService.addDeviceStatusToFirebase(
|
||||
{
|
||||
deviceTuyaUuid: devId,
|
||||
status: [{ code: 'sos', value: false }],
|
||||
log: logData,
|
||||
},
|
||||
]);
|
||||
deviceCache,
|
||||
);
|
||||
|
||||
await this.deviceStatusFirebaseService.addBatchDeviceStatusToOurDb(
|
||||
[
|
||||
{
|
||||
deviceTuyaUuid: devId,
|
||||
status: [{ code: 'sos', value: false }],
|
||||
log: logData,
|
||||
},
|
||||
],
|
||||
deviceCache,
|
||||
);
|
||||
} catch (err) {
|
||||
this.logger.error('Failed to send SOS false value', err);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ import TuyaWebsocket from '../../config/tuya-web-socket-config';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { DeviceStatusFirebaseService } from '@app/common/firebase/devices-status/services/devices-status.service';
|
||||
import { SosHandlerService } from './sos.handler.service';
|
||||
import { DeviceRepository } from '@app/common/modules/device/repositories';
|
||||
|
||||
@Injectable()
|
||||
export class TuyaWebSocketService {
|
||||
@ -16,11 +17,13 @@ export class TuyaWebSocketService {
|
||||
}[] = [];
|
||||
|
||||
private isProcessing = false;
|
||||
private deviceCache: Map<string, any> = new Map();
|
||||
|
||||
constructor(
|
||||
private readonly configService: ConfigService,
|
||||
private readonly deviceStatusFirebaseService: DeviceStatusFirebaseService,
|
||||
private readonly sosHandlerService: SosHandlerService,
|
||||
private readonly deviceRepository: DeviceRepository,
|
||||
) {
|
||||
this.isDevEnv =
|
||||
this.configService.get<string>('NODE_ENV') === 'development';
|
||||
@ -33,6 +36,11 @@ export class TuyaWebSocketService {
|
||||
maxRetryTimes: 100,
|
||||
});
|
||||
|
||||
this.loadAllActiveDevices();
|
||||
|
||||
// Reload device cache every 1 hour
|
||||
setInterval(() => this.loadAllActiveDevices(), 60 * 60 * 1000);
|
||||
|
||||
if (this.configService.get<string>('tuya-config.TRUN_ON_TUYA_SOCKET')) {
|
||||
this.setupEventHandlers();
|
||||
this.client.start();
|
||||
@ -42,6 +50,22 @@ export class TuyaWebSocketService {
|
||||
setInterval(() => this.processQueue(), 15000);
|
||||
}
|
||||
|
||||
private async loadAllActiveDevices(): Promise<void> {
|
||||
const devices = await this.deviceRepository.find({
|
||||
where: { isActive: true },
|
||||
relations: ['productDevice'],
|
||||
});
|
||||
|
||||
this.deviceCache.clear();
|
||||
devices.forEach((device) => {
|
||||
this.deviceCache.set(device.deviceTuyaUuid, device);
|
||||
});
|
||||
|
||||
console.log(
|
||||
`🔄 Device cache reloaded: ${this.deviceCache.size} active devices at ${new Date().toISOString()}`,
|
||||
);
|
||||
}
|
||||
|
||||
private setupEventHandlers() {
|
||||
// Event handlers
|
||||
this.client.open(() => {
|
||||
@ -51,18 +75,30 @@ export class TuyaWebSocketService {
|
||||
this.client.message(async (ws: WebSocket, message: any) => {
|
||||
try {
|
||||
const { devId, status, logData } = this.extractMessageData(message);
|
||||
if (!Array.isArray(logData?.properties)) {
|
||||
if (!Array.isArray(logData?.properties)) return;
|
||||
|
||||
const device = this.deviceCache.get(devId);
|
||||
if (!device) {
|
||||
// console.log(`⛔ Ignored unknown device: ${devId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.sosHandlerService.isSosTriggered(status)) {
|
||||
await this.sosHandlerService.handleSosEventFirebase(devId, logData);
|
||||
await this.sosHandlerService.handleSosEventFirebase(
|
||||
devId,
|
||||
logData,
|
||||
this.deviceCache,
|
||||
);
|
||||
} else {
|
||||
// Firebase real-time update
|
||||
await this.deviceStatusFirebaseService.addDeviceStatusToFirebase({
|
||||
deviceTuyaUuid: devId,
|
||||
status: status,
|
||||
log: logData,
|
||||
});
|
||||
await this.deviceStatusFirebaseService.addDeviceStatusToFirebase(
|
||||
{
|
||||
deviceTuyaUuid: devId,
|
||||
status,
|
||||
log: logData,
|
||||
},
|
||||
this.deviceCache,
|
||||
);
|
||||
}
|
||||
|
||||
// Push to internal queue
|
||||
@ -111,11 +147,12 @@ export class TuyaWebSocketService {
|
||||
|
||||
try {
|
||||
await this.deviceStatusFirebaseService.addBatchDeviceStatusToOurDb(
|
||||
batch?.map((item) => ({
|
||||
batch.map((item) => ({
|
||||
deviceTuyaUuid: item.devId,
|
||||
status: item.status,
|
||||
log: item.logData,
|
||||
})),
|
||||
this.deviceCache,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('❌ Error processing batch:', error);
|
||||
|
||||
Reference in New Issue
Block a user