2022. 11. 17. 10:49ㆍ개발/Node-red
이전 포스팅에 이어서 수정을 진행한다.
이전 단계에서, 노드 내부 설정에서 Mac address 를 기입했을 때 오류가 발생했다.
그래서 위 사진처럼 mac 값을 소스에 강제로 'test'로 기입했다.
하지만 이런 식으로 "mac" key의 value 문자열이 " " 로 반환되지 않는다.
이 오류들을 수정한다.
Json 객체 포맷 수정
var offLoad = [
'{\"mac\": test' + ", \"type\":100" + ", \"outNo\" :0" + ", \"value\" :0" + '}',
'{\"mac\": test' + ", \"type\":100" + ", \"outNo\" :1" + ", \"value\" :0" + '}',
'{\"mac\": test' + ", \"type\":100" + ", \"outNo\" :2" + ", \"value\" :0" + '}',
'{\"mac\": test' + ", \"type\":100" + ", \"outNo\" :3" + ", \"value\" :0" + '}'
]; //turns all ports off
위 사진처럼 "mac" 의 value를 test로 강제 입력 했었는데, test가 문자열 형식이
아니라서 Json 객체변환이 불가능 한 것 같다.
Json 객체 포맷 수정하면서 config.id오류로 임의로 'test'를 기입했던 부분도 수정한다.
var offLoad = [
'{\"mac\":' + '\"'+ config.id + '\"' + ", \"type\":100" + ", \"outNo\" :0" + ", \"value\" :0" + '}',
'{\"mac\": test' + ", \"type\":100" + ", \"outNo\" :1" + ", \"value\" :0" + '}',
'{\"mac\": test' + ", \"type\":100" + ", \"outNo\" :2" + ", \"value\" :0" + '}',
'{\"mac\": test' + ", \"type\":100" + ", \"outNo\" :3" + ", \"value\" :0" + '}'
]; //turns all ports off
위와 같이 수정했다. 'test' 대신 원래대로 config.id( 노드 입력 Mac address )로 수정했고
첫번째 index만 config.id 양단에 \" 를 추가해주었다.
config.id 수정 후 결과
debug 36 부분에 정상적으로 outNo:0 에 대한 Json 객체가 출력된다.
나머지 outNo 데이터는 초기 오류대로 String 으로 출력된다.
나머지 데이터도 마찬가지로 수정해준다.
출력 메시지 최종 수정
var offLoad = [
'{\"mac\":' + '\"'+ config.id + '\"' + ", \"type\":100" + ", \"outNo\" :0" + ", \"value\" :0" + '}',
'{\"mac\":' + '\"'+ config.id + '\"' + ", \"type\":100" + ", \"outNo\" :1" + ", \"value\" :0" + '}',
'{\"mac\":' + '\"'+ config.id + '\"' + ", \"type\":100" + ", \"outNo\" :2" + ", \"value\" :0" + '}',
'{\"mac\":' + '\"'+ config.id + '\"' + ", \"type\":100" + ", \"outNo\" :3" + ", \"value\" :0" + '}'
]; //turns all ports off
데이터 포맷 뿐만 아니라, 불필요한 메시지를 없애고
함수가 어디서 실행되는지 찾기 위해서 특정 메시지를 추가했다.
testing error 1 ~ 3 메시지를 client.publish로 확인한다.
sTimestamp = new Date(start).getTime(); //stime timestamp
eTimestamp = new Date(end).getTime(); //etime timestamp
if (curTimestamp < sTimestamp) { //timer hasn't started (considering the case where the flow has been restarted)
setTimeout(function() {
publishMessage(item, client, inTopic, config);
}, sTimestamp - curTimestamp);
setTimeout(function() {
for (var i = 0; i < 4; i++) {
client.publish(inTopic, offLoad[i]);
}
}, eTimestamp - curTimestamp); //turn all ports off when the schedule has been finished.
//node.warn("등록하신 스케쥴 " + String(node.start_time) + '~' + String(node.end_time) + '이 끝났습니다.')
/* 윗부분 주석처리! 불필요한 메시지. 시간값이 잘못 설정 됐을 경우는 괜찮은 메시지긴 하지만
지금은 불필요함. */
client.publish(inTopic,"error testing 1"); // 이 부분 추가. 메시지 발생위치 찾기 위함
}
else if (curTimestamp >= sTimestamp && curTimestamp <= eTimestamp) { //schedule has been up and running
//{"mac":"048e741c5210","type":100,"outNo":2,"value":1}
publishMessage(item, client, inTopic, config);
setTimeout(function() {
for (var i = 0; i < 4; i++) {
client.publish(inTopic, offLoad[i]);
}
}, eTimestamp - curTimestamp); //reset all ports
node.warn("등록하신 스케쥴 " + String(node.start_time) + '~' + String(node.end_time) + '이 끝났습니다.');
client.publish(inTopic,"error testing 2"); // 이 부분 추가. 메시지 발생위치 찾기 위함
}
else if (curTimestamp > eTimestamp) {
for (var i = 0; i < 4; i++) {
client.publish(inTopic, offLoad[i]);
} //reset all ports since the schedule has already been finished. Just in case the ports were not reset.
client.publish(inTopic,"error testing 3"); // 이 부분 추가. 메시지 발생위치 찾기 위함
}
위와 같이 client.publish(inTopic, "error testing 3"); 등의 메시지를 추가해서
동작 위치를 확인하기 용이하도록 했다.
최종 타이머 동작 확인
위와 같이 노드를 설정한다. 시작시간, 종료시간, Cooling 기능 체크.
1. 스케쥴 시작 전
error testing 1 이 정상적으로 출력된다.
error testing 1 은 현재 시간이, 타이머의 시작 시간보다 작을 때 출력이다.
2. 스케쥴 시작
체크한 Cooling 기능 (outNo : 1 )이 정상적으로 JSON 객체로 출력.
나머지 기능 (outNo ) 들은 JSON이 아닌 String으로 출력됨.
추후에 JSON 인지 String 인지 구분하는 처리를 추가해서
필요한 데이터만 전송하도록 수정할 예정.
3. 스케쥴 종료
타이머 종료시간이 되면, 모든 outNo 들을 0 출력해서 OFF 한다.
이로써 MQTT 통신 출력데이터는 정상적으로 handle할 수 있다.
시작 알림 메시지 오류
1. 타이머 시작 전 에 출력되는 메시지다.
시작시간 ~ 종료시간이 undefined로 출력된다. 소스코드를 살펴보았다.
node.warn('등록하신 스케쥴을 시작합니다. (' + node.startTime + '~' + String(node.endTime) + ')');
if (curTimestamp < sTimestamp) { //timer hasn't started (considering the case where the flow has been restarted)
setTimeout(function() {
publishMessage(item, client, inTopic, config);
}, sTimestamp - curTimestamp);
setTimeout(function() {
for (var i = 0; i < 4; i++) {
client.publish(inTopic, offLoad[i]);
}
}, eTimestamp - curTimestamp); //turn all ports off when the schedule has been finished.
//node.warn("등록하신 스케쥴 " + String(node.start_time) + '~' + String(node.end_time) + '이 끝났습니다.')
/* 윗부분 주석처리! 불필요한 메시지. 시간값이 잘못 설정 됐을 경우는 괜찮은 메시지긴 하지만
지금은 불필요함. */
client.publish(inTopic,"error testing 1"); // 이 부분 추가. 메시지 발생위치 찾기 위함
}
코드 최상단에 node.warn( ) 부분에서 출력되는 것 같다.
현재시간으로 if 문 처리하기 전에 node.warn( )이 먼저 실행된다.
시작 시간 = node.startTime
종료 시간 = node.endTime 으로 받아오는데, undefined로 출력되는게 이상하다.
if (curTimestamp < sTimestamp)
이 부분의 시작시간 ( sTimestamp )은
var start = String(config.startTime);
sTimestamp = new Date(start).getTime(); //stime timestamp
이 선언으로 정상적으로 처리된다.
따라서, undefined가 발생하는 node.startTime 이 아닌, start변수로 수정해야되나?
시작 알림 메시지 수정
node.warn('등록하신 스케쥴을 시작합니다!!! (' + start + '~' + String(node.endTime) + ')');
위와 같이 수정해보았다.
오류를 수정했다!! 나머지 endTime 도 수정했다.
node.warn('등록하신 스케쥴을 시작합니다!!! (' + start + '~' + end + ')');
위와 같이 시작시간 ~ 종료시간 이 정상적으로 출력됐다.
깔끔하게 출력되도록 소스를 좀 더 수정했다.
node.warn('노드 스케쥴 설정 되었습니다.\n시작 : ' + start + '\n종료 : ' + end );
node.warn('노드 스케쥴 설정 되었습니다.\n시작 : ' + start + '\n종료 : ' + end );
if (curTimestamp < sTimestamp) { //timer hasn't started (considering the case where the flow has been restarted)
node.warn("스케쥴 시작 전 입니다");
setTimeout(function() {
publishMessage(item, client, inTopic, config);
}, sTimestamp - curTimestamp);
setTimeout(function() {
for (var i = 0; i < 4; i++) {
client.publish(inTopic, offLoad[i]);
}
}, eTimestamp - curTimestamp); //turn all ports off when the schedule has been finished.
//node.warn("등록하신 스케쥴 " + String(node.start_time) + '~' + String(node.end_time) + '이 끝났습니다.')
/* 윗부분 주석처리! 불필요한 메시지. 시간값이 잘못 설정 됐을 경우는 괜찮은 메시지긴 하지만
지금은 불필요함. */
//client.publish(inTopic,"error testing 1"); // 이 부분 추가. 메시지 발생위치 찾기 위함
}
node.warn( "스케쥴 시작 전 입니다"); 추가
else if (curTimestamp >= sTimestamp && curTimestamp <= eTimestamp) { //schedule has been up and running
//{"mac":"048e741c5210","type":100,"outNo":2,"value":1}
node.warn("등록하신 스케쥴\n시작 : " + start + '\n종료 : ' + end + '\n실행됩니다.');
publishMessage(item, client, inTopic, config);
setTimeout(function() {
for (var i = 0; i < 4; i++) {
client.publish(inTopic, offLoad[i]);
}
}, eTimestamp - curTimestamp); //reset all ports
//node.warn("등록하신 스케쥴 " + String(node.start_time) + '~' + String(node.end_time) + '이 끝났습니다.');
//client.publish(inTopic,"error testing 2"); // 이 부분 추가. 메시지 발생위치 찾기 위함
}
else if (curTimestamp > eTimestamp) {
node.warn("등록하신 스케쥴\n시작 : " + start + '\n종료 : ' + end + '\n끝났습니다.');
for (var i = 0; i < 4; i++) {
client.publish(inTopic, offLoad[i]);
} //reset all ports since the schedule has already been finished. Just in case the ports were not reset.
//client.publish(inTopic,"error testing 3"); // 이 부분 추가. 메시지 발생위치 찾기 위함
}
node.warn("등록하신 스케쥴\n시작 : " + start + '\n종료 : ' + end + '\n끝났습니다.'); 추가
수정 후 출력 확인
위와 같이 정상적으로 동작한다.
잔여 오류 및 보완할 점
- mqtt 통신 불안정
- mqtt 통신 불안정에 따른 Node-red 서버 중지 ( cmd 에서 자주 node-red 종료 )
- 스케쥴 시작 알림에 어떤 기능의 스케쥴인지 알려주면 좋을 것 같음
- 노드 설정으로 동작시키는 경우 제외하고 외부 inject로도 동작하면 좋을 것 같음
'개발 > Node-red' 카테고리의 다른 글
[Node-red] Schedule node 수정 - 4 (0) | 2022.11.21 |
---|---|
[Node-red] Schedule node 수정 - 3 (0) | 2022.11.21 |
[Node-red] Schedule node 수정-1 (0) | 2022.11.16 |
[Node-red] Schedule node 소스 분석 (0) | 2022.11.16 |
Node-red 윈도우 설치 (0) | 2022.11.14 |