Я передаю данные с ПЛК Siemens S7 через node-red, установленный на периферийном устройстве IoT, в облачное хранилище.
В красном узле я получаю данные в виде объекта JSON с несколькими свойствами каждую секунду от узла ПЛК. Объект JSON (или данные) имеет одни и те же свойства каждую секунду.
Некоторые свойства меняются каждую секунду, некоторые меняются за пять минут, некоторые остаются неизменными в течение нескольких часов.
Для обработки данных в облаке объект JSON обрабатывается узлом концентратора IoT в красном узле.
Я хотел бы обработать этот объект JSON перед обращением к узлу концентратора IoT таким образом, чтобы объект JSON имел только те свойства, которые изменились по сравнению с предыдущим состоянием (секунду назад). Это означает, что я хочу сравнить входной объект в данный момент t
с объектом в t-1
и сгенерировать новый объект со свойствами объекта в t
, которые отличаются от свойств объекта в t-1
.
Новый объект будет обрабатываться дальше. Ожидается, что обработка объекта будет выполняться в функциональном узле в узле-красном. От узла ПЛК объект JSON принимается как msg.payload
.
Не могли бы вы помочь мне написать (javascript) процесс, который я описал?
msg.payload для функционального узла является объектом json:
{"Zone0": 200,
"Wire_tension": 2.5}
UPD: Так как было непонятно, что я пробовал, вот код. Извините, что не предоставил это, я думал, что это ясно.
var state = {}; // this state will be messaged further
var prev_state = {
"Zone0": 0,
"Wire_tension": 0
}; // initially zeros are assigned
var current_state = msg.payload; // has these two properties and updated every second
// comparison of properties
if (current_state.Zone0 != prev_state.Zone0) {
state["Zone0"] = current_state.Zone0;
prev_state["Zone0"] = current_state.Zone0;
}
if (current_state.Wire_tension != prev_state.Wire_tension) {
state["Wire_tension"] = current_state.Wire_tension;
prev_state["Wire_tension"] = current_state.Wire_tension;
}
msg.payload = state;
return msg;
Похоже, что когда поток в узле-красном запускается, функциональный узел каждый раз запускает код. Поэтому prev_state назначается каждый раз. Я понимаю, что мне нужно как-то обрабатывать начальное состояние, которое в дальнейшем обновляется.
УПД2: Я также попытался использовать следующий код (также с функцией контекста). Пример с моими реальными данными:
var state = {}; // this state will be messaged further
flow.set(["Zone0", "Wire_tension"],[0,0]); // initially zeros are assigned
var current_state = msg.payload; // has these two properties and updated every second
// comparison of properties
if (current_state.Zone0 != flow.get("Zone0")) {
state["Zone0"] = current_state.Zone0;
flow.set("Zone0", current_state.Zone0);
}
if (current_state.Wire_tension != flow.get("Wire_tension")) {
state["Wire_tension"] = current_state.Wire_tension;
flow.set("Wire_tension", current_state.Wire_tension);
}
msg.payload = state;
return msg;
Я добавил код, который пробовал. Я думал, что это ясно из того, что было объяснено. Извините, если было непонятно.
Важно понимать, что prev_state
будет сбрасываться для каждого нового сообщения (поскольку функциональный узел ВЕСЬ запускается для каждого сообщения), вам нужно переместить его, чтобы сохранить в контексте, о котором я упоминал ранее.
@hardillb Я попробовал контекстную функцию node-red, это не сработало
лучший вариант - использовать глобальную контекстную переменную node-red
var object_to_build = {}
var key_1_val = global.get("key_1");
if (msg.payload.key_1 != key_1_val) {
object_tto_build['key_1'] = msg.payload.key_1
global.set("key_1", msg.payload.key_1);
}
// делайте с ним что хотите - object_to_build. Я не проверял код, просто опечатка
На вкладке «При запуске» в свойствах функционального узла:
flow.set(["Zone0", "Wire_tension"], [0, 0]);
Во вкладке «В сообщении» в свойствах функционального узла:
var state = {}; // this state will be messaged further
var current_state = msg.payload; // has these two properties and updated every second
// comparison of properties
if (current_state.Zone0 != context.get("Zone0")) {
state["Zone0"] = current_state.Zone0;
context.set("Zone0", current_state.Zone0);
}
if (current_state.Wire_tension != context.get("Wire_tension")) {
state["Wire_tension"] = current_state.Wire_tension;
context.set("Wire_tension", current_state.Wire_tension);
}
msg.payload = state;
return msg;
Stack Overflow так не работает, мы не просто предоставляем код. Вам нужно попробовать, затем покажите нам, что вы пробовали и как это не сработало, тогда мы поможем вам это исправить. Но мы не будем просто предоставлять код на основе списка требований. Я дам вам подсказку, чтобы вы начали, вам нужно посмотреть что-то под названием «контекст» в документации.