[Node-red] Schedule node 수정-1

2022. 11. 16. 17:11개발/Node-red

https://iruk.tistory.com/8

 

Node-red Custom node 소스 분석

Inject 로 시간 데이터를 입력하거나 노드 내에서 html Schedule 기능으로 동작구현. 특정 시간에 동작시키는 기능. MQTT 무선통신으로 ESP32 에 데이터전송. Node-red 에서 원격으로 PTC 환풍기를 제어하기

iruk.tistory.com

이전 포스팅에서 다뤘던 Node-red 의 제작 노드 수정 단계.

MQTT 서버 접속 오류를 해결하는 과정을 기록한다.

 

Mac address input 받는 config.id 오류

노드의 소스를 살펴보면

function test_l(config) {
        RED.nodes.createNode(this,config);
        var node = this;
        var received = "";
        var mqtt    = require('mqtt');
        //var mongo   = require('mongodb');
        //var url     = "";
        //var database = "";
        //var collectionName = "";
        //var savedData = "";
        var curTimestamp = 0;
        var sTimestamp = 0;
        var eTimestamp = 0;
        var nodeContext = this.context();
        
      
        
        var outTopic= "LightTalk-out";
        var inTopic = "LightTalk-in";

위와 같이 outTopic, inTopic 을 LightTalk- config.id -out 식으로 config.id를 사용했다.

config.id 란, 노드의 설정에서 입력하는 Mac address 값이다.

 

input으로 받아오는 Mac 주소를 반환한다. 이렇게 설정을 해야, Topic이 겹치지 않고

각각의 ESP32마다 고유의 데이터를 주고받을 수 있는데, 이 부분에서 오류가 발생.


MQTT topic 에서 config.id 제외

//var outTopic= "LightTalk-" + String(config.id) + "-out";
//var inTopic = "LightTalk-" + String(config.id) + "-in";
        
var outTopic= "LightTalk-out";
var inTopic = "LightTalk-in";

토픽을 config.id 없이 일단 테스트 해보았다. 

출력 메시지가 mac key 의 value 가 빈 채로 들어왔다.

MQTT 통신을 하는 부분들을 모두 확인 후 해당하는 부분중 2군데를 검토했다.

 

1. publishMessage 함수

function publishMessage(item, client, inTopic, config) {
	client.publish(inTopic, '{\"mac\":' + config.id + ", \"type\":100" + ", \"outNo\" :0" + ", \"value\" :" + String(item[0]) + '}');
	client.publish(inTopic, '{\"mac\":' + config.id + ", \"type\":100" + ", \"outNo\" :1" + ", \"value\" :" + String(item[1]) + '}');
	client.publish(inTopic, '{\"mac\":' + config.id + ", \"type\":100" + ", \"outNo\" :2" + ", \"value\" :" + String(item[2]) + '}');
	client.publish(inTopic, '{\"mac\":' + config.id + ", \"type\":100" + ", \"outNo\" :3" + ", \"value\" :" + String(item[3]) + '}');
	console.log(item[0], item[1], item[2], item[3]);
}

2. offLoad 배열

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

두 가지 경우 모두 config.idvalue로 반환하는데, config.id null이어서 공백이다.

하지만 노드 설정에서 Mac address를 기입해주면, mqtt 서버 접속이 안되는 오류가 발생한다.

위와 같이 Mac address를 임의로 기입한 뒤 테스트해보았다.

 

하지만 node mqtt에 접속을 못하고 계속 접속중 이 반복되었다.

 

이 오류 해결보다 임의로 일단 Mad address 없이 테스트를 진행한다.


출력 메시지 수정

function publishMessage(item, client, inTopic, config) {
	client.publish(inTopic, '{\"mac\": test' + ", \"type\":100" + ", \"outNo\" :0" + ", \"value\" :" + String(item[0]) + '}');
	client.publish(inTopic, '{\"mac\": test' + ", \"type\":100" + ", \"outNo\" :1" + ", \"value\" :" + String(item[1]) + '}');
	client.publish(inTopic, '{\"mac\": test' + ", \"type\":100" + ", \"outNo\" :2" + ", \"value\" :" + String(item[2]) + '}');
	client.publish(inTopic, '{\"mac\": test' + ", \"type\":100" + ", \"outNo\" :3" + ", \"value\" :" + String(item[3]) + '}');
	console.log(item[0], item[1], item[2], item[3]);
}

메시지 출력 포맷인 publishMessage( ) 부분을 수정했다. mac value‘test’

강제로 입력하고 테스트 해보았다. 하지만 여전히 메시지는 mac 이 공백인채로 출력됐다.

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

마찬가지로 출력 포맷의 또 한가지 경우인 offLoad 배열을 수정했다. macvalue

‘test’로 강제 입력하고 테스트 해보았다.

성공적으로 mac 의 value 가 출력됐다.


출력되는 구간 확인

if (cur < stime) { //timer hasn't started (considering the case where the flow has been restarted)
	setTimeout(function() {
		client.publish(inTopic, msg_toPublish);
	}, stime - cur);
                        
	setTimeout(function() {
		for (var i = 0; i < 4; i++) {
			client.publish(inTopic, offLoad[i]);
		}
	}, etime - cur); //turn all ports off when the schedule has been finished.
	node.warn("등록하신 스케쥴 " + String(node.start_time) + '~' + String(node.end_time) + '이 끝났습니다.');
} 
else if (cur >= stime && cur <= etime) { //schedule has been up and running
	client.publish(inTopic, msg_toPublish);
	setTimeout(function() {
	for (var i = 0; i < 4; i++) {
	client.publish(inTopic, offLoad[i]);
	}
	}, etime - cur); //reset all ports
	node.warn("등록하신 스케쥴 " + String(node.start_time) + '~' + String(node.end_time) + '이 끝났습니다.');
} 
else if (cur > etime) {
	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.
} 
else {
	node.send("nothing happened");
} //do nothing since case does not exist.

offLoad 배열에서 데이터가 반환되는 걸 확인했지만, offLoadclient.publish

송신하는 부분이 다양해서 찾아보았다.

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,"testing error");       
}

curtimestamp > eTimestamp 일 때 출력이 발생했다는 걸 알 수 있었다.

var curTimestamp = Date.now();

curTimestamp 는 현재 시간값

eTimestamp = new Date(end).getTime();

eTimestamp end timestamp 값이다.

var end = String(config.endTime);

end 는 노드 설정에서 input endTime 이다.

, 타이머가 동작해서 동작 종료시간을 지났을 때 동작해야될 부분에서 출력된다.


시간 받는 변수 및 여러가지 부분들 수정 필요해보임

'개발 > Node-red' 카테고리의 다른 글

[Node-red] Schedule node 수정 - 4  (0) 2022.11.21
[Node-red] Schedule node 수정 - 3  (0) 2022.11.21
[Node-red] Schedule node 수정 - 2  (0) 2022.11.17
[Node-red] Schedule node 소스 분석  (0) 2022.11.16
Node-red 윈도우 설치  (0) 2022.11.14