Merge branch 'dev' into fix-some-issues-wehn-add-new-device

This commit is contained in:
faris Aljohari
2025-04-14 14:26:13 +03:00
19 changed files with 661 additions and 1 deletions

View File

@ -482,7 +482,15 @@ export class ControllerRoute {
'This endpoint retrieves all devices in a specified group within a space, based on the group name and space UUID.';
};
};
static PowerClamp = class {
public static readonly ROUTE = 'power-clamp';
static ACTIONS = class {
public static readonly GET_ENERGY_SUMMARY = 'Get power clamp data';
public static readonly GET_ENERGY_DESCRIPTION =
'This endpoint retrieves power clamp data for a specific device.';
};
};
static DEVICE = class {
public static readonly ROUTE = 'devices';

View File

@ -0,0 +1 @@
export const SQL_QUERIES_PATH = 'libs/common/src/sql/queries';

View File

@ -0,0 +1,28 @@
import { SQL_QUERIES_PATH } from '@app/common/constants/sql-query-path';
import { Injectable, Logger } from '@nestjs/common';
import { readFileSync } from 'fs';
import { join } from 'path';
@Injectable()
export class SqlLoaderService {
private readonly logger = new Logger(SqlLoaderService.name);
private readonly sqlRootPath = join(__dirname, '../sql/queries');
loadQuery(module: string, queryName: string): string {
const filePath = join(
process.cwd(),
SQL_QUERIES_PATH,
module,
`${queryName}.sql`,
);
try {
return readFileSync(filePath, 'utf8');
} catch (error) {
this.logger.error(
`Failed to load SQL query: ${module}/${queryName}`,
error.stack,
);
throw new Error(`SQL query not found: ${module}/${queryName}`);
}
}
}

View File

@ -0,0 +1,12 @@
select device_id ,
product."name" as "device_type",
event_time::date as date ,
event_time::time as time,
code ,
value
from "device-status-log" dsl
join product
on dsl.product_id = product.prod_id
join device d
on d."uuid" = dsl.device_id
order by 1,3,4

View File

@ -0,0 +1,5 @@
SELECT generate_series(
DATE '2024-01-01', -- Start date
DATE '2065-12-31', -- End date
INTERVAL '1 day' -- Step size
)::DATE AS daily_date;

View File

@ -0,0 +1,66 @@
WITH start_date AS (
SELECT
device.uuid AS device_id,
device.created_at,
device.device_tuya_uuid,
device.space_device_uuid AS space_id,
"device-status-log".event_id,
"device-status-log".event_time::timestamp,
"device-status-log".code,
"device-status-log".value,
"device-status-log".log,
LAG("device-status-log".event_time::timestamp)
OVER (PARTITION BY device.uuid -- Partition only by device.uuid
ORDER BY "device-status-log".event_time) AS prev_timestamp,
LAG("device-status-log".value)
OVER (PARTITION BY device.uuid
ORDER BY "device-status-log".event_time) AS prev_value
FROM device
LEFT JOIN "device-status-log"
ON device.uuid = "device-status-log".device_id
LEFT JOIN product
ON product.uuid = device.product_device_uuid
WHERE product.cat_name = 'hps'
AND "device-status-log".code = 'presence_state'
ORDER BY device.uuid, "device-status-log".event_time
),
time_differences AS (
SELECT
device_id,
value,
prev_value,
event_time,
prev_timestamp,
event_time::date AS event_date,
EXTRACT(EPOCH FROM (event_time - COALESCE(prev_timestamp, event_time))) AS time_diff_in_seconds
FROM start_date
),
duration as (
SELECT
device_id,
event_date,
SUM(CASE WHEN prev_value = 'motion' THEN time_diff_in_seconds ELSE 0 END) AS motion_seconds,
SUM(CASE WHEN prev_value = 'presence' THEN time_diff_in_seconds ELSE 0 END) AS presence_seconds,
SUM(CASE WHEN prev_value = 'none' THEN time_diff_in_seconds ELSE 0 END) AS none_seconds
FROM time_differences
WHERE prev_timestamp::date=event_date
GROUP BY device_id, event_date
ORDER BY device_id, event_date)
, data_final AS(
select device_id,
event_date,
motion_seconds,
CONCAT(FLOOR(motion_seconds / 3600), ':',LPAD(FLOOR((motion_seconds % 3600) / 60)::TEXT, 2, '0'), ':',LPAD(FLOOR(motion_seconds % 60)::TEXT, 2, '0')) AS motion_formatted_duration,
presence_seconds,
CONCAT(FLOOR(presence_seconds / 3600), ':',LPAD(FLOOR((presence_seconds % 3600) / 60)::TEXT, 2, '0'), ':',LPAD(FLOOR(presence_seconds % 60)::TEXT, 2, '0')) AS presence_formatted_duration,
none_seconds,
CONCAT(FLOOR(none_seconds / 3600), ':',LPAD(FLOOR((none_seconds % 3600) / 60)::TEXT, 2, '0'), ':',LPAD(FLOOR(none_seconds % 60)::TEXT, 2, '0')) AS none_formatted_duration
from duration
order by 1,2)
SELECT * FROM data_final

View File

@ -0,0 +1,65 @@
-- model shows the energy consumed per day per device
WITH total_energy AS (
SELECT
device_id,
event_time::date AS date,
MIN(value)::integer AS min_value,
MAX(value)::integer AS max_value
FROM "device-status-log"
where code='EnergyConsumed'
GROUP BY device_id, date
)
, energy_phase_A AS (
SELECT
device_id,
event_time::date AS date,
MIN(value)::integer AS min_value,
MAX(value)::integer AS max_value
FROM "device-status-log"
where code='EnergyConsumedA'
GROUP BY device_id, date
)
, energy_phase_B AS (
SELECT
device_id,
event_time::date AS date,
MIN(value)::integer AS min_value,
MAX(value)::integer AS max_value
FROM "device-status-log"
where code='EnergyConsumedB'
GROUP BY device_id, date
)
, energy_phase_C AS (
SELECT
device_id,
event_time::date AS date,
MIN(value)::integer AS min_value,
MAX(value)::integer AS max_value
FROM "device-status-log"
where code='EnergyConsumedC'
GROUP BY device_id, date
)
SELECT
total_energy.device_id,
total_energy.date,
(total_energy.max_value-total_energy.min_value) as energy_consumed_kW,
(energy_phase_A.max_value-energy_phase_A.min_value) as energy_consumed_A,
(energy_phase_B.max_value-energy_phase_B.min_value) as energy_consumed_B,
(energy_phase_C.max_value-energy_phase_C.min_value) as energy_consumed_C
FROM total_energy
JOIN energy_phase_A
ON total_energy.device_id=energy_phase_A.device_id
and total_energy.date=energy_phase_A.date
JOIN energy_phase_B
ON total_energy.device_id=energy_phase_B.device_id
and total_energy.date=energy_phase_B.date
JOIN energy_phase_C
ON total_energy.device_id=energy_phase_C.device_id
and total_energy.date=energy_phase_C.date

View File

@ -0,0 +1,91 @@
-- Step 1: Get device presence events with previous timestamps
WITH start_date AS (
SELECT
d.uuid AS device_id,
d.space_device_uuid AS space_id,
l.value,
l.event_time::timestamp AS event_time,
LAG(l.event_time::timestamp) OVER (PARTITION BY d.uuid ORDER BY l.event_time) AS prev_timestamp
FROM device d
LEFT JOIN "device-status-log" l
ON d.uuid = l.device_id
LEFT JOIN product p
ON p.uuid = d.product_device_uuid
WHERE p.cat_name = 'hps'
AND l.code = 'presence_state'
),
-- Step 2: Identify periods when device reports "none"
device_none_periods AS (
SELECT
space_id,
device_id,
event_time AS empty_from,
LEAD(event_time) OVER (PARTITION BY device_id ORDER BY event_time) AS empty_until
FROM start_date
WHERE value = 'none'
),
-- Step 3: Clip the "none" periods to the edges of each day
clipped_device_none_periods AS (
SELECT
space_id,
GREATEST(empty_from, DATE_TRUNC('day', empty_from)) AS clipped_from,
LEAST(empty_until, DATE_TRUNC('day', empty_until) + INTERVAL '1 day') AS clipped_until
FROM device_none_periods
WHERE empty_until IS NOT NULL
),
-- Step 4: Break multi-day periods into daily intervals
generated_daily_intervals AS (
SELECT
space_id,
gs::date AS day,
GREATEST(clipped_from, gs) AS interval_start,
LEAST(clipped_until, gs + INTERVAL '1 day') AS interval_end
FROM clipped_device_none_periods,
LATERAL generate_series(DATE_TRUNC('day', clipped_from), DATE_TRUNC('day', clipped_until), INTERVAL '1 day') AS gs
),
-- Step 5: Merge overlapping or adjacent intervals per day
merged_intervals AS (
SELECT
space_id,
day,
interval_start,
interval_end
FROM (
SELECT
space_id,
day,
interval_start,
interval_end,
LAG(interval_end) OVER (PARTITION BY space_id, day ORDER BY interval_start) AS prev_end
FROM generated_daily_intervals
) sub
WHERE prev_end IS NULL OR interval_start > prev_end
),
-- Step 6: Sum up total missing seconds (device reported "none") per day
missing_seconds_per_day AS (
SELECT
space_id,
day AS missing_date,
SUM(EXTRACT(EPOCH FROM (interval_end - interval_start))) AS total_missing_seconds
FROM merged_intervals
GROUP BY space_id, day
),
-- Step 7: Calculate total occupied time per day (86400 - missing)
occupied_seconds_per_day AS (
SELECT
space_id,
missing_date as date,
86400 - total_missing_seconds AS total_occupied_seconds
FROM missing_seconds_per_day
)
-- Final Output
SELECT *
FROM occupied_seconds_per_day
ORDER BY 1,2;

View File

@ -0,0 +1,15 @@
select dup."uuid" as primary_key,
dup.device_uuid,
product.name,
pt.type,
dup.user_uuid as authorized_user_id,
dup.created_at::date as permission_creation_date,
dup.updated_at::date as permission_update_date
from "device-user-permission" dup
left join "permission-type" pt
on dup.permission_type_uuid =pt."uuid"
left join device
on device."uuid" =dup.device_uuid
LEFT JOIN product
ON product.uuid = device.product_device_uuid;

View File

@ -0,0 +1,75 @@
--This model shows the number of times a presence was detected per hour, per day.
WITH device_logs AS (
SELECT
device.uuid AS device_id,
device.created_at,
device.device_tuya_uuid,
device.space_device_uuid AS space_id,
"device-status-log".event_id,
"device-status-log".event_time::timestamp,
"device-status-log".code,
"device-status-log".value,
"device-status-log".log,
LAG("device-status-log".event_time::timestamp)
OVER (PARTITION BY device.uuid
ORDER BY "device-status-log".event_time) AS prev_timestamp,
LAG("device-status-log".value)
OVER (PARTITION BY device.uuid
ORDER BY "device-status-log".event_time) AS prev_value
FROM device
LEFT JOIN "device-status-log"
ON device.uuid = "device-status-log".device_id
LEFT JOIN product
ON product.uuid = device.product_device_uuid
WHERE product.cat_name = 'hps'
AND "device-status-log".code = 'presence_state'
ORDER BY device.uuid, "device-status-log".event_time
),
presence_detection AS (
SELECT *,
CASE
WHEN value = 'motion' AND prev_value = 'none' THEN 1 ELSE 0
END AS motion_detected,
CASE
WHEN value = 'presence' AND prev_value = 'none' THEN 1 ELSE 0
END AS presence_detected
FROM device_logs
),
presence_detection_summary AS (
SELECT
pd.device_id,
d.subspace_id,
pd.space_id,
pd.event_time::date AS event_date,
EXTRACT(HOUR FROM date_trunc('hour', pd.event_time)) AS event_hour,
SUM(motion_detected) AS count_motion_detected,
SUM(presence_detected) AS count_presence_detected,
SUM(motion_detected + presence_detected) AS count_total_presence_detected
FROM presence_detection pd
LEFT JOIN device d ON d.uuid = pd.device_id
GROUP BY 1, 2, 3, 4, 5
),
all_dates_and_hours AS (
SELECT device_id, subspace_id, space_id, event_date, event_hour
FROM (
SELECT DISTINCT device_id, subspace_id, space_id, event_date
FROM presence_detection_summary
) d,
generate_series(0, 23) AS event_hour
)
SELECT
adah.*,
COALESCE(pds.count_motion_detected, 0) AS count_motion_detected,
COALESCE(pds.count_presence_detected, 0) AS count_presence_detected,
COALESCE(pds.count_total_presence_detected, 0) AS count_total_presence_detected
FROM all_dates_and_hours adah
LEFT JOIN presence_detection_summary pds
ON pds.device_id = adah.device_id
AND pds.event_date = adah.event_date
AND pds.event_hour = adah.event_hour
ORDER BY 1, 4, 5;

View File

@ -0,0 +1,78 @@
-- This model gives the average hourly set and current temperatures per space, per device
-- The only issue witht this model is that it does not represent 24 hours/device. which is normal when no changelog is being recorded.
--Shall I fill the missing hours
WITH avg_set_temp AS (-- average set temperature per device per hour
SELECT
device.uuid AS device_id,
device.space_device_uuid AS space_id,
event_time::date AS date,
DATE_PART('hour', event_time) AS hour,
AVG("device-status-log".value::INTEGER) AS avg_set_temp
FROM device
LEFT JOIN "device-status-log"
ON device.uuid = "device-status-log".device_id
LEFT JOIN product
ON product.uuid = device.product_device_uuid
WHERE product.name = 'Smart Thermostat'
AND "device-status-log".code = 'temp_set'
GROUP BY 1,2,3,4
)
, avg_current_temp as (
SELECT
device.uuid AS device_id,
device.space_device_uuid AS space_id,
event_time::date AS date,
DATE_PART('hour', event_time) AS hour,
AVG("device-status-log".value::INTEGER) AS avg_current_temp
FROM device
LEFT JOIN "device-status-log"
ON device.uuid = "device-status-log".device_id
LEFT JOIN product
ON product.uuid = device.product_device_uuid
WHERE product.name = 'Smart Thermostat'
AND "device-status-log".code = 'temp_current'
GROUP BY 1,2,3,4
)
, joined_data AS ( -- this will return null values for hours where there was no previously set temperature
SELECT
current_temp.device_id,
current_temp.space_id,
current_temp.date,
current_temp.hour,
set_temp.avg_set_temp,
current_temp.avg_current_temp,
ROW_NUMBER() OVER (PARTITION BY current_temp.device_id, current_temp.space_id ORDER BY current_temp.date, current_temp.hour) AS row_num
FROM avg_current_temp AS current_temp
LEFT JOIN avg_set_temp AS set_temp
ON set_temp.device_id = current_temp.device_id
AND set_temp.space_id = current_temp.space_id
AND set_temp.date = current_temp.date
AND set_temp.hour = current_temp.hour
)
, filled_data AS (
SELECT
a.device_id,
a.space_id,
a.date,
a.hour,
COALESCE(
a.avg_set_temp,
(SELECT b.avg_set_temp
FROM joined_data b
WHERE b.device_id = a.device_id
AND b.space_id = a.space_id
AND b.row_num < a.row_num
AND b.avg_set_temp IS NOT NULL
ORDER BY b.row_num DESC
LIMIT 1)
) AS avg_set_temp,
a.avg_current_temp
FROM joined_data a
)
SELECT *
FROM filled_data
ORDER BY 1,3,4;

View File

@ -0,0 +1,44 @@
/*
* This model tracks the timestamp when a presence state went from no-presence --> presence detected, per device.
* This model should be used to display the presence logs Talal requested on the platform
*/
WITH device_logs AS (
SELECT
device.uuid AS device_id,
device.created_at,
device.device_tuya_uuid,
device.space_device_uuid AS space_id,
"device-status-log".event_id,
"device-status-log".event_time::timestamp,
"device-status-log".code,
"device-status-log".value,
"device-status-log".log,
LAG("device-status-log".event_time::timestamp)
OVER (PARTITION BY device.uuid
ORDER BY "device-status-log".event_time) AS prev_timestamp,
LAG("device-status-log".value)
OVER (PARTITION BY device.uuid
ORDER BY "device-status-log".event_time) AS prev_value
FROM device
LEFT JOIN "device-status-log"
ON device.uuid = "device-status-log".device_id
LEFT JOIN product
ON product.uuid = device.product_device_uuid
WHERE product.cat_name = 'hps' -- presence sensors
AND "device-status-log".code = 'presence_state'
ORDER BY device.uuid, "device-status-log".event_time
)
, presence_detection AS (
SELECT *,
CASE
WHEN value IN ('presence', 'motion') AND prev_value = 'none' THEN 1 -- detects a change in status from no presence to presence or motion
ELSE 0
END AS presence_detected
FROM device_logs
)
SELECT event_time as "time_presence_detected", device_id, space_id
FROM presence_detection
WHERE presence_detected=1

View File

@ -0,0 +1,104 @@
Category code,Description
dj,Light
xdd,Ceiling light
fwd,Ambiance light
dc,String lights
dd,Strip lights
gyd,Motion sensor light
fsd,Ceiling fan light
tyndj,Solar light
tgq,Dimmer
ykq,Remote control
kg,Switch
pc,Power strip
cz,Socket
cjkg,Scene switch
ckqdkg,Card switch
clkg,Curtain switch
ckmkzq,Garage door opener
tgkg,Dimmer switch
rs,Water heater
xfj,Ventilation system
bx,Refrigerator
yg,Bathtub
xy,Washing machine
kt,Air conditioner
ktkzq,Air conditioner controller
bgl,Wall-hung boiler
sd,Robot vacuum
qn,Heater
kj,Air purifier
lyj,Drying rack
xxj,Diffuser
cl,Curtain
mc,Door/window controller
wk,Thermostat
yb,Bathroom heater
ggq,Irrigator
jsq,Humidifier
cs,Dehumidifier
fs,Fan
js,Water purifier
dr,Electric blanket
cwtswsq,Pet treat feeder
cwwqfsq,Pet ball thrower
ntq,HVAC
cwwsq,Pet feeder
cwysj,Pet fountain
sf,Sofa
dbl,Electric fireplace
tnq,Smart milk kettle
msp,Cat toilet
mjj,Towel rack
sz,Smart indoor garden
bh,Smart kettle
mb,Bread maker
kfj,Coffee maker
nnq,Bottle warmer
cn,Milk dispenser
mzj,Sous vide cooker
mg,Rice cabinet
dcl,Induction cooker
kqzg,Air fryer
znfh,Bento box
mal,Alarm host
sp,Smart camera
sgbj,Siren alarm
zd,Vibration sensor
mcs,Contact sensor
rqbj,Gas alarm
ywbj,Smoke alarm
wsdcg,Temperature and humidity sensor
sj,Water leak detector
ylcg,Pressure sensor
ldcg,Luminance sensor
sos,Emergency button
pm2.5,PM2.5 detector
pir,Human motion sensor
cobj,CO detector
co2bj,CO2 detector
dgnbj,Multi-functional alarm
jwbj,Methane detector
hps,Human presence sensor
ms,Residential lock
bxx,Safe box
gyms,Business lock
jtmspro,Residential lock pro
hotelms,Hotel lock
ms_category,Lock accessories
jtmsbh,Smart lock (keep alive)
mk,Access control
videolock,Lock with camera
photolock,Audio and video lock
amy,Massage chair
liliao,Physiotherapy product
ts,Smart jump rope
tzc1,Body fat scale
sb,Watch/band
zndb,Smart electricity meter
znsb,Smart water meter
dlq,Circuit breaker
ds,TV set
tyy,Projector
tracker,Tracker
znyh,Smart pill box
1 Category code Description
2 dj Light
3 xdd Ceiling light
4 fwd Ambiance light
5 dc String lights
6 dd Strip lights
7 gyd Motion sensor light
8 fsd Ceiling fan light
9 tyndj Solar light
10 tgq Dimmer
11 ykq Remote control
12 kg Switch
13 pc Power strip
14 cz Socket
15 cjkg Scene switch
16 ckqdkg Card switch
17 clkg Curtain switch
18 ckmkzq Garage door opener
19 tgkg Dimmer switch
20 rs Water heater
21 xfj Ventilation system
22 bx Refrigerator
23 yg Bathtub
24 xy Washing machine
25 kt Air conditioner
26 ktkzq Air conditioner controller
27 bgl Wall-hung boiler
28 sd Robot vacuum
29 qn Heater
30 kj Air purifier
31 lyj Drying rack
32 xxj Diffuser
33 cl Curtain
34 mc Door/window controller
35 wk Thermostat
36 yb Bathroom heater
37 ggq Irrigator
38 jsq Humidifier
39 cs Dehumidifier
40 fs Fan
41 js Water purifier
42 dr Electric blanket
43 cwtswsq Pet treat feeder
44 cwwqfsq Pet ball thrower
45 ntq HVAC
46 cwwsq Pet feeder
47 cwysj Pet fountain
48 sf Sofa
49 dbl Electric fireplace
50 tnq Smart milk kettle
51 msp Cat toilet
52 mjj Towel rack
53 sz Smart indoor garden
54 bh Smart kettle
55 mb Bread maker
56 kfj Coffee maker
57 nnq Bottle warmer
58 cn Milk dispenser
59 mzj Sous vide cooker
60 mg Rice cabinet
61 dcl Induction cooker
62 kqzg Air fryer
63 znfh Bento box
64 mal Alarm host
65 sp Smart camera
66 sgbj Siren alarm
67 zd Vibration sensor
68 mcs Contact sensor
69 rqbj Gas alarm
70 ywbj Smoke alarm
71 wsdcg Temperature and humidity sensor
72 sj Water leak detector
73 ylcg Pressure sensor
74 ldcg Luminance sensor
75 sos Emergency button
76 pm2.5 PM2.5 detector
77 pir Human motion sensor
78 cobj CO detector
79 co2bj CO2 detector
80 dgnbj Multi-functional alarm
81 jwbj Methane detector
82 hps Human presence sensor
83 ms Residential lock
84 bxx Safe box
85 gyms Business lock
86 jtmspro Residential lock pro
87 hotelms Hotel lock
88 ms_category Lock accessories
89 jtmsbh Smart lock (keep alive)
90 mk Access control
91 videolock Lock with camera
92 photolock Audio and video lock
93 amy Massage chair
94 liliao Physiotherapy product
95 ts Smart jump rope
96 tzc1 Body fat scale
97 sb Watch/band
98 zndb Smart electricity meter
99 znsb Smart water meter
100 dlq Circuit breaker
101 ds TV set
102 tyy Projector
103 tracker Tracker
104 znyh Smart pill box

View File

@ -31,6 +31,7 @@ import { PrivacyPolicyModule } from './privacy-policy/privacy-policy.module';
import { TagModule } from './tags/tags.module';
import { ClientModule } from './client/client.module';
import { DeviceCommissionModule } from './commission-device/commission-device.module';
import { PowerClampModule } from './power-clamp/power-clamp.module';
@Module({
imports: [
ConfigModule.forRoot({
@ -64,8 +65,8 @@ import { DeviceCommissionModule } from './commission-device/commission-device.mo
TermsConditionsModule,
PrivacyPolicyModule,
TagModule,
DeviceCommissionModule,
PowerClampModule,
],
providers: [
{

View File

@ -0,0 +1 @@
export * from './power-clamp.controller';

View File

@ -0,0 +1,26 @@
import { Controller, Get, UseGuards } from '@nestjs/common';
import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
import { EnableDisableStatusEnum } from '@app/common/constants/days.enum';
import { ControllerRoute } from '@app/common/constants/controller-route';
import { JwtAuthGuard } from '@app/common/guards/jwt.auth.guard';
import { PowerClampService } from '../services/power-clamp.service';
@ApiTags('Power Clamp Module')
@Controller({
version: EnableDisableStatusEnum.ENABLED,
path: ControllerRoute.PowerClamp.ROUTE,
})
export class PowerClampController {
constructor(private readonly powerClampService: PowerClampService) {}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Get()
@ApiOperation({
summary: ControllerRoute.PowerClamp.ACTIONS.GET_ENERGY_SUMMARY,
description: ControllerRoute.PowerClamp.ACTIONS.GET_ENERGY_DESCRIPTION,
})
async getPowerClampData() {
return await this.powerClampService.getPowerClampData();
}
}

View File

@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { PowerClampService } from './services/power-clamp.service';
import { PowerClampController } from './controllers';
import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service';
@Module({
imports: [ConfigModule],
controllers: [PowerClampController],
providers: [PowerClampService, SqlLoaderService],
exports: [PowerClampService],
})
export class PowerClampModule {}

View File

@ -0,0 +1 @@
export * from './power-clamp.service';

View File

@ -0,0 +1,27 @@
import { SqlLoaderService } from '@app/common/helper/services/sql-loader.service';
import { Injectable } from '@nestjs/common';
import { DataSource } from 'typeorm';
@Injectable()
export class PowerClampService {
constructor(
private readonly sqlLoader: SqlLoaderService,
private readonly dataSource: DataSource,
) {}
async getPowerClampData() {
const sql = this.sqlLoader.loadQuery(
'fact_daily_energy_consumed',
'fact_daily_energy_consumed',
);
return this.dataSource.manager.query(sql);
}
async getEnergyConsumed(code: string) {
const sql = this.sqlLoader.loadQuery(
'energy',
'energy_consumed_with_params',
);
return this.dataSource.manager.query(sql, [code]);
}
}