Подписываемся на датчики

от автора

Электроника плотно укоренилась в нашей жизни. И речь идёт не о повседневном пользовании благами цивилизации. Мы говорим о тех моментах, когда устройства, созданные на аломощных и недорогих компонентах, решают довольно большой спектр повседневных задач. Они омогают нам с бытом, следят за безопасностью и контролируют наше жилое пространство.

С чего началось

 Решил я с приближением зимнего периода, понаблюдать за температурными параметрами в своей квартире и определить качество отопления, если можно так сказать. Если рассмотреть идею с точки зрения DS18B20 (1-wire) — показать основной принцип. В дальнейшем, без труда можно добавлять любое количество датчиков. Крепить их в необходимых точках и считывать этот физический мир ?. Задача на самом деле довольно тривиальна с учетом наличия большого числа IoT платформ. Но лично мне хотелось получить от процесса больше свободы. Иметь возможность не только получать данные на готовый https://habr.com/ru/articles/463 669/

MQTT хорошо себя зарекомендовал как раз в сфере домашней автоматизации и систем IoT. 

Моя панель Дома с Алисой после добавления точек

Моя панель Дома с Алисой после добавления точек

  Данные будут поступать или на IoT платформу или на любого клиента. Я в качестве таковых использовал «Дом с Алисой» и одну из платформ для облачных решений в области IoT, MQTT-брокер «wqtt.ru». Он предоставляет возможность легкой интеграции с «Дом с Алисой». Достаточно прост авторизоваться в системе через аккаунт Яндекса. Далее в приложении
выбрать сервис WQTT. https://rightech.io/ — версия верхнего уровня представляет собой уже готовое решение — облачный сервис для интернета вещей. Имеется дружелюбный мануал по настройке связи с нижним уровнем, добавлению сущностей и обработки событий.

Второй вариант более сложный, с точки зрения клиент-серверной части, но, так как я сам занимаюсь Javascript и Заветный JSON файл.

Заветный JSON файл.

По умолчанию, Express работает с шаблонизатором // подключаем необходимые библеотеки и модули var createError = require("http-errors"); var express = require("express"); var path = require("path"); var cookieParser = require("cookie-parser"); var logger = require("morgan"); var indexRouter = require("./routes/index"); var usersRouter = require("./routes/users"); var testRouter = require("./routes/test"); var mq = require("./lib/mq.js"); mq.mq(); var {tempHot}=require('./lib/mq.js'); app.listen(80); app.set("views", path.join(__dirname, "views")); app.set("view engine", "pug"); app.use(logger("dev")); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, "public"))); app.use(express.static(path.join(__dirname, "lib"))); //обработка GET-запроса app.use("/", indexRouter); app.use("/users", usersRouter); app.use("/test", testRouter); app.get('/data', (req, res) => { res.setHeader('Content-Type', 'text/html'); res.write('<!DOCTYPE html>'); res.write('<html>'); res.write('<head>'); res.write('<title>Hello Node.js</title>'); res.write('<meta charset="utf-8" />'); res.write('</head>'); res.write(tempHot, ()=>{ console.log(tempHot) }); res.write('</html>'); res.end(); }) // перехват ошибки 404 app.use(function (req, res, next) { next(createError(404)); }); handler app.use(function (err, req, res, next) { res.locals.message = err.message; res.locals.error = req.app.get("env") === "development" ? err : {}; // формирование странички с ошибкой res.status(err.status || 500); res.render("error"); }); module.exports = app;

Модуль MQTT:

//подтягиваем библеотеки и переменные console.log("Script is RUN!"); const mqtt = require("mqtt"); const host = "m3.wqtt.ru"; const port = "9309"; const connectUrl = `mqtt://${host}:${port}`; const fs = require("fs"); var tempRoom; var obj; var data; //экспортируем модуль  exports.mq = () => {     const client = mqtt.connect(connectUrl, {         clean: true,         connectTimeout: 4000,         username: "YOUR USERNAME",         password: "YOUR PASSWORD",         reconnectPeriod: 1000,     });     Error.stackTraceLimit = 10;     const topic = "base/state/temperature_room";     client.on("connect", () => {         console.log("Connected");         client.subscribe([topic], () => {             console.log(`Subscribe to topic '${topic}'`);             client.on("message", (topic, payload) => {                 tempRoom = payload.toString();                 console.log("Temp room from module", +tempRoom);                 data = {                     room: tempRoom,                     hot: "wait"                 };                 data = JSON.stringify(data);                 fs.writeFile('/home/a0888254/domains/a0888254.xsph.ru/public_html/myapp/lib/data.json', data, (err) => {                     if (err) {                         console.error(err)                         return                     }                     console.log("File is writed!)");                 })             });                    });     }); };  

Клиентская сторона

Затем я хочу использовать возможности JavaScript по записи и считыванию файлов, таким образом создав некий буферный файл, в котором текущие параметры перезаписываются при следующем обновлении. Именно отсюда я буду вытягивать AJAXом значения на клиентскую сторону. Для начала надо создать и подключить необходимый скрипт. Для этого в папке Public создадим файл app.js. Листинг можно найти в тут: /public/javascript/app.js Его задача получать данные из JSON, парсить их и выводить на страничку в режиме реального времени.

/*Когда сформировался DOM - начинается исполнение кода.  Функция readFile принимает в квачестве параметргов два аргумента.  А в  качестве обратного вызова передает ответ на запрос.*/  document.addEventListener("DOMContentLoaded", function () {   var data;   var outputs = document.getElementsByTagName("output");    function readFile(file, callback) {     var rawFile = new XMLHttpRequest();     rawFile.overrideMimeType("application/json");     rawFile.open("POST", file, true);     rawFile.onreadystatechange = function () {       if (rawFile.readyState == 4 && rawFile.status == "200") {         callback(rawFile.responseText);       }     }     rawFile.send()   }   function rd() {     readFile("myapp/lib/data.json", function (text) {       data = JSON.parse(text);       outputs[0].innerHTML = '<h2 id="data" style="color=#ff6347">' + data.hot + '°C' + '</h2>';       outputs[1].innerHTML = '<h2 id="data">' + data.room + '°C' + '</h2>';     });   };   setInterval(rd, 5000) });

На клиентской стороне размещаются элементы, с которыми взаимодействует конечный пользователь. Будь то простое визуальное взаимодействие (визуальный контроль) или
непосредственные инструменты влияния на процесс. Тут речь идет о всевозможных регуляторах, кнопках, ползунках, слайдерах. В нашем случае мы просто мониторим процесс. Потому нам достаточно будет вывести схематичное отображения измеряемого параметра. и само значение. В дальнейшем, эта страничка может обрасти массой элементов управления и может даже получить звание полноценной SCADA системы. Кто знает ?

Я просто написал страничку на HTML и перевел ее в PUG для шаблонизатора. Обращайте внимание на то, какой шаблон нам надо использовать. Layot — это общий шаблон. В нем можно ничего не править. А вот index.pug — наш малец. В нем мы и работаем в контексте этого абзаца.

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

Ссылка на мой репозиторий github c исходниками тут.


ссылка на оригинал статьи https://habr.com/ru/articles/786322/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *