From 2a1f1f52f6fa3e54681e4d7f2041247722dcb626 Mon Sep 17 00:00:00 2001 From: faris Aljohari <83524184+farisaljohari@users.noreply.github.com> Date: Sun, 4 May 2025 19:11:14 +0300 Subject: [PATCH 1/3] feat: add presence sensor module with entity, DTO, and repository --- libs/common/src/database/database.module.ts | 2 ++ .../modules/device/entities/device.entity.ts | 3 ++ .../src/modules/presence-sensor/dtos/index.ts | 1 + .../dtos/presence-sensor.dto.ts | 27 ++++++++++++++++ .../modules/presence-sensor/entities/index.ts | 1 + .../entities/presence-sensor.entity.ts | 31 +++++++++++++++++++ .../presence-sensor.repository.module.ts | 11 +++++++ .../presence-sensor/repositories/index.ts | 1 + .../presence-sensor.repository.ts | 10 ++++++ 9 files changed, 87 insertions(+) create mode 100644 libs/common/src/modules/presence-sensor/dtos/index.ts create mode 100644 libs/common/src/modules/presence-sensor/dtos/presence-sensor.dto.ts create mode 100644 libs/common/src/modules/presence-sensor/entities/index.ts create mode 100644 libs/common/src/modules/presence-sensor/entities/presence-sensor.entity.ts create mode 100644 libs/common/src/modules/presence-sensor/presence-sensor.repository.module.ts create mode 100644 libs/common/src/modules/presence-sensor/repositories/index.ts create mode 100644 libs/common/src/modules/presence-sensor/repositories/presence-sensor.repository.ts diff --git a/libs/common/src/database/database.module.ts b/libs/common/src/database/database.module.ts index fa83c76..f65cb1d 100644 --- a/libs/common/src/database/database.module.ts +++ b/libs/common/src/database/database.module.ts @@ -51,6 +51,7 @@ import { PowerClampHourlyEntity, PowerClampMonthlyEntity, } from '../modules/power-clamp/entities/power-clamp.entity'; +import { PresenceSensorDailyEntity } from '../modules/presence-sensor/entities'; @Module({ imports: [ TypeOrmModule.forRootAsync({ @@ -109,6 +110,7 @@ import { PowerClampHourlyEntity, PowerClampDailyEntity, PowerClampMonthlyEntity, + PresenceSensorDailyEntity, ], namingStrategy: new SnakeNamingStrategy(), synchronize: Boolean(JSON.parse(configService.get('DB_SYNC'))), diff --git a/libs/common/src/modules/device/entities/device.entity.ts b/libs/common/src/modules/device/entities/device.entity.ts index 9015c40..4dc9519 100644 --- a/libs/common/src/modules/device/entities/device.entity.ts +++ b/libs/common/src/modules/device/entities/device.entity.ts @@ -18,6 +18,7 @@ import { SpaceEntity } from '../../space/entities/space.entity'; import { SubspaceEntity } from '../../space/entities/subspace/subspace.entity'; import { NewTagEntity } from '../../tag'; import { PowerClampHourlyEntity } from '../../power-clamp/entities/power-clamp.entity'; +import { PresenceSensorDailyEntity } from '../../presence-sensor/entities'; @Entity({ name: 'device' }) @Unique(['deviceTuyaUuid']) @@ -82,6 +83,8 @@ export class DeviceEntity extends AbstractEntity { public tag: NewTagEntity; @OneToMany(() => PowerClampHourlyEntity, (powerClamp) => powerClamp.device) powerClampHourly: PowerClampHourlyEntity[]; + @OneToMany(() => PresenceSensorDailyEntity, (sensor) => sensor.device) + presenceSensorDaily: PresenceSensorDailyEntity[]; constructor(partial: Partial) { super(); Object.assign(this, partial); diff --git a/libs/common/src/modules/presence-sensor/dtos/index.ts b/libs/common/src/modules/presence-sensor/dtos/index.ts new file mode 100644 index 0000000..9993c83 --- /dev/null +++ b/libs/common/src/modules/presence-sensor/dtos/index.ts @@ -0,0 +1 @@ +export * from './presence-sensor.dto'; diff --git a/libs/common/src/modules/presence-sensor/dtos/presence-sensor.dto.ts b/libs/common/src/modules/presence-sensor/dtos/presence-sensor.dto.ts new file mode 100644 index 0000000..e37f9db --- /dev/null +++ b/libs/common/src/modules/presence-sensor/dtos/presence-sensor.dto.ts @@ -0,0 +1,27 @@ +import { IsNotEmpty, IsNumber, IsString } from 'class-validator'; + +export class PresenceSensorDto { + @IsString() + @IsNotEmpty() + public uuid: string; + + @IsString() + @IsNotEmpty() + public deviceUuid: string; + + @IsString() + @IsNotEmpty() + public eventDate: string; + + @IsNumber() + @IsNotEmpty() + public CountMotionDetected: number; + + @IsNumber() + @IsNotEmpty() + public CountPresenceDetected: number; + + @IsNumber() + @IsNotEmpty() + public CountTotalPresenceDetected: number; +} diff --git a/libs/common/src/modules/presence-sensor/entities/index.ts b/libs/common/src/modules/presence-sensor/entities/index.ts new file mode 100644 index 0000000..b578244 --- /dev/null +++ b/libs/common/src/modules/presence-sensor/entities/index.ts @@ -0,0 +1 @@ +export * from './presence-sensor.entity'; diff --git a/libs/common/src/modules/presence-sensor/entities/presence-sensor.entity.ts b/libs/common/src/modules/presence-sensor/entities/presence-sensor.entity.ts new file mode 100644 index 0000000..710b245 --- /dev/null +++ b/libs/common/src/modules/presence-sensor/entities/presence-sensor.entity.ts @@ -0,0 +1,31 @@ +import { Column, Entity, ManyToOne, Unique } from 'typeorm'; +import { AbstractEntity } from '../../abstract/entities/abstract.entity'; +import { PresenceSensorDto } from '../dtos'; +import { DeviceEntity } from '../../device/entities/device.entity'; + +@Entity({ name: 'presence-sensor-daily-detection' }) +@Unique(['deviceUuid', 'eventDate']) +export class PresenceSensorDailyEntity extends AbstractEntity { + @Column({ nullable: false }) + public deviceUuid: string; + + @Column({ nullable: false, type: 'date' }) + public eventDate: string; + + @Column({ nullable: false }) + public CountMotionDetected: number; + + @Column({ nullable: false }) + public CountPresenceDetected: number; + + @Column({ nullable: false }) + public CountTotalPresenceDetected: number; + + @ManyToOne(() => DeviceEntity, (device) => device.presenceSensorDaily) + device: DeviceEntity; + + constructor(partial: Partial) { + super(); + Object.assign(this, partial); + } +} diff --git a/libs/common/src/modules/presence-sensor/presence-sensor.repository.module.ts b/libs/common/src/modules/presence-sensor/presence-sensor.repository.module.ts new file mode 100644 index 0000000..54849b2 --- /dev/null +++ b/libs/common/src/modules/presence-sensor/presence-sensor.repository.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { PresenceSensorDailyEntity } from './entities/presence-sensor.entity'; + +@Module({ + providers: [], + exports: [], + controllers: [], + imports: [TypeOrmModule.forFeature([PresenceSensorDailyEntity])], +}) +export class PresenceSensorRepositoryModule {} diff --git a/libs/common/src/modules/presence-sensor/repositories/index.ts b/libs/common/src/modules/presence-sensor/repositories/index.ts new file mode 100644 index 0000000..8b64ee8 --- /dev/null +++ b/libs/common/src/modules/presence-sensor/repositories/index.ts @@ -0,0 +1 @@ +export * from './presence-sensor.repository'; diff --git a/libs/common/src/modules/presence-sensor/repositories/presence-sensor.repository.ts b/libs/common/src/modules/presence-sensor/repositories/presence-sensor.repository.ts new file mode 100644 index 0000000..2dcd8bc --- /dev/null +++ b/libs/common/src/modules/presence-sensor/repositories/presence-sensor.repository.ts @@ -0,0 +1,10 @@ +import { DataSource, Repository } from 'typeorm'; +import { Injectable } from '@nestjs/common'; +import { PresenceSensorDailyEntity } from '../entities'; + +@Injectable() +export class PresenceSensorDailyRepository extends Repository { + constructor(private dataSource: DataSource) { + super(PresenceSensorDailyEntity, dataSource.createEntityManager()); + } +} From e538f2b8290a1ead0cc883916f04391fef957fe9 Mon Sep 17 00:00:00 2001 From: Dona Maria Absi <49731027+DonaAbsi@users.noreply.github.com> Date: Tue, 6 May 2025 11:28:43 +0300 Subject: [PATCH 2/3] grain change --- ..._daily_space_energy_consumed_procedure.sql | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 libs/common/src/sql/procedures/fact_space_energy_consumed/fact_daily_space_energy_consumed_procedure.sql diff --git a/libs/common/src/sql/procedures/fact_space_energy_consumed/fact_daily_space_energy_consumed_procedure.sql b/libs/common/src/sql/procedures/fact_space_energy_consumed/fact_daily_space_energy_consumed_procedure.sql new file mode 100644 index 0000000..1a127fa --- /dev/null +++ b/libs/common/src/sql/procedures/fact_space_energy_consumed/fact_daily_space_energy_consumed_procedure.sql @@ -0,0 +1,20 @@ +WITH params AS ( + SELECT + TO_DATE(NULLIF($1, ''), 'MM-YYYY') AS start_month, + string_to_array(NULLIF($2, ''), ',') AS device_ids +) + +SELECT + A.date, + SUM(A.energy_consumed_kW::numeric) AS total_energy_consumed_KW, + SUM(A.energy_consumed_A::numeric) AS total_energy_consumed_A, + SUM(A.energy_consumed_B::numeric) AS total_energy_consumed_B, + SUM(A.energy_consumed_C::numeric) AS total_energy_consumed_C +FROM public."power-clamp-energy-consumed-daily" AS A +JOIN public.device AS B + ON A.device_uuid::TEXT = B."uuid"::TEXT +JOIN params P ON TRUE +WHERE B."uuid"::TEXT = ANY(P.device_ids) + AND (P.start_month IS NULL OR date_trunc('month', A.date)= P.start_month) +GROUP BY A.date +ORDER BY A.date; From 0d48505eacdaa624bd8086768ea9e3fae32c6d15 Mon Sep 17 00:00:00 2001 From: Dona Maria Absi <49731027+DonaAbsi@users.noreply.github.com> Date: Tue, 6 May 2025 11:30:23 +0300 Subject: [PATCH 3/3] month name --- .../fact_daily_space_energy_consumed_procedure.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/common/src/sql/procedures/fact_space_energy_consumed/fact_daily_space_energy_consumed_procedure.sql b/libs/common/src/sql/procedures/fact_space_energy_consumed/fact_daily_space_energy_consumed_procedure.sql index 1a127fa..7cd49a5 100644 --- a/libs/common/src/sql/procedures/fact_space_energy_consumed/fact_daily_space_energy_consumed_procedure.sql +++ b/libs/common/src/sql/procedures/fact_space_energy_consumed/fact_daily_space_energy_consumed_procedure.sql @@ -1,6 +1,6 @@ WITH params AS ( SELECT - TO_DATE(NULLIF($1, ''), 'MM-YYYY') AS start_month, + TO_DATE(NULLIF($1, ''), 'MM-YYYY') AS month, string_to_array(NULLIF($2, ''), ',') AS device_ids ) @@ -15,6 +15,6 @@ JOIN public.device AS B ON A.device_uuid::TEXT = B."uuid"::TEXT JOIN params P ON TRUE WHERE B."uuid"::TEXT = ANY(P.device_ids) - AND (P.start_month IS NULL OR date_trunc('month', A.date)= P.start_month) + AND (P.month IS NULL OR date_trunc('month', A.date)= P.month) GROUP BY A.date ORDER BY A.date;