Arduino, ESP8266 Lua, Raspberry Pi 2 && OpenHab. Умный дом: азы управления.

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

  1. alp69

    alp69 Форумчанин

    Кто-то твердотельные реле типа S202S02 использует в этом (аналогичном) проекте? Они не мешают работе ESP помехами при срабатывании?
    Да и вообще, есть у кого практический опыт применения симисторов, управляющих без детектора нуля ~220 вольтовой нагрузкой, в непосредственной близости от ESP? Имеется ввиду помехоустойчивость ESP.
     
  2. ИгорьК

    ИгорьК Гуру

    Использую. Правда не в непосредственной близости, а в одной комнате.
    Не думаю что будут проблемы. Твердотельное реле штука электронная, а не механическая. Помех от нее нет.
     
  3. ИгорьК

    ИгорьК Гуру

    Значицца так, друже! Дошли у меня руки посмотреть, якобы, мой код. Я взял именно тот, что Вы привели.

    1. Где же это у меня в таймере переподключения стоит время 6 секунд? Там стоит время 2 минуты. Почему так? Потому что клиент по одной команде делает 4 попытки переподключения, которые, в общей сложности, занимают не менее минуты.

    Заставлять его переподключаться повторно, пока идет первая сессия, недопустимо. Тестовый код в таком случае не валится, потому что в нем ничего нет. Он просто выдает:
    Код (Javascript):
    > dofile("mqttTest001.lua");
    > connected
    offline at 328278101
    DNS retry 1!
    DNS retry 1!
    DNS retry 1!
    DNS retry 2!
    DNS retry 1!
    DNS retry 1!
    DNS retry 2!
    DNS retry 1!
     
    То есть, запустились три сессии только за одну попытку пересоединения. А за четыре сколько запустится? Только на этом участке мы видим шесть сессий.

    Если программа более менее тяжелая, вся эта история завалит модуль.

    2. Одновременно с выключением модема я запустил таймер на телефоне Как только увидел дублирование сессий - включил модем. После соединения - выключил таймер:
    Общее время операции:
    Screenshot_20160516-103344.png
    3. Теперь код:
    Код (Javascript):

    my_timer = 0
    start_timer = 0
    m = mqtt.Client(myClient, 30, name, pass)
    m:lwt("/lwt", myClient, 0, 0)
    m:on("offline", function(con)
        my_timer = tmr.now()
        print("offline at "..my_timer)
        tmr.alarm(1, 60000, 1, function()
              m:connect(Broker, port, 0, function(conn)
                tmr.stop(1)
                print("Reconnected by "..((start_timer - tmr.now())/1000000).." sec. from switch off modem")
                print("Reconnected by "..((my_timer - tmr.now())/1000000).." sec. from got disconnected")
                print("Time from switch off modem to got disconnected: "..((my_timer - start_timer)/1000000))
         
                m:subscribe(myClient.."/#",0, function(conn)
                end)
              end)
            collectgarbage()
        end)
    end)

    m:on("message", function(conn, topic, data) -- Если пришли данные от брокера
    print(data)
    end)


    tmr.alarm(0, 1000, 1, function()
        if wifi.sta.status() == 5 and wifi.sta.getip() ~= nil then
            tmr.stop(0)
              m:connect(Broker, port, 0, function(conn)
                  print("connected")
                  m:subscribe(myClient.."/#",0, function(conn)
                  end)
            end)
        end
    end)
     
    И результаты его работы.
    Код (C++):
    > dofile("mqttTest001.lua");
    > connected
    start_timer  = tmr.now() // вручную даю эту команду и одновременно выключаю модм
    > offline at 33683231
    DNS retry 1!  // Включаю модем в это время. Ему надо время на соединение.
    DNS retry 2!
    DNS retry 3!
    DNS retry 4!
    Reconnected by -133.344303 sec. from switch off modem
    Reconnected by -114.043001 sec. from got disconnected
    Time from switch off modem to got disconnected: 19.306758 sec. from got offline
     
     
    Последнее редактирование: 16 май 2016
  4. ИгорьК

    ИгорьК Гуру

    30. Быстрое восстановление связи с брокером MQTT. Шаблон.
    Как результат вопроса выше, предлагаю уважаемой публике для тестирования следующий код поддержания здоровья и связи с брокером mqtt:
    Код (Lua):
    Broker="ВАШ_БРОКЕР"
    port=ВАШ_ПОРТ
    myClient="nooLite"
    name=myClient
    pass="ВАШ_ПАРОЛЬ"
    my_timer = 0
    publish = false

    m = mqtt.Client(myClient, 30, name, pass)
    m:lwt("/lwt", myClient, 0, 0)

    m:on("offline", function(con)
        publish = false
        my_timer = tmr.now()
        print("Offline at "..(my_timer/1000000))
        m:connect(Broker, port, 0, 0,
            function(conn)
                publish = true
                tmr.stop(1)
                m:subscribe(myClient.."/#",0, function(conn)
                    print("Just Subscribed.")
                end)
                print("Just reconnected by "..((tmr.now() - my_timer)/1000000).." sec. from got disconnected!")
        end)
        tmr.alarm(1, 90000, 1, function()
                  m:connect(Broker, port, 0, function(conn)
                    publish = true
                    tmr.stop(1)
                    print("Reconnected at timer by "..((tmr.now() - my_timer)/1000000).." sec. from got disconnected")
                    m:subscribe(myClient.."/#",0, function(conn)
                       print("Subscribed at Timer.")
                    end)
               end)
         end)
        collectgarbage()
    end)


    m:on("message", function(conn, topic, data) -- Если пришли данные от брокера
        print(topic)
        print(data)
    end)


    tmr.alarm(0, 1000, 1, function()
        if wifi.sta.status() == 5 and wifi.sta.getip() ~= nil then
            tmr.stop(0)
              m:connect(Broker, port, 0, function(conn)
                  publish = true
                  print("Connected")
                  m:subscribe(myClient.."/#",0, function(conn)
                    print("Subscribed.")
                  end)
            end)
        end
    end)
     

    UPD 23/06/2016:
    Код (Lua):
    Broker = "Ваш_Сайт"
    port = Ваш_Порт
    myClient = "Ваш_Клинт"
    name = myClient
    pass = "Ваш_Пароль"
    publish = false -- регулируем возможность публикаций

    m = mqtt.Client(myClient, 180, name, pass)
    m:lwt("/lwt", myClient, 0, 0)

    function connecting()
        print('(Re)Connecting')
        publish = false
        function getConnect()
           if wifi.sta.status() == 5 and wifi.sta.getip() ~= nil then
                print("Got WiFi!")
                m:connect(Broker, port, 0, 0,
                    function(conn)
                        tmr.stop(6)
                        print("Connected")
                        publish = true
                        m:subscribe(myClient.."/#",0, function(conn)
                            print("Subscribed")
                        end)
                end)
            end
        end
        getConnect()
        tmr.alarm(6, 90000, 1, function()
            getConnect()
        end)
    end

    m:on("offline", function(con)
        connecting()
    end)

    --[[
    Здесь ваш код!
    --]]

    connecting()
    ЗЫ. Есть более эффективное решение.
     
    Последнее редактирование: 26 фев 2019
    DeFluder и alp69 нравится это.
  5. ИгорьК

    ИгорьК Гуру

    Видео снять? :)
     
  6. netmaster

    netmaster Гик

    Код (C++):
    > Connected
    Subscribed. -- почти сразу выключил
    --появилось сообщение в брокере подождал еще немного включил модем
    Offline at 82
    Just reconnected by 0 sec. from got disconnected!
    Just Subscribed.
     
    Видео мне не нужно, мне бы понять - почему так. Как обойти я уже придумал, но вот
    понять почему у меня так долго не приходит offline - не могу.

    А сделайте пож-та распечатку от NodeMCU custom build by frightanic.com и до >
    Спасибо.
     
  7. ИгорьК

    ИгорьК Гуру

    Код (C++):
    NodeMCU custom build by frightanic.com
        branch: master
        commit: c8037568571edb5c568c2f8231e4f8ce0683b883
        SSL: true
        modules: bit,cjson,enduser_setup,file,gpio,mqtt,net,node,rtcfifo,rtcmem,rtctime,sntp,tmr,uart,wifi
    build     built on: 2016-03-27 16:31
    powered by Lua 5.1.4 on SDK 1.4.0
    lua: cannot open init.lua
    >
    Я вижу у Вас int а не float, как у меня.
     
  8. netmaster

    netmaster Гик

    Интересная мысль, однако!

    Код (C++):
    NodeMCU custom build by frightanic.com
        branch: master
        commit: c8037568571edb5c568c2f8231e4f8ce0683b883
        SSL: false
        modules: file,mqtt,node,sntp,tmr,uart,wifi
    build     built on: 2016-05-12 09:24
    powered by Lua 5.1.4 on SDK 1.4.0
     
     
  9. ИгорьК

    ИгорьК Гуру

    У меня по-загруженнее будет...
     
  10. netmaster

    netmaster Гик

    Вот такой же тест на float прошивке

    Код (C++):
    > Connected
    Subscribed. --выключил
    --в брокере пришло, чуть позднее включил связь
    Offline at 144.451659
    Just reconnected by 0.031859 sec. from got disconnected!
    Just Subscribed.
     
     
  11. ИгорьК

    ИгорьК Гуру

    Решено?
     
  12. netmaster

    netmaster Гик

    Заметил следущее - время offline он показывает правильно, если связь восстанавливается меньше чем за ~ 10 минут.

    Получается, что логика не совсем такая как я думал... Мыслилось, что offline должно приходить сразу после истечения таймера keepalive, - это так для брокера, но не для клиента. Странно, но получается так.
     
  13. ИгорьК

    ИгорьК Гуру

    Совсем я запутался. Простыми словами:
    Запускаю, законнектился.
    Отрубаю модем.
    Практически сразу, плюс-минус, появляется сообщение оффлайн.
    Через небольшое время появляются сообщения DNS retry 1! - это немедленно срабатывает восстановление коннекта.
    Одновременно запускается таймер на 90 секунд.
    Если в первой сессии соединения не возникнет, начинает долбить таймер до тех пор, пока интернет не появится.

    Никак не пойму вашу проблему. Дайте полный свой лог.
     
  14. netmaster

    netmaster Гик

    Отрубаю модем.
    Практически сразу, плюс-минус, появляется сообщение оффлайн.

    У меня это сообщение появляется только после 10 минут, либо если связь восстанавливается.
    т.е. print("Offline at " что-то там надпись появляется только в этих случаях, а не по истечении keepalive.

    С вашей программой все тоже.

    Еще раз делаю так
    1) вижу Connected
    2) вижу Subscribed.
    3) выключаю модем
    4) Прошло ~ 10 минут вижу "Offline at " что-то там
     
  15. ИгорьК

    ИгорьК Гуру

    То есть модуль просто не выдает информацию о своей подпольной работе.
     
  16. netmaster

    netmaster Гик

    Ну да... сообщений DNS retry 1! у меня просто нет, а обращение к серверу по имени.

    UPD
    Был не прав, сегодня пришел смотрю, - опа!
    > Connected
    Subscribed.
    --модем отключен был все ночь
    Offline at 619.085094
    DNS retry 1!
    DNS retry 2!
    DNS retry 3!
    DNS retry 4!
    DNS Fail!
    и т.д.
    --тут его включили утром
    Reconnected at timer by -382.00877 sec. from got disconnected
    Subscribed at Timer.
     
    Последнее редактирование: 17 май 2016
  17. asda

    asda Нерд

    за поддержание здоровья и связи, хотя абсолютно не согласна в логике, не понимаю чем это может помочь, и главное, когда это соединение осуществится.
    Игорь, объясните, пожалуйста, для человека с нулевым уровнем подготовки - что за 4 коробка на рисунке помимо тех, что в заголовке? и что еще надо приобрести, какие провода может, или еще что, чтобы осуществить это соединение.
     
  18. ИгорьК

    ИгорьК Гуру

    Приношу извинение, но эта тема для Вас не годится. Начинайте, с этой.
     
  19. tammat

    tammat Нерд

    Добрый день, всем!
    Спасибо за интересную и хорошую тему.
    Связал openhab и osanywhereweather (Oregon LW301)
    Использовал
    https://www.npmjs.com/package/osanywhereweather
    и Mosquitto
    osa.js
    Код (C++):
    'use strict'

    var osa = require('osanywhereweather')
    var mqtt    = require('mqtt');
    var client  = mqtt.connect('mqtt://xxx.xxx.xxx.xxx');
    var options = {
      'stationId': 'xxxxx',
      'email': 'xxxxx@gmail.com',
      'password': 'zzzzzz'
    }

    osa.login(options, function (error, data) {
      if (error) {
        console.error(error)
      } else {
        osa.getLiveData({stationId: options.stationId, sessionKey: data.sessionKey}, function (err, json) {
          if (err) {
            console.error(err)
          } else {
            console.log(json);

           client.on('connect', function () {
        });
         client.publish('/oregon/json',JSON.stringify(json));
         client.end();
    }
        })
      }
    })
     
    В Openhab
    Item
    Group Oregon

    String Oregon_json "Oregon [%s]" {mqtt="<[mymosquitto:/oregon/json:state:default]"}
    Number OS_temp "Температура OSA [%.1f°C]" <temperature> (Oregon,Chart_Temp)
    Number OS_Hum "Влажность OSA [%.1f%%]" <humidity> (Oregon,Chart_Humidity)
    Number OS_Press "Давление OSA [%.1fmB]" <pressure> (Oregon)
    Number OS_Press_mm "Давление OSA [%.1fmm]" <pressure> (Oregon)
    Number OS_Rain "Осадки OSA [%.0f mm]" <humidity> (Oregon)
    Number OS_Wind "Скорость ветра OSA [%.1f м/с]" <humidity> (Oregon)
    String OS_Dir "Направление ветра OSA[%s]" <humidity> (Oregon)
    Number OS_wind_gust "Порывы ветра OSA [%.1f м/с]" <humidity> (Oregon)
    Number OS_wind_angle "Направление ветра OSA [%.1f °]" <humidity> (Oregon)
    Number OS_low_battery "Статус батареи OSA [%.0f %%]" <humidity> (Oregon)
    Number OS_sealevel_pressure "Давление на уровне моря OSA[%.1f mm]" <pressure> (Oregon)
    DateTime OS_LastUpdate "Обновлено [%1$td %1$tb %1$tY %1$tT]" <clock> (Oregon)

    Sitemap

    Group item=Oregon label="Oregon" icon="sun"

    Rule

    rule "Mqtt_Json"
    when
    // Item Oregon_json changed or
    // Item Oregon_json updated or
    Item Oregon_json received update
    then
    /* {"status":200,"process_time":21.47507667541504,
    "live":{"wind_speed":"--",
    "rainfall":"--",
    "temperature":"--",
    "low_battery":{},
    "wind_direction":"--",
    "uv":"--",
    "wind_angle":"--",
    "forecast":"--",
    "pressure":"--",
    "local_time":"2016-05-13 16:22:23.645885",
    "sealevel_pressure":"--",
    "humidity":"--",
    "wind_gust":"--"
    }
    }
    */
    var String live = (Oregon_json.state as StringType).toString
    // postUpdate(Oregon_json, live)
    var Or_temp = transform("JSONPATH", "$.live.temperature", live)
    logInfo("Mqtt_Json", "temp Oregon = " + Or_temp)
    postUpdate(OS_temp, Or_temp)
    //OS_temp.postUpdate(Or_temp)
    var Or_Hum = transform("JSONPATH", "$live.humidity", live)
    logInfo("Mqtt_Json", "HUM_Oregon = " + Or_Hum)
    postUpdate(OS_Hum, Or_Hum)
    var Or_Press = transform("JSONPATH", "$live.pressure", live)
    logInfo("Mqtt_Json", "Presure_Oregon =" + Or_Press)
    //logInfo("Mqtt_Json", "Presure_Oregon Type= " + typeof(Or_Press))

    postUpdate(OS_Press, Or_Press)

    var Or_Rain = transform("JSONPATH", "$live.rainfall", live)
    logInfo("Mqtt_Json", "rain_Oregon = " +Or_Rain)
    postUpdate(OS_Rain, Or_Rain)
    var Or_Wind = transform("JSONPATH", "$live.wind_speed", live)
    logInfo("Mqtt_Json", "Wind Speed Oregon = " + Or_Wind)
    postUpdate(OS_Wind, Or_Wind)

    /* не работает
    var Or_Dir = transform("JSONPATH", "$live.wind_direction", live)

    logInfo("Mqtt_Json", "Wind Di Oregon = " + Or_dir)
    //postUpdate(OS_Dir, Or_Dir)
    */

    var Or_wind_gust = transform("JSONPATH", "$live.wind_gust", live)
    logInfo("Mqtt_Json", "Wind Gust Oregon = " + Or_wind_gust)
    postUpdate(OS_wind_gust, Or_wind_gust)

    var Or_wind_angle = transform("JSONPATH", "$live.wind_angle", live)
    logInfo("Mqtt_Json", "wind_angle = " + Or_wind_angle)
    postUpdate(OS_wind_angle, Or_wind_angle)

    var Or_low_battery = transform("JSONPATH", "$live.low_battery", live)
    logInfo("Mqtt_Json", "Or_low_battery = " + Or_low_battery)
    postUpdate(OS_low_battery, Or_low_battery)

    var Or_sealevel_pressure = transform("JSONPATH", "$live.sealevel_pressure", live)
    logInfo("Mqtt_Json", "Or_sealevel_pressure variable = " + Or_sealevel_pressure)
    postUpdate(OS_sealevel_pressure, Or_sealevel_pressure)
    postUpdate(OS_LastUpdate, new DateTimeType())
    end
    Ну и в cron закинул node osa.js
    Все работает, кроме wind_direction, И не могу преобразовать mBar в mm


    Код (C++):
    rule "Pressure in mm"
    when
    Item Or_Press changed or
    Item OS_LastUpdate received update
    then
       var MmHg = (Or_Press.state as DecimalType).intValue()
      logInfo("Mqtt_Json", "Presure_Oregon mm = " + MmHg/1.3328 )
        postUpdate(OS_Press_mm, MmHg/1.3328)
    end
     
    Выдает ошибку.
    2016-05-17 11:20:04.760 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'Pressure in mm': The name 'Or_Press' cannot be resolved to an item or type.
    Есть ли у кого какие мысли?
    Спасибо.
     
    Последнее редактирование: 17 май 2016
  20. ИгорьК

    ИгорьК Гуру

    Дык... Оно говорит: "где же найти итем Or_Press?"