ITСooky

IT-рецепты съедобные и не очень!

IoT по-взрослому: на ESP8266 по MQTT через Mosquitto в Node-RED!

дата 15.11.2018

В начале это казалось простой понятной темой на пару дней… неее, но потом страх новой концепции прошел, оказалось так просто, а потом опять нет!

Немного расшифрую название статьи: ESP8266 это чип основа устройства с WiFi интерфейсом по сути компутер-клиент MQTT, MQTT это протокол связи, он старый но можно сделать безопасным если заморочится(я не буду), Mosquitto это приемщик и передатчик сообщений которые идут от клиентов по MQTT сообщения разные от данных до коммонад, Node-RED а это тоже клиент MQTT потомучто Mosquitto просто передатчик(центр), Node-RED это графический интерфейс программирования (собираешь из кирпичеков чего хочешь) он работает на Node.js его начало разрабатывать IBM(и бросило?) для всего-всего(например собирать сообщение из twitter по хештегам, всего два кирпичика).

Крутиться все будет на Orange Pi Pc сервере вот на таком

Свеже собранный Orange PI PC Server на Armbian!


Полностью полагаюсь на этот шикарный мануал https://randomnerdtutorials.com/esp8266-and-node-red-with-mqtt/

Ставим Mosquitto
sudo apt update
sudo apt-get install mosquitto mosquitto-clients

Смотрим завелся ли москито, с лушает ли прорт 1883
netstat -tulpn | grep LISTEN
слушает

Ставим Node-Red
Мы в рут дирктории
cd /root

Сначала ставим nodejs
curl -sL https://deb.nodesource.com/setup_9.x | bash -
apt-get install -y nodejs

Смотрим что установилось

root@orangepipcplus:~# node --version
v9.11.2
root@orangepipcplus:~# npm --version
5.6.0

Далее ставим
sudo npm install node-red
sudo npm i node-red-dashboard

заходим в
cd ./node_modules/node-red
и запускаем, пока так
node red.js
Заходим в браузере на ip где стоит и порт 1880
http://192.168.1.1:1880
Работает, просто запустить его недостаточно, хотелось бы чтобы он сам запускался после перезагрузки
Для этого ставим pm2
npm i pm2 -g
Запускаем
pm2 start red.js --name Node-Red
И еще команда, теперь бот будет запускаться после перезагрузки
pm2 startup
pm2 save

Перегружаемся

Работает! Во вкладке с Dashboard делаем tab под названием Room а внем Group под названием Lamp и Sensor

В центр надо накидать вот этих кирпичей. Тут главное какое это кирпич левый или правый. Нам нужны два правых MQTT и один левый MQTT остальные вродебы все левые

Сам я это поздно заметил, так что сейчас переделываю и некоторые кирпичи уже с названиями из будущего!

Жмем два на любой из MQTT и делаем его сервером здесь надо только имя и localhost написать


Далее картинки настроек прочих кирпичей
switch

mqtt другой кирпич

mqtt другой кирпич

chart

gauge
Здесь надо поставить range от 0 до 100 на скриншоте забыл

Соединяем и жмем Deploy(справа вверху)

Делаем железо
NodedMcu брал давно и поддельный, просто криво спаянный, вот такой 5 Шт./лот V3 Беспроводной модуль NodeMcu 4 М байт Lua WI-FI Интернет вещей ESP8266 доска развития на основе для arduino совместимость за 1112 RUR за 5шт, сслыки уже нет!

Прошивать буду на Ubuntu, но процесс одинаков и на других ОС, кроме установки!

Придется помучится с подключением, чтобы все работало надо ставить Ардуино из консоли а не через Ubuntu Softw…
snap install arduino-mhall119 --classic
Перед этим, правда попробовал, кучу других советов, может они помогли, я же говорю придется помочится

В меню Arduino 1.8.5 File > Prefernces надо вставить в Additional Boars Manager URLs надо вставить
http://arduino.esp8266.com/stable/package_esp8266com_index.json
Далее идем в Tools > Board > Boards manager и тут в низу появится esp866 его и надо установить

На плате написано Lolin new NodeMcu v3 эээ неизвестный зверь для Lolin лью его выбирая в Board: LION(WEMOS)D1 R2 & mini

Закачиваем скетч для мигания лампочкой, тут главное определить пин лампы а то в скриптах из примеров этого не делают

#define LED_BUILTIN 2

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, LOW);   // Turn the LED on (Note that LOW is the voltage level
  // but actually the LED is on; this is because
  // it is active low on the ESP-01)
  delay(2000);                      // Wait for a second
  digitalWrite(LED_BUILTIN, HIGH);  // Turn the LED off by making the voltage HIGH
  delay(5000);                      // Wait for two seconds (to demonstrate the active low LED)
}

Сработало и это же обычный Arduino код, хотя это совсем не ардуино

Кстати один модуль был бракованный, я это конечно не сразу понял. Плохо шился, Wi-Fi не работал, при осмотре за крышкой ESP было в никуда припаяно сопротивление. Пришлось его добить, чтобы не мучался. На фото как раз то место справа внизу крайнее сопротивление это я сорвал а остальное как было.

Качаем библиотеку для сенсора температуры и влажности dht22 https://github.com/adafruit/DHT-sensor-library/archive/master.zip и вот эту тоже https://github.com/adafruit/Adafruit_Sensor/archive/master.zip

Добавляем её в программу через меню Scretch > Include Library > Add .ZIP Library
И пытаюсь закинуть обычный скетч для ардуино. Надо только учесть что подписи пинов на плате не о чем, надо смотреть схему

ОЧЕНЬ ВАЖНО: Тут открывается важное обстоятельство, о котором все должны предупреждать, но нет…у этих аля NoneMcu ESP8266 только два GPIO нормальные D1 и D2(на остальных что-то еще висит) остальные просто так не работают вот пишут https://www.forward.com.au/pfod/ESP8266/GPIOpins/index.html и это хрень какая-то. 0,2,6-11,15 точно заняты, другие можно пробовать! Пытался спаять шилд с датчиком темпы ну и подключал к 15ому так как рядом, а он не работает хоть и написано GPIO!!!

То что на плате D2 на самом деле 4

#include <DHT_U.h>
#include <DHT.h>
//Libraries
//Constants
#define DHTPIN 4     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino

//Variables
int chk;
float hum;  //Stores humidity value
float temp; //Stores temperature value

void setup()
{
  Serial.begin(9600);
  dht.begin();
}

void loop()
{
    delay(2000);
    //Read data and store it to variables hum and temp
    hum = dht.readHumidity();
    temp= dht.readTemperature();
    //Print temp and humidity values to serial monitor
    Serial.print("Humidity: ");
    Serial.print(hum);
    Serial.print(" %, Temp: ");
    Serial.print(temp);
    Serial.println(" Celsius");
    delay(10000); //Delay 2 sec.
}

После заливки жмем Serial Monitor и ха! Работает! Так что плата работает!

Так же качаю и добавляю библиотеку Arduino Client for MQTT от сюда https://github.com/knolleary/pubsubclient/archive/master.zip

Собираю схему как в инструкции, лампа на 4, датчик на 5, сопротивления лампы 220 Ом а датчика…

У меня тут какая то аномалия, если делать как во всех схемах резистор 10к или 4,7к то датчик dht22 вместо с esp8266 не работает, один может работать и на сериный порт сообщать темпу, так что убрал это сопротивление вообще…и у меня датчик сидит на 3.3v, попробовал на 5V тоже нет

Ну и закидываю сразу код с http://randomnerdtutorials.com/ исправил только список библиотек и в четырех местах ввел свои данные!

#include <PubSubClient.h>
#include <DHT_U.h>
#include <DHT.h>
#include <ESP8266WiFi.h>


// Uncomment one of the lines bellow for whatever DHT sensor type you're using!
//#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

// Change the credentials below, so your ESP8266 connects to your router
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker
const char* mqtt_server = "REPLACE_WITH_YOUR_RPI_IP_ADDRESS";

// Initializes the espClient. You should change the espClient name if you have multiple ESPs running in your home automation system
WiFiClient espClient;
PubSubClient client(espClient);

// DHT Sensor - GPIO 5 = D1 on ESP-12E NodeMCU board
const int DHTPin = 5;

// Lamp - LED - GPIO 4 = D2 on ESP-12E NodeMCU board
const int lamp = 4;

// Initialize DHT sensor.
DHT dht(DHTPin, DHTTYPE);

// Timers auxiliar variables
long now = millis();
long lastMeasure = 0;

// Don't change the function below. This functions connects your ESP8266 to your router
void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi connected - ESP IP address: ");
  Serial.println(WiFi.localIP());
}

// This functions is executed when some device publishes a message to a topic that your ESP8266 is subscribed to
// Change the function below to add logic to your program, so when a device publishes a message to a topic that 
// your ESP8266 is subscribed you can actually do something
void callback(String topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // Feel free to add more if statements to control more GPIOs with MQTT

  // If a message is received on the topic room/lamp, you check if the message is either on or off. Turns the lamp GPIO according to the message
  if(topic=="room/lamp"){
      Serial.print("Changing Room lamp to ");
      if(messageTemp == "on"){
        digitalWrite(lamp, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "off"){
        digitalWrite(lamp, LOW);
        Serial.print("Off");
      }
  }
  Serial.println();
}

// This functions reconnects your ESP8266 to your MQTT broker
// Change the function below if you want to subscribe to more topics with your ESP8266 
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    /*
     YOU MIGHT NEED TO CHANGE THIS LINE, IF YOU'RE HAVING PROBLEMS WITH MQTT MULTIPLE CONNECTIONS
     To change the ESP device ID, you will have to give a new name to the ESP8266.
     Here's how it looks:
       if (client.connect("ESP8266Client")) {
     You can do it like this:
       if (client.connect("ESP1_Office")) {
     Then, for the other ESP:
       if (client.connect("ESP2_Garage")) {
      That should solve your MQTT multiple connections problem
    */
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");  
      // Subscribe or resubscribe to a topic
      // You can subscribe to more topics (to control more LEDs in this example)
      client.subscribe("room/lamp");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

// The setup function sets your ESP GPIOs to Outputs, starts the serial communication at a baud rate of 115200
// Sets your mqtt broker and sets the callback function
// The callback function is what receives messages and actually controls the LEDs
void setup() {
  pinMode(lamp, OUTPUT);
  
  dht.begin();
  
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

}

// For this project, you don't need to change anything in the loop function. Basically it ensures that you ESP is connected to your broker
void loop() {

  if (!client.connected()) {
    reconnect();
  }
  if(!client.loop())
    client.connect("ESP8266Client");

  now = millis();
  // Publishes new temperature and humidity every 30 seconds
  if (now - lastMeasure > 30000) {
    lastMeasure = now;
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht.readHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.readTemperature();
    // Read temperature as Fahrenheit (isFahrenheit = true)
    float f = dht.readTemperature(true);

    // Check if any reads failed and exit early (to try again).
    if (isnan(h) || isnan(t) || isnan(f)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }

    // Computes temperature values in Celsius
    float hic = dht.computeHeatIndex(t, h, false);
    static char temperatureTemp[7];
    dtostrf(hic, 6, 2, temperatureTemp);
    
    // Uncomment to compute temperature values in Fahrenheit 
    // float hif = dht.computeHeatIndex(f, h);
    // static char temperatureTemp[7];
    // dtostrf(hic, 6, 2, temperatureTemp);
    
    static char humidityTemp[7];
    dtostrf(h, 6, 2, humidityTemp);

    // Publishes Temperature and Humidity values
    client.publish("room/temperature", temperatureTemp);
    client.publish("room/humidity", humidityTemp);
    
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t Temperature: ");
    Serial.print(t);
    Serial.print(" *C ");
    Serial.print(f);
    Serial.print(" *F\t Heat index: ");
    Serial.print(hic);
    Serial.println(" *C ");
    // Serial.print(hif);
    // Serial.println(" *F");
  }
} 

Ва!!!у и все сразу работает!!!

Иду на http://ip_вашего_сервера:1880/ui а там уже побежала статистика и лампочка включается!

Кстати понятно почему все так опасаются безопасности IoT устройств, её просто нет! Тут у всех берет всем дает, даже админка Node-Red да даже нет такого пункта в меню, пароль надо через одно место перекручивать — через консоль!

Включаем аутентификацию в админке Node-Red
Идем в (это важно это вообще упускается из документации у меня также такие же настройки в setting.js который в /root/node_modules/node-red)
cd /root/.node-red
Генерируем краказябру своего пароля коммандой
node -e "console.log(require('bcryptjs').hashSync(process.argv[1], 8));" your-password-here
И в файле settings.js находим строки и расскомментируем должно быть вот так, со своей краказяброй вместо пароля

adminAuth: {
    sessionExpiryTime: 86400,
    type: "credentials",
    users: [{
        username: "admin",
        password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
        permissions: "*"
    }]
},

Перезапускает
pm2 stop Node-Red
pm2 start Node-Red

Можно еще генерировать через так
sudo npm install -g node-red-admin
node-red-admin hash-pw

В Chrome заработало в FireFox нет, из поля логин курсор ни куда больше не двигается

Добавляем пароль в Mosquitto
Останавливаем
sudo service mosquitto stop
Далее, тут надо логин поставить в комманду, и спросить- какой пароль ставить
sudo mosquitto_passwd -c /etc/mosquitto/passwd login_svoy
В файл настройке добавлеям
vi /etc/mosquitto/mosquitto.conf
строки

password_file /etc/mosquitto/passwd
allow_anonymous false

и перегружаем

Node-Red сразу перестает получать данные.
На кирпиче Mosquitto во вкладке Security пишем логин пароль

А esp8266 надо перепрошивать, в коде изменения строки констатнты логин пароль и вот это
if (client.connect(WiFi.hostname().c_str(), mqttUser, mqttPassword)) {
Это очень важная строка, здесь не просто вставляется пароль для соединения, но и задается ункиальное имя клиента для подключения к mosquitto к топику с состоянием лампочки. Это имя должно быть уникальным, если нет москитто начинает тупить и данные начинают поступать с задержками уже от датчиков температуры влажности. WiFi.hostname().c_str() — берет и вставляет хост нейм уникальность одного имени, для одной платы, обеспечена. (версия что нужно уникальное имя на каждую подписку, проверится потом)

Вот эти строки остаются для меня не поняты.

  if(!client.loop())
    client.connect("ESP8266Client");

Без неё не работает включение лампочки… сама по себе она тоже не должна работать потому что пароль не передается…и похоже неважно какое здесь имя… может она просто никогда не исполняется…а если исполнится то не сможет подключиться…а почему тогда лампа!

Также я убрал сообщения на сериал порт, да и по другому считает интервал отсылки температуры и влажности, до этого было не правильно, могло зависнуть через 24 дня

#include <PubSubClient.h>
#include <DHT_U.h>
#include <DHT.h>
#include <ESP8266WiFi.h>


// Uncomment one of the lines bellow for whatever DHT sensor type you're using!
//#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
#define LED_BUILTIN 2

// Change the credentials below, so your ESP8266 connects to your router
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
const char* mqttUser = "yout_logi8n";
const char* mqttPassword = "your_password";
const char* mqttTopicLamp = "room/lamp";
const char* mqttTopicHumidity = "room/humidity";
const char* mqttTopicTemperature = "room/temperature";

// Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker
const char* mqtt_server = "REPLACE_WITH_YOUR_RPI_IP_ADDRESS";

// DHT Sensor - GPIO 5 = D1 on ESP-12E NodeMCU board
const int DHTPin = 5;

// Lamp - LED - GPIO 4 = D2 on ESP-12E NodeMCU board
const int lamp = 4;

// Timers auxiliar variables
unsigned long now = millis();
unsigned long lastMeasure = 0;
unsigned long resendtime = 30000; //30sec

// Initializes the espClient. You should change the espClient name if you have multiple ESPs running in your home automation system
WiFiClient espClient;
PubSubClient client(espClient);

// Initialize DHT sensor.
DHT dht(DHTPin, DHTTYPE);

// The setup function sets your ESP GPIOs to Outputs, starts the serial communication at a baud rate of 115200
// Sets your mqtt broker and sets the callback function
// The callback function is what receives messages and actually controls the LEDs
void setup() {
  dht.begin();
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  pinMode(LED_BUILTIN, OUTPUT); 
  pinMode(lamp, OUTPUT);
  client.setCallback(callback);
}


// Don't change the function below. This functions connects your ESP8266 to your router
void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }

}

// This functions is executed when some device publishes a message to a topic that your ESP8266 is subscribed to
// Change the function below to add logic to your program, so when a device publishes a message to a topic that 
// your ESP8266 is subscribed you can actually do something
void callback(String topic, byte* message, unsigned int length) {
  String messageTemp; 
  for (int i = 0; i < length; i++) {
   messageTemp += (char)message[i];
  }

  // Feel free to add more if statements to control more GPIOs with MQTT

  // If a message is received on the topic mqttTopicLamp, you check if the message is either on or off. Turns the lamp GPIO according to the message
 if(topic==mqttTopicLamp){
     if(messageTemp == "on"){       
       digitalWrite(lamp, HIGH);
     }
     else if(messageTemp == "off"){
       digitalWrite(lamp, LOW);
      }
 }
}

// This functions reconnects your ESP8266 to your MQTT broker
// Change the function below if you want to subscribe to more topics with your ESP8266 
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    // Attempt to connect
    /*
     

      WARNING VERY IMPORTANT
     
     
     YOU MIGHT NEED TO CHANGE THIS LINE, IF YOU'RE HAVING PROBLEMS WITH MQTT MULTIPLE CONNECTIONS
     To change the ESP device ID, you will have to give a new name to the ESP8266.
     Here's how it looks:
       if (client.connect("ESP8266Client")) {
     You can do it like this:
       if (client.connect("ESP1_Office")) {
     Then, for the other ESP:
       if (client.connect("ESP2_Garage")) {
      That should solve your MQTT multiple connections problem
    */
    if (client.connect(WiFi.hostname().c_str(), mqttUser, mqttPassword)) {
      // Subscribe or resubscribe to a topic
      // You can subscribe to more topics (to control more LEDs in this example)
   client.subscribe(mqttTopicLamp);

    } else {
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}


// For this project, you don't need to change anything in the loop function. Basically it ensures that you ESP is connected to your broker
void loop() {

  if (!client.connected()) {
    reconnect(); 
  }
 //dont know what this string does, but without it lamp does not work
  if(!client.loop())
    client.connect("ESP8266Client");

  now = millis();

  // Publishes new temperature and humidity every 30 seconds
  if (now - lastMeasure > resendtime) {
    lastMeasure = now;
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht.readHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.readTemperature();
    // Read temperature as Fahrenheit (isFahrenheit = true)
    float f = dht.readTemperature(true);

    // Check if any reads failed and exit early (to try again).
    if (isnan(h) || isnan(t) || isnan(f)) {
      return;
    }

    // Computes temperature values in Celsius
    float hic = dht.computeHeatIndex(t, h, false);
    static char temperatureTemp[7];
    dtostrf(hic, 6, 2, temperatureTemp);
    
    // Uncomment to compute temperature values in Fahrenheit 
    // float hif = dht.computeHeatIndex(f, h);
    // static char temperatureTemp[7];
    // dtostrf(hic, 6, 2, temperatureTemp);
    
    static char humidityTemp[7];
    dtostrf(h, 6, 2, humidityTemp);

    // Publishes Temperature and Humidity values
    digitalWrite(LED_BUILTIN, LOW);
    client.publish(mqttTopicTemperature, temperatureTemp);
    client.publish(mqttTopicHumidity, humidityTemp);
    digitalWrite(LED_BUILTIN, HIGH);
  }
} 

И работает, все говорят что это очень фиговая защита пароль передается в явном виде его можно перехватить, но это хоть что-то — от бытовухи защитит!

В Node-Red записываем в файл данные с указанием времени
Продолжаю разбираться в красном кирпиче. Каждая страница это flow поток, каждый кирпич это node. И моя проблема с кирпичами в сравнение с консолью в том что то что в консоли делается сложновато кирпичами делается просто, то что в консоле делается интуитивно и с миллионом примеров в кирпичах вообще кажется невозможным и ни у кого нет примера! Вот как раз это!

Но у меня получилось вот нужные кирпичи

Туже информацию можно передать текстом со всеми настройками, чтобы добавить к себе надо выбрать в меню Import > Clipboard

[{"id":"2b78492d.489886","type":"ui_chart","z":"476e896a.8c56d8","name":"Temperature","group":"fa72526.2d064b","order":0,"width":0,"height":0,"label":"Temperature","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":370,"y":440,"wires":[[],[]]},{"id":"18a2f60b.0663f2","type":"mqtt in","z":"476e896a.8c56d8","name":"Temperature","topic":"room/temperature","qos":"2","broker":"c5742a15.0a437","x":190,"y":400,"wires":[["2b78492d.489886","184f86e5.78c849"]]},{"id":"a059a740.1ac0c8","type":"file","z":"476e896a.8c56d8","name":"Write file /root/temp_log","filename":"/root/temp_log","appendNewline":true,"createDir":false,"overwriteFile":"false","x":630,"y":400,"wires":[[]]},{"id":"6c769a0d.7bb714","type":"moment","z":"476e896a.8c56d8","name":"","topic":"","input":"","inputType":"msg","inTz":"Europe/Moscow","adjAmount":"3","adjType":"hours","adjDir":"add","format":"","locale":"en_US","output":"time","outputType":"flow","outTz":"Europe/Moscow","x":440,"y":340,"wires":[[]]},{"id":"34e53513.7fbd9a","type":"inject","z":"476e896a.8c56d8","name":"","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":340,"wires":[["6c769a0d.7bb714"]]},{"id":"184f86e5.78c849","type":"function","z":"476e896a.8c56d8","name":"Add time to data","func":"var timenow=flow.get('time');\nmsg.payload = timenow + ' '+ msg.payload + ' '+Date.now();\nreturn msg;","outputs":1,"noerr":0,"x":400,"y":400,"wires":[["a059a740.1ac0c8"]]},{"id":"fa72526.2d064b","type":"ui_group","z":"","name":"Sensor","tab":"2ada7e28.6906ea","order":1,"disp":true,"width":"6","collapse":false},{"id":"c5742a15.0a437","type":"mqtt-broker","z":"","name":"Mosquitto Orange","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"2ada7e28.6906ea","type":"ui_tab","z":"","name":"Room","icon":"dashboard","order":1}]

Я рассчитываю что тот кому надо сделает так, поэтому скриншотов настроек не будет

Начну с конца, нам нужен кирпич file(на картинке Write file /root/temp_log) при чем тот что пишет, он очень похож на тот что читает. Здесь главное указать абсолютный путь до файла.

Кирпич file(на картинке Write file /root/temp_log) получает информацию от кирпича function(на картинке Add time to data) — хороший кирпич, он полностью заменяет кирпич template, если надо вставить слова то делайте это тут, я вставлял пробелы. Это кирпич берет переменную time которая задается в рамках нашего листа — потока — flow (есть еще глобальные и кирпичные)

код в function

var timenow=flow.get('time');
msg.payload = timenow + ' '+ msg.payload + ' '+Date.now();
return msg;

Перемененную time наполняют два кирпича сверху. Кирпитч timestamp он же inject отдает время в нечеловеческом виде раз в секунду. Оно нам не нужно так как в кирпиче function можно и так получить время в таком виде с помощью Date.now(). Поэтому эти данные он скидывает в конвертер времени moment(кирпич справа) его надо ставить отдельно. В меню Manage Palette > Palette > Install находим node-red-contrib-moment и ставим его. Он задает переменную time в рамках flow в более менее человеческом виде.

Последний кирпич старый он отадет просто цифру температуру всем кто к нему подключен.

UPD: ВАЖНО: Пропадает конфиг после смены имени хоста
Да если поменять hostname на машине на которой Node-Red то пропадает весь конфиг, то есть все. Но не все потеряно, над просто
1. Остановить Node-Red
2. В папке с настройками Node-Red у меня это /root/.node-red
3. Переименовать файлы flows_orangepipcplus.json flows_orangepipcplus_cred.json на новый хост, где orangepipcplus это старый хост
4. Запустить Node-Red
5. В настройках опять прописать пароль для Mosquitto
6. Сделать бэкап из меню, там только копипастой можно