ESP32: отправка данных на Telegram, Народный мониторинг и MQTT брокер, сигнализация.

Тема в разделе "Глядите, что я сделал", создана пользователем ИгорьК, 4 дек 2017.

  1. ИгорьК

    ИгорьК Давно здесь

    Начнем так ("патамучто!"):

    upload_2017-12-4_17-14-8.png

    Датчиков - любое количество. Один - тоже сгодится.

    Нет, сначала превратим ESP32 в Espruino. Вот здесь раскрыто как это делается. Вопросы по трансформации лучше задать в той теме (Все равно она мной создана).

    В итоге, надо добиться в окне Espruino IDE следующей картины:
    upload_2017-12-4_17-19-45.png


    Ну а потом заливаем в Espruino-ESP32 скрипт:

    Код (Javascript):
    // -- Установить свое: -- //
    var ssid = 'ВАША_ТОЧКА_ДОСТУПА';
    var password = 'ВАШ_СУПЕРПАРОЛЬ';
    // Это надо придумать самому для Народного Мониторинга, однако '#' в начале и  '\n' в конце - сохранить!
    var secretword = "#12:34:56:78:90:AB\n";
    var brok = "iot.eclipse.org";
    var port = "1883";
    var topikk = "myESP32/abrakadabra01/ ";
    // -----------------------//

    var cl = console.log;
    var wifi = require('Wifi');
    var mod = {broker : false};
    var mqtt;
    var start;
    var tick;
    var nextCheck;
    var dattable = {};

    function repeat() {
        nextCheck =  setTimeout(tick, 15000);
    }

    function mqttnow() {
        cl('Start MQTT');
        mqtt = require("MQTT").connect({
            host: brok,
            port: port
        });
        mqtt.on('connected', function() {
            cl('Connected!');
            // mqtt.publish("test/esp32", "ON"); // Это на перспективу :-)
            // mqtt.subscribe("test/esp32/command");
            mod.broker = true;
            // cl('Subscribed!');
            start();
        });

        mqtt.on('publish', function (pub) {
            cl("topic: "+pub.topic);
            cl("message: "+pub.message);
        });

        mqtt.on('disconnected', function() {
            mod.broker = false;
            cl("MQTT disconnected... reconnecting.");
            tick();
        });
    }

    start = function(){
        var ow = new OneWire(21);
        var sensors = ow.search().map(function (device) {
            return require("DS18B20").connect(ow, device);
        });

        sensors.forEach(function (sensor, index) {
            cl(sensor, index);
        });

        setInterval(function() {
            sensors.forEach(function (sensor, index) {
                cl("\n");
                let dska = 0;
                sensor.getTemp(function (temp) {
                    var tt = temp.toFixed(2);
                    dska = sensors[index].sCode;
                    dattable[dska] = tt;
                    cl(dska + ": " + tt + "°C");
                    if(mod.broker) {
                        mqtt.publish(topikk + dska, tt);
                        cl("Pub: Temp is " + tt + "°C");
                    }
                });
            });
        }, 30000);
    };

    function getwifi(){
      wifi.connect(ssid, {password: password}, function(er) {
        if(er) {
          cl('Error Wifi connect:', er);
          return;
        }
        cl('Connected to Wifi.  IP address is:', wifi.getIP().ip);
        //wifi.save();
        mqttnow();
      });
    }

    tick = function() {
        cl("Check WiFi!");
        wifi.getDetails(cl);
        wifi.getIP(function(tb){
            cl(tb.ip);
            if(tb.ip !=="0.0.0.0") {
                try {
                    if (mqtt == "undefined"){
                        mqttnow();
                    }
                    else {
                        if (mqtt.connected) return;
                        mqtt.connect();
                    }
                } catch(e){
                    repeat();
                }
            }
            else {
                repeat();
                getwifi();
            }
        });
    };

    function sendnm() {
        if(mod.broker === false) return;
        cl("\n\n\nNarodmon Starts!");
        let tomon = secretword;
        for (var key in dattable) {
            tomon = tomon + "#"+key+"#"+dattable[key]+"\n";
        }
        tomon = tomon + "##\n";
        cl(tomon);

        var client = require("net").connect({host: "narodmon.ru", port: 8283}, function() {
            cl('client connected');
            client.write(tomon);
            client.on('data', function(data) {
                cl(">"+JSON.stringify(data));
            });
            client.on('end', function() {
                cl('client disconnected');
            });
        });
        cl("\n \n \n");
    }

    setInterval(sendnm, 5*60*1000);
    repeat();
    getwifi();

    Работает:
    upload_2017-12-4_17-37-28.png

    Почему три датчика? На улице, в доме и в контуре отопления - вот и три.

    Почему перспективная система? В ближайшее время поработаю ее таким образом, что можно будет подключать и иные датчики, а значит... ПРОДОЛЖЕНИЕ!
     
    Последнее редактирование: 13 дек 2017
  2. IvanUA

    IvanUA Гуру

    Игорь я правильно понимаю что для Espruino IDE - это нормально залить скрипт, посмотреть его работу, и при повторном включении необходимо снова заливать скрипт?
    Как то можно его сохранить в энергонезависимую память? Или как его стартовать после ресета?
    Или есть другая ИДЕ с более расширенными функциями?
     
    Последнее редактирование: 5 дек 2017
  3. ИгорьК

    ИгорьК Давно здесь

    Там в настройках есть галка "(типа) Сохранить при заливке".
    Ее выставлять стоит только после полной отладки устройства, иначе придется частенько его перешивать полностью.
     
    IvanUA нравится это.
  4. IvanUA

    IvanUA Гуру

    Спасибо, нашел, все сохраняет)))

    PS.Пойду бороздить просторы Espruino
     
  5. ИгорьК

    ИгорьК Давно здесь

    Дык... Заработало?
     
    IvanUA нравится это.
  6. IvanUA

    IvanUA Гуру

    Да, сейчас пробую начинать разбираться как работает ваш скрипт.))))))
     
    Последнее редактирование: 5 дек 2017
  7. ИгорьК

    ИгорьК Давно здесь

    Я доработаю его позже и закомментирую. Сейчас специально сделал для копипасты.
    ESP32 + Espruino - это надолго.
     
  8. IvanUA

    IvanUA Гуру

    Самому уже нравится. Читаю статьи Амперки по данной теме, и слюна аж брыжжит)))))))
    Чувствую что опять начнутся бессонные ночи как это было с ардуинкой...
     
    ИгорьК нравится это.
  9. ИгорьК

    ИгорьК Давно здесь

    С почином :)
     
    IvanUA нравится это.
  10. IvanUA

    IvanUA Гуру

    Игорь подскажите, если МQTT сервер с авторизацией, то где ее прописать.
    Без авторизации работает отлично.

    А вот с народным мониторингом пришлось повозиться.
    Код упорно не хотел перед ID датчика добавлять #. И не разделял показания датчиков с новой строки.
    Пришлось немного поправить код.
    Код (Java):
    var secretword = "#12:34:56:78:90:AF";
    ...
    tomon = tomon+"\n"+"#"+key+"#"+dattable[key]+"\n";
     
  11. ИгорьК

    ИгорьК Давно здесь

    Не знаю что на это сказать - у меня все отлично работает именно в том виде, как и представил.
    Уже привык выкладывать пруфы - он есть на фото.

    Хотя, возможно, Вы правы - я же чистил СВОЙ код перед публикацией и выносил в заголовки все что у меня там было по-умолчанию, возможно что-то пропустил.

    Потерял "\n"! Точно. Исправил.

    Вот как это в работающем коде:
    upload_2017-12-6_0-37-13.png


    Код (Javascript):
    var server = "192.168.1.10";
      var options = { // Все опционально
        client_id : "myESP32",
        keep_alive: 60,
        port: 1883,
        clean_session: true,
        username: "username",
        password: "password",
        protocol_name: "MQTT",
        protocol_level: 4,
      };
       var mqtt = require("MQTT").create(server, options);
     
    Последнее редактирование: 6 дек 2017
    IvanUA нравится это.
  12. IvanUA

    IvanUA Гуру

    Супер - спасибо.

    ПС. В функции вывода на народный мониторинг вы используете проверку флага коннекта к МQTT серверу (mod.broker) - и если нет коннекта то данные не передаются. Может стоит выполнять проверку не коннекта к MQTT, а подключения к WiFi сети? Просто мне кажется что это не зависимые вещи. Для себя в массиве добавил флаг (mod.wifi) - и уже делаю проверку по нему.
     
  13. ИгорьК

    ИгорьК Давно здесь

    Тут что важнее
    Для меня народный мониторинг факультатив.
    А так да - можно добавить.
     
  14. ИгорьК

    ИгорьК Давно здесь

    В целом, здесь важнее даже не флаги - это дело простое, а организация отправки mqtt данных без callback функций публикации - их нет в библиотеке. (А на Lua NodeMCU - ЕСТЬ!)

    И обеспечение совместной работы разных датчиков. Если датчики разные такой метод публикации как сейчас не прокатит. Мониторинг же будет работать и с разными датчиками.

    Сегодня накидал более менее.
    Думаю, и для Вас со временем Народный мониторинг отойдет на второй план.
     
    Последнее редактирование: 6 дек 2017
  15. IvanUA

    IvanUA Гуру

    Ну да так и есть)))
     
  16. IvanUA

    IvanUA Гуру

    Могу конечно ошибаться, но callback функция не публикует, а наоборот проверяет нет ли входящих сообщений.
    По идее, callback - можно попробовать организовать при помощи той же функции setInterval. А что бы не пропустить входящее сообщение - если есть конечно, то включить функция SSL (подтверждение доставки сообщения).

    По поводу публикации сообщений с разных датчиков. Опрос датчиков, я бы вынес в отдельную функции со своим таймингом. А публикацию делал бы отдельно.

    Еще надо решетку в начале
    Код (Java):
    var secretword = "#12:34:56:78:90:AB\n";
    ПС. Игорь, спасибо. Благодаря вашему труду, я сегодня реально начал пробовать разобраться в ява скрипте, еспруино и.... До этого ESP32 - лежала у меня больше месяца мертвым грузом, и я не знал с какого боку к ней подойти))) А планы то на нее есть.
     
    Последнее редактирование: 6 дек 2017
    ИгорьК нравится это.
  17. IvanUA

    IvanUA Гуру

    Допилил таки прием данных по MQTT.
    Код (Javascript):
        mqtt.on('publish', function (pub) {
            console.log("topic: "+pub.topic);
            console.log("message: "+pub.message);
                if (pub.topic=="mydevice/1/set") {
                      var v = pub.message != 0;
                      digitalWrite(D18, v);
                }
                if (pub.topic=="mydevice/2/set") {
                      var v = pub.message != 0;
                      digitalWrite(D19, v);
                }
    Теперь при получении любого сообщения светодиоды зажигаются, а при поучении "0" гасятся.
    Вот только не пойму, почему в окне листинга программы, у меня стоят восклицательные знаки. Что не так?
    ПС. Еще надо подписаться на этот топик.
     
    Последнее редактирование: 9 дек 2017
    ИгорьК нравится это.
  18. ИгорьК

    ИгорьК Давно здесь

    Помнится, Вы там тему по управлению отоплением делали... :)
    Чет здесь Вы слишком усложнили, но кому как нравится :)
     
  19. IvanUA

    IvanUA Гуру

    Можно конечно и проще))
    Код (Javascript):
    if (pub.topic=="mydevice/1/set") {D18.write(pub.message)}
    Или можно еще проще?
     
    Последнее редактирование: 9 дек 2017
    ИгорьК нравится это.
  20. ИгорьК

    ИгорьК Давно здесь

    Вот это правильно:)
     
    IvanUA нравится это.