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

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

  1. netmaster

    netmaster Гик

    А как я радовался когда это увидел. Проверьте что я написал, когда увидел долго удивлялся. Связи нет, а она возвращает true.
     
  2. Sevic71

    Sevic71 Нерд

    ИМХО асинхронный вызов априори не может вернуть результат сразу, т.к. он возврашщает управление до завершения операции. Видимо true в данном контексте означает "я все поняла, данные корректны, пойду отправлять"
     
    ИгорьК нравится это.
  3. Sevic71

    Sevic71 Нерд

    "Уф я тут оптестировался, целый стенд собрал ;)" - я тоже наверное вечером расчехлю ESP-шку. Хотя год назад я сказал себе что не буду ее трогать даже под страхом смертной казни. Так достала ;)
     
  4. netmaster

    netmaster Гик

    Я предпочитаю пользованться термином - машина состояний. Ну и сейчас пойду нарисую все в визио, чтобы потом не забыть, что я тут напрограммер. А давай!
    вместе веселее.

    Кстати тут пришла мысля! А что стоит, сделать запрос от контролера к ЕСП на предмет наличия связи, до того как что-то посылать. Вот пользуйтесь моей гениальностью! :):D:)
     
    Последнее редактирование: 9 фев 2016
  5. ИгорьК

    ИгорьК Гуру

    Текущее состояние NodeMCU, мне кажется, не то что год назад.
     
  6. Sevic71

    Sevic71 Нерд

    Ну вообще-то в "цивильных" MQTT реализациях это работает по умолчанию. Я, например, в саоей программе для обмена RF433 <>MQTT использую библитотеку paho mqtt for C. Так вот она мало того, что "сама" в бэкграунде отсылает в брокер keep alive сообщения, так еще и мгновенно реагирует если брокер становится недоступен. Правда, и программа и брокер крутятся на одной "малине", удаленно не пробовал. Хотя то же myMQTT на телефоне тоже мгновенно реагирует если брокер уходит.
     
  7. Sevic71

    Sevic71 Нерд

    "Текущее состояние NodeMCU, мне кажется, не то что год назад." -приятно слышать и всячески на это уповаю. Потому как сама по себе ESP уникальна по совокупности характеристик, но вот кривизна реализации постоянно навевала мысли о зря потраченном времени. Мой друг не выдержал, и повыкидывал их к черту, банально заменил ардуинами с езернет шилдами, благо кабели у него были заложены везде.
    А моя "скотинка" пару раз врубала котел на даче на неделю, хотя никто ее об этом не просил. В итоге пришлось оплачивать этот "банкет" газовой конторе, итоговая сумма превышала стоимость ESP раз этак в пять. Но я на нее не сержусь, косяк был мой и весьма своеобразный..
     
  8. netmaster

    netmaster Гик

    Пока тестировал так у меня этот код и не заработал.
    Код (Java):
    m:on("connect", function(client) print ("connected") end)
    Прошивку мне собирали на сайте.
     
    Последнее редактирование: 9 фев 2016
    ИгорьК нравится это.
  9. ИгорьК

    ИгорьК Гуру

    Нонсенс. Перепрошивайтесь.
    5555555.jpg
     
    Последнее редактирование: 9 фев 2016
  10. ИгорьК

    ИгорьК Гуру

    WOW! А Вы правы! Пересмотрел свой код - оказывается я этой конструкцией никогда и не пользовался последнее время.
    Делаю так. Если m: on("offline", function(con) - останавливаю таймеры или запрещаю отправки. А разрешаю на m: connect или m: subscribe - смотря по обстоятельствам.

    Во как, век живи, век мозги тренируй. Раньше точно это работало. Сейчас в конструкции
    Код (C++):
    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("/myhome/dacha/kotel/command",0, function(conn)
                    print("Subscribed!")
                end)
            end)
            m:on("connect", function(conn) print ("connected connected connected") end)
        end
    end)
     
    m: on("connect", - блокирует обе вышестоящих callback функции.
     
    Последнее редактирование: 9 фев 2016
  11. Sevic71

    Sevic71 Нерд

    А как все таки сейчас с памятью дела обстоят с точки реализации постоянного коннекта к брокеру?Я имею в виду, если MQTT-линк поднять сразу после конекта в сеть и держать постоянно поднятым, выполнение прочих операций типа опрос DS18B20 , отправлять данные и отрабатывать логику простого термостата, памяти хватает? Или все же нужно все делать по очереди : читаем датчик, коннектимся к MQTT, отправляем -данные -дисконнектимся -термостатируем? (с промежуточными уборками мусора, ессно)
     
  12. netmaster

    netmaster Гик

    Присоединюсь к коллеге с его просьбой. Как по Вашему лучше работать и контролировать heap в esp8266. Хочется с подробностями, а уж со ссылками на Ваши работы - было бы просто здорово.
     
  13. ИгорьК

    ИгорьК Гуру

    Берем, проверяем, тестируем, "убиваем" любыми способами. Логика там ясна.
    Только не забываем, что прошивку надо собирать, а не заливать ту, что идет с прошивальщиком.

    Код (Lua):
    -- Отправка температуры DS18b20
    pin = 4
    Broker="вашсайт"
    port=вашпорт
    myClient="tempMuv01"
    iogin="tempMuv01"
    pass="passWord"

    m = mqtt.Client( myClient, 120, login, pass)
    m:lwt("/lwt/", myClient, 0, 0)
    m:on("offline", function(con)
         print ("Mqtt Reconnecting.")
         tmr.stop(2)
         tmr.alarm(1, 90000, 1, function()
             print ("Try Reconnecting...")
             m:connect(Broker, port, 0, function(conn)
                 print("Mqtt Connected to "..Broker)
                 tmr.stop(1)
                 tmr.start(2)
             end)
         end)
    end)

    function publish_data()
            local ds18b20 = require('ds18b20')
            ds18b20.setup(pin)
            local addres={}
            addres=ds18b20.addrs()
            local t = ds18b20.read(addres[1])
            print('t= '..t)
            if t ~= 85 and t ~= nil then
                    m:publish("/myhome/dacha/tempMuv01/state",t,0,0, function(conn)
                       print("Temp "..t.." published!")
                       tmr.alarm(1, 10000, 0, function()
                            m:publish("/myhome/dacha/tempMuv01/heap",node.heap(),0,0, function(conn)
                            print("Heap published!")
                            end)
                        end)
                    end)
            else
                m:publish("/lwt/","tempMuv01 bad DS18b20",0,0,function(conn) print("Bad published!")end)
            end
            ds18b20 = nil
            package.loaded["ds18b20"]=nil
            collectgarbage()
    end

    function run_main_prog()
        print("Main  program starts!")
        tmr.alarm(2, 60000, 1, publish_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("Mqtt Connected to: " .. Broker)
                 run_main_prog()
             end)
         end
    end)

     
    Отправка данных с Ардуино и передача на него.
    Данные поступают в оба конца в формате Х:У
    Код (Lua):
     -- ESP8266 <=> Arduino
    Broker="вашсайт"
    port=вашпорт
    myClient="ESPUART01"
    name="ESPUART01"
    pass="password"
    sendmessage = false

    m = mqtt.Client(myClient, 180, name, pass) -- Объявляем MQTT клиента
    m:lwt("/lwt", myClient, 0, 0) -- Сообщение OpenHab о потере связи
    m:on("offline", function(con) -- Функция для возобновления связи с брокером, если терялась сеть
        sendmessage = false
        print ("reconnecting...") -- Закомментировать для рабочего варианта
        print(node.heap()) -- Закомментировать для рабочего варианта
        tmr.alarm(1, 120000, 1, function() -- Многократный вызов
              m:connect(Broker, port, 0, function(conn) -- Адрес и порт брокера
                tmr.stop(1) -- если соединились, прекращаем соединение
                m:subscribe("arduino01/#",0, function(conn)
                      sendmessage = true
                      print ("Subscribed!")
                end)
              end)
            collectgarbage() -- Почистим память
        end)
    end)

    uart.on("data","\n",  -- Функция обработки информаци из UART
        function(input)
            if wifi.sta.status() == 5 then
                print("Received from UART:", input) -- Закомментировать для рабочего варианта
                local topic -- Две локальные переменные для захвата информации
                local info
                -- Функция захвата. Захватываем только шаблоны типа "Цифры-двоеточие-цифры ( и необязательно)-точка-цифры"
                topic, info = string.match(input, "(%d+):(%d+%.?%d?%d?)")

                if topic ~= nil  then -- Только если прошел правильный захват. Иначе и topic и info будут nil
                    if (wifi.sta.status() == 5) and (wifi.sta.getip() ~= nil) and (sendmessage == true) then
                        print("Publish Topic: "..topic.." and Info: "..info) -- Закомментировать для рабочего варианта
                        m:publish("arduino01/"..topic.."/state",info,0,0) -- Публикуем на брокер
                    end
           
                end
                topic = nil -- Освобождаем и чистим память
                info = nil
                collectgarbage()
            end
      end, 0)
    m:on("message", function(conn, topic, data) -- Если пришли банные от брокера
        if (string.find(topic, "state")) == nil then -- И если это не подтверждение состояния, то есть в строке отсутствует "state"
            local top = string.gsub(topic, "arduino01/","") -- Удаляем лишнюю часть информации
            print("To Arduino -> ") -- Закомментировать для рабочего варианта
            print(top..":"..data) -- Отправляем на Ардуино по UART
        end
        collectgarbage() -- Чистим память
    end)

    tmr.alarm(0, 1000, 1, function() -- Подписываемся на все топики, начинающиеся на "arduino/"
        if wifi.sta.status() == 5 and wifi.sta.getip() ~= nil then -- Если связь установлена
            tmr.stop(0) -- Останавливаем этот таймер, чтобы на повторять подписку
              m:connect(Broker, port, 0, function(conn)  -- Подписываемся
                  sendmessage = true
                  print("connected") -- Закомментировать для рабочего варианта
                  m:subscribe("arduino01/#",0, function(conn)
                  end)
            end)
        end
    end)
     
     
    Последнее редактирование: 10 фев 2016
  14. ИгорьК

    ИгорьК Гуру

    А вот MODQUITTO установить на BeagleBone Black c Debian 8 пока не удается. И получается то, что указывал товарищ тут двумя страницами ранее - connection refused. Будем разбираться.
     
  15. netmaster

    netmaster Гик

    А это скорее всего по 2 причинам 1) файрвол 2) версия москита (см. ранее)

    Код (Javascript):
    mosquitto -v
    1455088421: mosquitto version 1.4.7 (build date 2016-02-05 11:43:32+0300) starting
    1455088421: Using default config.
    1455088421: Opening ipv4 listen socket on port 1883.
    1455088421: Opening ipv6 listen socket on port 1883.
    1455088424: mosquitto version 1.4.7 terminating
     
     
    Последнее редактирование: 10 фев 2016
    ИгорьК нравится это.
  16. ИгорьК

    ИгорьК Гуру

    Файрвола нет, москит последний. Не суть. Решил понять что такое Paho. (Не скоро.)
    Что посоветуете почитать, чтобы понимать это все?
    У ардуинщика, как справедливо указывал некий нетоварщ, есть два путя:
    Arluino => AVR => регистры => ассемблер
    или
    Arluino => Малина/BeableBone => Linux => Python
     
  17. netmaster

    netmaster Гик

    Игорь Paho это таже тема с версиями MQTT, если не ошибаюсь, в настройках Paho есть возможность выставить 3 или 4 это собсвенно эквивалент 3.1 или 3.1.1

    Вот Вы и приплыли к моей используемой IDE у меня Eclipse под все на чем можно програмить и что можно програмить - кроме Lua (но еще не вечер!). Не настаиваю, просто советую.

    А путей много, когда пути нет - я сделаю свой.
     
  18. ИгорьК

    ИгорьК Гуру

    Москит с офсайта на Debian 8 Jessie - не устанавливается без бубна. Устанавливается на Debian 7 Weezy без проблем.
     
  19. netmaster

    netmaster Гик

    Вы наверное имеете ввиду, что через apt-get не устанавливается и ставите на BeagleBone Black так?

    К теме Paho это каким боком? Paho ведь клиентская часть.
     
  20. Sevic71

    Sevic71 Нерд

    По поводу paho - можно начать читать с этого http://i-o-t.ru/protokol-mqtt/
    По сути комплект библиотек для реализации обмена по MQTT. Я использовал вне Eclipse, т.к. пишу "по старинке" прямо на малине в текстовом редакторе и собираю с помощью make. Пока этого хватает. В принципе, имея представление о MQTT ничего сложного нет, у меня взлетело почти сразу даже на C, на python тоже попробовал, без проблем вообще, там с библиотекой идут рабочие примеры, с них можно смело начинать. Был один трабл, отнял пару вечеров пока не разобрался. В первой реализации я собирался использовать только pub. sub отложил на потом, о чем жестоко пожалел ;). Мои pub сообщения отправлялись только раз (в смысле первое после коннекта), остальные пропадали. Т.е. функция отправки отрабатывает без проблем (как казалось), а сообщения в топике нет. Как оказалось, брокер отключал меня через 120 секунд, потому как срабатывал keep alive timer. Чтобы этого не происходило, нужно периодически "слушать" входящий сокет от брокера, при этом библиотека сама отправляет keep alive сообщение. Даже если ничего получать не собираемся, периодически надо вызывать библиотечную функцию yield (или как-то так), она как раз и отрабативает протокольные "реверансы" по keep alive. После того как разрулил эту ситуацию, все заработало без проблем. И еще - для тестирования я использовал прогу -консольный pub client из комплекта поставки paho for C. У нее обнаружился один неприятный момент - она при отправке оставляет в payload символ перевода строки. Так сразу не заметно, работает да и ладно, но вот openhab категорически отказывался принимать такие сообщения. С виду там типа ON или OFF, но openhab решительно отказывается их обрабатывать
     
    Последнее редактирование: 10 фев 2016
    ИгорьК нравится это.