드디어 끝이 보입니다.
엔드 디바이스에서 신호를 보내면, 라즈베리파이에서 zigbee 데이터를 받고 AWS IoT로 넘겨줍니다.
WLED가 설치된 ESP8266을 포트포워딩을 통해 외부IP로 접속할 수 있게 설정해 주었습니다.
EC2에 node-red를 구성해서 로직을 짜주어야 합니다!!
EC2는 우분투 20.04로 생성하고 Public subnet에 구성해줍니다.
private subnet에 구성하는 것은 테스트를 우선 진행하고 완성한 후 이미지를 따서 넘길 생각입니다.
ec2에 ssh 접속을 통해 node-red를 설치해 줍시다.
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt-get install -y nodejs build-essential
sudo npm install -g --unsafe-perm node-red
sudo npm install -g --unsafe-perm pm2
pm2 start `which node-red` -- -v
pm2 save
pm2 startup
테스트할 것이기 때문에 해당 포트에 대해 0.0.0.0/0 으로 설정했습니다.
이부분은 보안상 좋지 못한 예시입니다.
로직만 구성한 후 재정리를 하도록 하겠습니다.
(잘만 동작하면 되지않을까..?)
딱봐도 복잡해 보입니다.
차근 차근 살펴봅시다.
연필 표시를 눌러줍니다.
AWS IoT엔드포인트 및 포트를 입력해 줍니다. (포트는 8883)
사용TLS에서 연필 부분을 눌러줍니다.
라즈베리파이에 넣어놨던 인증서, private key, CA를 넣어줍니다.
확인을 누르면 연결이 완료됩니다.
DO : door open
DF : door close
MO : motion on
MF : motion off
//DO
var msg2 = { payload: {} };
if (msg.payload.contact === false) {
return msg2
}
//DF, MF
var msg8 = { payload: {} };
if (msg.payload.occupancy === false) {
return msg8;
}
//MO
var msg3 = { payload: {} };
//msg.payload.contact === true &&
if (msg.payload.occupancy === true) {
return msg3;
}
//DO,MO
var msg7 = { payload: {} };
//msg.payload.contact === false &&
if (msg.payload.contact === false && msg.payload.occupancy === true) {
return msg7;
}
여기서 trigger을 추가해줍니다.
이유는 door sensor가 상태값을 가지지 않기 때문에 고정시켜줌으로써 동작 안정화를 위해 달아주었습니다.
{"on":true,"bri":128,"transition":7,"mainseg":0,"seg":[{"id":0,"start":0,"stop":200,"grp":1,"spc":0,"of":0,"on":true,"frz":false,"bri":248,"cct":127,"col":[[255,200,0],[255,224,160],[255,255,0]],"fx":19,"sx":95,"ix":181,"pal":3,"sel":true,"rev":true,"mi":true},{"stop":0},{"stop":0},{"stop":0},{"stop":0},{"stop":0},{"stop":0},{"stop":0},{"stop":0},{"stop":0},{"stop":0},{"stop":0},{"stop":0},{"stop":0},{"stop":0},{"stop":0}]}
API 형식으로 HTTP WLED에 request를 날려줍니다.
오른쪽 위 배포하기 오른쪽에 줄3개 클릭
팔렛트 관리 클릭
설치가능한노드 에서 openweathermap 검색 후 설치
WLED 또한 설치
openweathermap 에서 얻은 api key와 위도, 경도 추가
//0~50개 weather 표시
var weather = msg.payload.weather;
var temperature = msg.payload.tempc;
var msg4 = { payload: {} };
msg4.payload.on = true
msg4.payload.bri = 128
msg4.payload.transition = 7
msg4.payload.mainseg = 0
// Set the color and effect of the first LED segment based on the weather
switch (weather) {
case "Clear":
msg4.payload.seg =
[{
"id": 0, "start": 0, "stop": 50, "grp": 1, "spc": 0, "of": 0, "on": true, "frz": false,
"col": [[3, 169, 244], [3, 169, 244], [3, 169, 244]],
"fx": 12,
"sx": 95,
"ix": 181,
"pal": 2,
"sel": false,
"rev": true,
"mi": false
}];
break;
case "Clouds":
msg4.payload.seg =
[{
"id": 0, "start": 0, "stop": 50, "grp": 1, "spc": 0, "of": 0, "on": true, "frz": false,
"col": [[189, 189, 189], [189, 180, 189], [189, 200, 189]],
"fx": 12,
"sx": 95,
"ix": 181,
"pal": 2,
"sel": false,
"rev": true,
"mi": false
}];
break;
case "Rain":
[{
"id": 0, "start": 0, "stop": 50, "grp": 1, "spc": 0, "of": 0, "on": true, "frz": false,
"col": [[33, 150, 243], [33, 150, 243], [33, 150, 243]],
"fx": 12,
"sx": 95,
"ix": 181,
"pal": 2,
"sel": false,
"rev": true,
"mi": false
}];
break;
case "Snow":
[{
"id": 0, "start": 0, "stop": 50, "grp": 1, "spc": 0, "of": 0, "on": true, "frz": false,
"col": [[255, 245, 254], [255, 245, 254], [255, 245, 254]],
"fx": 12,
"sx": 95,
"ix": 181,
"pal": 2,
"sel": false,
"rev": true,
"mi": false
}];
break;
default:
msg4.payload.seg =
[{
"id": 0, "start": 0, "stop": 60, "grp": 1, "spc": 0, "of": 0, "on": true, "frz": false,
"col": [[128, 128, 128], [128, 128, 128], [128, 128, 128]],
"fx": 12,
"sx": 95,
"ix": 181,
"pal": 2,
"sel": false,
"rev": true,
"mi": false
}];
}
return msg4;
//날씨 컬러
Clear: #03A9F4 [3, 169, 244] (파란색)
Clouds: #BDBDBD [189, 189, 189] (회색)
Rain: #2196F3 [33, 150, 243] (진한 파란색)
Snow: #E1F5FE [225, 245, 254](연한 파란색)
잘 보시면 col의 배열이 3개입니다. 기준이 되는 색상 1개와 비슷한 계열의 색상 2개를 추가함으로써 밋밋한 효과를 줄일 수 있습니다.
//51 ~ 100개의 LED는 온도 표시
var weather = msg.payload.weather;
var temperature = msg.payload.tempc;
var msg6 = { payload: {} };
msg6.payload.bri = 128
msg6.payload.transition = 7
msg6.payload.mainseg = 0
// Set the color and effect of the second LED segment based on the temperature
if (temperature <= 0) {
msg6.payload.seg =
[{
"id": 1, "start": 51, "stop": 100, "grp": 1, "spc": 0, "of": 0, "on": true, "frz": false,
"col": [[135, 206, 250], [150, 206, 250], [170, 206, 250]],
"fx": 12,
"sx": 95,
"ix": 181,
"pal": 2,
"sel": false,
"rev": true,
"mi": false
}];
} else if (temperature > 0 && temperature <= 5) {
msg6.payload.seg =
[{
"id": 1, "start": 51, "stop": 100, "grp": 1, "spc": 0, "of": 0, "on": true, "frz": false,
"col": [[0, 255, 255], [100, 255, 255], [200, 255, 255]],
"fx": 12,
"sx": 95,
"ix": 181,
"pal": 2,
"sel": false,
"rev": true,
"mi": false
}];
} else if (temperature > 5 && temperature <= 10) {
msg6.payload.seg =
[{
"id": 1, "start": 51, "stop": 100, "grp": 1, "spc": 0, "of": 0, "on": true, "frz": false,
"col": [[154, 205, 50], [154, 205, 100], [154, 205, 150]],
"fx": 12,
"sx": 95,
"ix": 181,
"pal": 2,
"sel": false,
"rev": true,
"mi": false
}];
}
else if (temperature > 10 && temperature <= 15) {
msg6.payload.seg =
[{
"id": 1, "start": 51, "stop": 100, "grp": 1, "spc": 0, "of": 0, "on": true, "frz": false,
"col": [[255, 255, 0], [255, 255, 100], [255, 255, 200]],
"fx": 12,
"sx": 95,
"ix": 181,
"pal": 2,
"sel": false,
"rev": true,
"mi": false
}];
}
else if (temperature > 15 && temperature <= 20) {
msg6.payload.seg =
[{
"id": 1, "start": 51, "stop": 100, "grp": 1, "spc": 0, "of": 0, "on": true, "frz": false,
"col": [[255, 165, 0], [255, 165, 100], [255, 165, 150]],
"fx": 12,
"sx": 95,
"ix": 181,
"pal": 2,
"sel": false,
"rev": true,
"mi": false
}];
}
else if (temperature > 20 && temperature <= 25) {
msg6.payload.seg =
[{
"id": 1, "start": 51, "stop": 100, "grp": 1, "spc": 0, "of": 0, "on": true, "frz": false,
"col": [[255, 0, 0], [255, 0, 50], [255, 0, 100]],
"fx": 12,
"sx": 95,
"ix": 181,
"pal": 2,
"sel": false,
"rev": true,
"mi": false
}];
}
else {
msg6.payload.seg =
[{
"id": 1, "start": 51, "stop": 100, "grp": 1, "spc": 0, "of": 0, "on": true, "frz": false,
"col": [[255, 0, 255], [255, 100, 255], [255, 200, 255]],
"fx": 12,
"sx": 95,
"ix": 181,
"pal": 2,
"sel": false,
"rev": true,
"mi": false
}];
}
return msg6;
//온도에 따른 컬러 값
하늘색: (135, 206, 250) 0도 이하
연녹색 (0, 255, 255) 0도 이상 5도 이하
연두색: (154, 205, 50) 5도이상 10도이하
노란색: (255, 255, 0) 10도이상 15도 이하
주황색: (255, 165, 0) 15도 이상 20도 이하
빨간색: (255, 0, 0) 20도 이상 25이하
자홍색: (255, 0, 255) 25도 이상 30도 이하
1,2번 WLED는 OFF
3,4번 WLED는 ON
모션센서의 탐지 시간은 트리거된 후 1분이 소요되므로 모션센서에서 보여주는 LED는 1분으로 설정했습니다.