아파트 온도, 습도, 전력 실시간 데이터 관리 프로젝트 Part 2.

스케줄러를 통한 이메일 보내기 기능 구현

사용자의 실시간 데이터를 서버로 전송받고 데이터베이스에 저장하여 쌓인 데이터를 연산하여 사용자에게 특정한 일자에 보내도록 하는 기능을 제공하기로 했다.

가장 먼저 생각한 방식이자 이상적인 방법이였던 카카오톡으로 전송하기는 토이 프로젝트이기에 사업자 번호 등 카카오에서 요구하는 조건에 부딧혀 포기하고 구글 이메일 보내기로 방향을 틀게 되었다.

구상하는 방식은 이렇다.

  1. 매월 1일 자정에 모든 동 호수의 데이터를 그래프로 그린다.
  2. 각 호수별 사용자이자 입주민이라는 가정하에 그래프 이미지를 이메일로 매월 1일 00시 15분에 발송한다.

스케줄러 활용

우리는 node-schedule모듈을 활용하여 스케줄러를 작성하여 메일을 발송하기로 했다.

  1. 그래프 이미지 그리기
  • 모든 집의 데이터를 각각 그래프로 그려 이미지로 파일로 저장
그래프 그리기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
const get_month = () => {
const today = new Date();
return today.getMonth() + 1;
}

// 아파트 단지, 동, 호 일별 데이터 가져오기
const sensorData = async (Complex, Dong, Ho) => {
let exData = await apt_Info.sensorFind(Complex, Dong, Ho);
return exData;
};

// 아파트의 모든 단지 동 호 정보 가져오기
const basename = async () => {
const aptInfo = await apt_Info.aptFind();

for(let i=0; i < aptInfo.length; i++) {
// 파일 이름 지정 => ex) 단지 동 호.png
let fileName = `${aptInfo[i].AptDong.apt_complex}${aptInfo[i].AptDong.apt_dong}${aptInfo[i].apt_ho}`;
// 단지, 동, 호의 센서 데이터 받아오기.
let data = await sensorData(aptInfo[i].AptDong.apt_complex, aptInfo[i].AptDong.apt_dong, aptInfo[i].apt_ho);

// 차트를 그리기위한 날짜, 데이터 별 배열 분리
let dateArray = [];
let humiArray = [];
let tempArray = [];
let wattArray = [];
data.map((sensor) => {
let newDate = new Date(sensor.dataValues.date);
dateArray.push(dateAndTime.format(newDate, 'MM-DD'));
tempArray.push(sensor.dataValues.humidityAVG);
humiArray.push(sensor.dataValues.temperatureAVG);
wattArray.push(sensor.dataValues.electricitySUM);
});

// 차트 그리기 함수로 파일 이름과 데이터 배열 전달
humiChart(fileName, humiArray, dateArray);
tempChart(fileName, tempArray, dateArray);
wattChart(fileName, wattArray, dateArray);
};
console.log("차트 그리기 시작");
logger.info('create chart');
};

// 아파트 모든 세대의 전력 차트 그리기
const wattChart = (fileName, data, date) => {
const filewatt = fileName + "watt.png";
saveChart(filewatt, "Watt", data, date);
};

// 아파트 모든 세대 온도 차트 그리기
const tempChart = (fileName, data, date) => {
const filetemp = fileName + "temp.png";
saveChart(filetemp, "Temp", data, date);
};

// 아파트 모든 세대 습도 차트 그리기
const humiChart = (fileName, data, date) => {
const filehumi = fileName + "humi.png";
saveChart(filehumi, "Humi", data, date);
};

//차트그리기 스케줄러
const drawChart = () => {
// 매달 자정에 파일 생성
const jobs = schedule.scheduleJob('0 0 01 * *', function() {
basename();
});
};

이미지 그리기 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
const ChartJsImage = require('chartjs-to-image');
const fs = require('fs');

const chart = new ChartJsImage();

const days = function(month,year) {
return new Date(year, month, 0).getDate();
};

const get_Month = () => {
const today = new Date();

return today.getMonth() + 1;
}

const makeFolder = (dir) => {
try {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir)
}
} catch (err) {
console.error(err)
}
}

const saveChart = async (filename, type, data, date) => {
// 차트 label 지정
const labels = date;
// 차트 그리기
chart.setConfig({
type: 'line',
data: { labels: labels, datasets: [{ label: type, data }] },
});

// 월별 / 데이터별 파일 구분하기
const folderName = './data/' + (get_Month() - 1);
const monthPath = folderName + '/' + type;
// Write file to disk
makeFolder(folderName);
makeFolder(monthPath);
await chart.toFile(monthPath + "/" + filename);
}

module.exports = saveChart;

각각의 파일은 월별 / 데이터 종류로 구분되어 저장되고 저장된 이미지를 사용자에게 전송한다.

  1. 이메일 보내기
이메일 보내기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 이메일 보내기 스케줄러 시간 지정 
const mailResult = async () => {
const userinfo = await User.findAll({
attributes: ['uemail', 'apt_ho'],
include: {
model: AptHo,
include: {
model: AptDong,
}
},
});
userinfo.map((user) => {
let emailParam = {
toEmail: `${user.uemail}`,
subject: `${get_month() -1}월 사용량입니다.`,
text: `${get_month() - 1}월 사용량입니다.`,
// ex)1단지101동101호
name: `${user.AptHo.AptDong.apt_complex}${user.AptHo.AptDong.apt_dong}${user.AptHo.apt_ho}`,
month: get_month() - 1,
};

// const rule = new schedule.RecurrenceRule();
// const m = 50;
// rule.minute = m;

// 매달 1일 0시 15분 이메일 보내기 실행
const j = schedule.scheduleJob('13 13 02 * *', function() {
// const j = schedule.scheduleJob(rule, async function() {
console.log("send mail");
// await basename();
logger.info('send mail');
mailSender.sendGmail(emailParam);
});
});
};

테스트를 위해 시간을 조정하여 진행하였고 스케줄러 시간 부분만 원하는 시간으로 조정하면 정상적으로 전송이 된다.

결과



Author

han Ju Ryeon

Posted on

2021-11-02

Updated on

2021-12-05

Licensed under

댓글