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

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

  1. VelAndr

    VelAndr Нуб

    Где Вы это в конфиге в разделе MQTT binding видели? Вводите человека в заблуждение. Пусть сначала на итемах попробует запуститься.
     
  2. Griffin

    Griffin Нуб

    Event Bus Binding Configuration

    In addition to configuring MQTT publish/subscribe options for specific openHAB items, you can also define a generic configuration in the openhab.cfg file which will act on ALL status updates or commands on the openHAB event bus.

    The following properties can be used to configure MQTT for the openHAB event bus:
    Код (Bash):
    mqtt-eventbus:broker=<broker>
    mqtt-eventbus:statePublishTopic=<statePublishTopic>
    mqtt-eventbus:commandPublishTopic=<commandPublishTopic>
    mqtt-eventbus:stateSubscribeTopic=<stateSubscribeTopic>
    mqtt-eventbus:commandSubscribeTopic=<commandSubscribeTopic>
    Ну и соответственно проверить в дир addons сам binding org.openhab.binding.http-1.x.x.jar, а то всякое бывает.
     
  3. ИгорьК

    ИгорьК Оракул Модератор

    Вот мой конфиг MQTT и этого достаточно:
    Код (Java):
    mqtt:mosquitto.url=tcp://localhost:1883
    mqtt:mosquitto.clientId=MyOpenHab
    Без этого можно обойтись.
     
  4. Sachapda

    Sachapda Нерд

    Здравствуйте друзья!
    Оставлю на всякий случай здесь!
    Проблема была решена откатом с версии хаба 1.8 на 1.7.1
    Всё отлично заработало!
    Похоже в 1.8 присутствует баг!
    win 8 + opnhab 1.7.1 + москит 1.4.7

    Всем огромное спасибо за помощь!
     
    ИгорьК нравится это.
  5. netmaster

    netmaster Гик

    День добрый, коллеги.

    Предлагаю вашему вниманию кусочек кода, проверяющий получаемыее по MQTT данные - ранее я спрашивал как это сделать на OpenHAB и вот что получилось.

    Код (Java):
    Number  Temperature001  "Моя тестовая температура [%.1f]"       <temperature>
    String  _Temperature001 "Скрытый элемент для - Моя тестовая температура"        { mqtt="<[mosquitto:/dev/boil/Temperature001/state:state:default]" }

    import java.util.regex.*

    var String str
    var String sExpr = "^-?\\d+(\\.\\d+$|$)"

    rule "MyTestRule"
    when
    Item _Temperature001 received update
    then
    str = _Temperature001.state.toString
    var Pattern pt = Pattern::compile(sExpr)
    var Matcher mt = pt.matcher(str)
    mt.find()
    if( mt.matches()) {
      logDebug("_Temperature001", mt.group().toString)
      postUpdate(Temperature001, mt.group().toString)
    }else { //broken || error
      logDebug("Temperature001", "Sensor is broken!")
    }
     
    p.s.
    На вполне законнный вопрос зачем? Отвечу так, - мне хочется собрать данные по температуре обратки, температуре в комнатах, температуре,влажности и скорости ветра на улице. И все эти данные сложить в БД для дальнейшего анализа. Но перед тем как их туда положить надо их проверить. Очень рекомендую просмотреть Ваш мануал на котел, скорее всего там есть так называемыя "отопительная характеристика". Мне удалось ппользуясь обычными приборами снизить расход газа 65-75% (по платежам за 2 года) и это как думается еще не предел.
     
    ИгорьК нравится это.
  6. ИгорьК

    ИгорьК Оракул Модератор

    Еще код бы комментировать, здесь спецов по Java очень мало.
     
  7. ИгорьК

    ИгорьК Оракул Модератор

    19.0. DHT11 - собираем прошивку NodeMCU.
    У ESP8266 в прошивке NodeMCU есть возможность, которой я еще не касался (потому что упустил - занимался другими вещами, а ситуация значительно изменилась в лучшую сторону). Мы можем собрать прошивку самостоятельно, исключив из нее ненужные нам возможности, сократив ее при этом и освободив себе больше памяти. Как это делается.
    Переходим по ссылке: http://nodemcu-build.com/
    Заполняем поле адреса своей электронной почты, переходим еще ниже и ставим галочки на необходимых нам блоках, а именно:
    4334.jpg
    Проматываем ниже и жмем кнопку:
    22112211.jpg

    Через некоторое время на электронную почту приходит две ссылки на загрузку пошивки, одна с поддержкой плавающей точки, другая без поддержки. Скачиваем и устанавливаем, причем для DHT11 можно использовать без плавающей, для DHT22 - с плавающей лучше.
     
    Последнее редактирование: 28 янв 2016
    alp69 нравится это.
  8. ИгорьК

    ИгорьК Оракул Модератор

    19.1. DHT11 - собираем прошивку NodeMCU.
    Как загрузить прошивку? По ссылке https://github.com/nodemcu/nodemcu-flasher скачиваем fasher в соответствии с системой.
    Запускаем его, и переходим на вкладку Config, там видим такую картину:
    321321.jpg

    Щелкаем по шестеренке в первой строчке и выбираем файл для загрузки:
    4252.jpg

    Возвращаемся на вкладку Operation и жмякаем на кнопку Flash.
    Появляется квадратик QR кода и зеленая линия сигнализирует нам о ходе заливки.
    Если этого не произошло, то значит вы забыли бросить на землю ногу на модуле.

    Внимание! Если после этого ничего не работает, смотрим сюда!


    Следующий пост.
     
    Последнее редактирование: 19 ноя 2016
    alp69 и netmaster нравится это.
  9. netmaster

    netmaster Гик

    Спецом по java не являюсь, но очень было надо ;)

    Ну комменты если коротко то такие:
    1) Выяснил, что сообщение received update приходит уже после того как openhab попытался внести данные в Итем. Напримет если Итем числовой, а пришла строка - это вызовет обработку исключения, а сообщения не будет. Вот для этого нужен - скрытый элемент.
    2) "^-?\\d+(\\.\\d+$|$)" - шаблон на целое либо дробное десятичное число со знаком.
    3) var Pattern pt = Pattern::compile(sExpr) компиляция шаблона (зачем такой изврат на java, простите не понимаю, еще осталось загадкой вызов через :: а не через . на это было убито ~2 часа спасибо форумам)
    4)var Matcher mt = pt.matcher(str) создается обьект для поиска, ему передается шаблон.
    5)mt.find() запуск метода
    6)mt.matches() - массив значений куда копируются результаты поиска, наш с индексом 0. Если в нем
    ничего нет - значит строка не целое либо дробное десятичное число со знаком.

    p.s.
    Мн-да на perl это одна строчка.
     
    Последнее редактирование: 27 янв 2016
    ИгорьК нравится это.
  10. ИгорьК

    ИгорьК Оракул Модератор

    19.2. DHT11 - собираем прошивку NodeMCU.
    Заливаем тестовый код:
    Код (Lua):
    pin = 4   -- сюда присоединяем датчик
    print "Connecting to MQTT broker. Please wait..."
    m = mqtt.Client( dht_001, 120, dht_001, password) -- объявляем параменты клиента
    m:connect( "www.mysite.org" , 1883, 0, function(conn) -- функция соединения с сервером MQTT на вашем сайте. Или на общедоступном, открытом.
         print("Connected to MQTT")
    end)

    function publish_data() -- публикация данных
         print("Publish Info")
         print("Heap at Start "..node.heap())
         local status,temp,humi,temp_decimial,humi_decimial = dht.read11(pin) -- читаем в локальные переменные значения датчика. Для DHT22 - dht.readxx(pin)
            if (status == dht.OK) then -- Проверка правильности чтения
                m:publish("/myhome/dht_001/temperature/status",temp,0,0, function(conn) -- Пудбликация температуры
                    print("Temp "..temp.." published!")
                    tmr.alarm(3, 20000, 0, function(conn) -- Однократный запуск таймера, чтобы опубликовать влажность
                        m:publish("/myhome/dht_001/humi/status",humi,0,0, function(conn) -- Публикация влажности
                        print("Humi "..humi.." published!")
                    end)
                    end)
                end)
            end
            collectgarbage() -- сбор мусора
            print("Heap "..node.heap())
    end

    function run_main_prog() -- Главная программа запускается по бесконечному таймеру раз в минуту
         print("Main  program")
         tmr.alarm(2, 60000, 1, publish_data )
    end

    repeat -- Если нет wi-fi
        print ("Waiting for wifi...")
    until wifi.sta.status() == 5
    run_main_prog()
     
     
    Последнее редактирование: 24 май 2017
  11. ИгорьК

    ИгорьК Оракул Модератор

    19.3. DHT11 - собираем прошивку NodeMCU.
    Код предыдущего поста, безусловно, рабочий и предназначен для общего понимания ситуации. Однако, он недостаточно хорошо работает в сложных wifi условиях. Что же, зальем цепкий, зубастый код. Он вгрызается в сеть, и жестко держит ее в любых условиях.

    Код (Lua):
    pin = 4
    -- Broker="www.mysite.org"
    Broker="iot.eclipse.org"
    port=1883

    m = mqtt.Client( dht_001, 120, dht_001, passfordht_001)
    m:lwt("/myhome/dht_001/lwt", "dht_001", 0, 0)
    m:on("offline", function(con)
         print ("Mqtt Reconnecting.")
         tmr.stop(2)
         tmr.alarm(1, 120000, 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()
         print("Publish Info")
         print("Heap at Start "..node.heap())
         if wifi.sta.status() == 5 then
             local status,temp,humi,temp_decimial,humi_decimial = dht.read11(pin)
                if (status == dht.OK) then
                    print("Status "..status)
                    m:publish("/myhome/dht_001/temperature/status",temp,0,0, function(conn)
                        print("Temp "..temp.." published!")
                        tmr.alarm(3, 20000, 0, function(conn)
                            m:publish("/myhome/dht_001/humi/status",humi,0,0, function(conn)
                                print("Humi "..humi.." published!")
                            end)
                        end)
                    end)
                end
                collectgarbage()
                print("Heap "..node.heap())
          end
    end

    function run_main_prog()
         print("Main  program")
         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)
    Пример соединения с брокером iot.eclipse.org

    Ashampoo_Snap_2017.05.24_23h08m05s_001.jpg
     
    Последнее редактирование: 25 май 2017
    alp69 и netmaster нравится это.
  12. netmaster

    netmaster Гик

    Ну вот этап с MySQL и провкой данных почти завершен.

    Сохранение состояний и отрисовка графиков через MySQL
    Код (Bash):
    mysql -p // Подключение к mysql
    mysql>create database openhab; //Создадим базу openhab
    mysql>CREATE USER 'openhab'@'localhost' IDENTIFIED BY 'openhab'; //Создадим пользователя openhab
    mysql>GRANT ALL PRIVILEGES ON openhab.* TO 'openhab'@'localhost'; //Дадим пользователю openhab права на базу openhab
    mysql>update user set password=PASSWORD("q1w2e3r4") where User='openhab'; //Поменяем пользователю пароль к базе
     
    Код (Bash):
    Итемы
    Group   StoreStateToDB  "Сохранение данных в БД."
    Number  Temperature001  "Моя тестовая температура [%.1f]"       <temperature> (StoreStateToDB)
     
    Создадим группу и к группе добавим, что собираемся хранить в БД.

    Код (Bash):
    # cat mysql.persist
    Strategies {
        default = everyChange
    }

    Items {
            StoreStateToDB* : strategy = everyChange, restoreOnStartup
    }
     
    Ну тут все просто! Самое главное не забыть (*) после имени группы.
    Код (Bash):
    # cat ../sitemaps/mytest.sitemap
    sitemap mytest label="My first test"
    {
            Frame label="mytest" {
                    Text item=Temperature001
                    Chart item=Temperature001 label="Мой тестовый график" period=h service="mysql" refresh=6000
            }
    }
     
    Усё! График строится, данные хранятся.
     
    Oberon, Vlad_L и ИгорьК нравится это.
  13. VelAndr

    VelAndr Нуб

    2ИгорьК - по коду 19.3 - мои небольшие знания в программировании говорят, что код не очень. Не отрабатывается, например, ситуация, когда вайфай был, но весь вышел.И 1 сек на опрос это жестко... На гиктаймсе была статья про автоматизацию, чего-то там, и там был очень хороший код, инициализацию сети оттуда можно взять практически целиком. Отлично работает...
    2Netmaster - А зачем вам метрики в mysql? Строить аналитику? Для метрик есть специализированные средства - RRD, или если хочется хороших графиков и дашбордов и у вас x86 железка - могу порекомендовать связку influxdb & grafana. Модуль для инфлюкса 0.9 появился в хабе 1.8.
    И по регексу - это ничего, что там вернется в значении только дробная часть с точкой? Я бы строил систему, точно зная, какие типы у меня возвращаются и какого формата, и не заморачивался насчет их преобразования. Все ошибки в преобразовании находятся на этапе тестирования.
     
  14. ИгорьК

    ИгорьК Оракул Модератор

    Просто возьмите и проверьте. Не забудьте отписаться.
    И о какой секунде речь?
    Друзья, я выставляю пусть и непрофессиональный (я не программист ни разу и не продаю свои услуги), но работающий и проверенный код.
    Чуть позже объясню как это работает.
    А Гиктайм... там наряду с крутыми вещами дилетантов тоже хватает.
     
    Последнее редактирование: 27 янв 2016
  15. VelAndr

    VelAndr Нуб

    2ИгорьК - Я про вот этот код -
    Код (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("Mqtt Connected to : " .. Broker)
                 run_main_prog()
             end)
         end
    end)
    В tmr.alarm 1000 - это милисекунды. У меня, например, после сброса проходит около 10 сек, прежде чем зацепится к точке доступа. А теперь представим - мы вошли в блок, получили IP и 5 в wifi.sta.status(), и работаем. Затем сеть заканчивается, и через какое-то время мы вылетаем из блока. Тем или иным способом. И выполнение кода закончится. Код лучше читать, представляя при этом самое худшее, что может случиться :)
    Да, обработка отключения mqtt присутствует, а сети-нет.
    Про гиктаймс - я же не рекомендую весь ресурс - я говорю про одну статью, в которой инит сети сделан лучше(там вроде масляный радиатор на картинке еще был нарисован). И да, я тоже не продаю свои услуги, если Вас это интересует - зачем-то Вы ведь это сказали... Сфера моих рабочих интересов никак не связана с домашней автоматизацией :)
     
  16. netmaster

    netmaster Гик

    Entia non sunt multiplicanda sine necessitate

    MySQL>сетевой коннектор>Excel>аналитика (Надежно, Практично, Быстро)


    Опппшибочка, в описании. Я уже поправил, вернётся - целое либо дробное десятичное число со знаком.
     
  17. ИгорьК

    ИгорьК Оракул Модератор

    Теперь есть предмет для разговора. Этот кусок кода уже в стольких устройствах работает, что и забыл про него.
    Не нравится секунда - поставьте двадцать.
    Давайте посмотрим на ситуацию шире: вот, прошили вы модуль, залили код, что я привел, включили, он что - заработает? Про wifi в нем что-то видели? Или он вообще сам запустится на исполнение?
    Значит это часть правды.
    Теперь об этом куске. Он повторяется лишь однажды, когда модуль включается. Больше он не повторяется никогда. Да, этот кусок ждет при старте запуска wi-fi, проверяя его каждую секунду (можно любое другое время, если процессор жалко - суть не меняется), но после того, как сеть подключилась, выполняется функция tmr.stop(0), соединение с брокером и подписка и больше этот кусок не исполняется никогда. Даже если теряется Интернет.
    Почему так сделано... Наверно надо действительно написать подробную заметку о логике работы.
    Что касается Вашего замечания - вы не учли, что этот код выполняет несколько иную задачу, нежели Вы решили, то есть не увидели смысл tmr.stop(0).
     
    Последнее редактирование: 27 янв 2016
  18. Securbond

    Securbond Гуру

    Давно ждал такой статьи . Игорь как всегда радует кропотливостью и внятным разжевыванием всего и вся. Все железо имеется, Осталось переварить осмыслить и реализовать ! Огромное спасибо за труд и терпение ... :)
     
  19. ИгорьК

    ИгорьК Оракул Модератор

    19.4. DHT11 - собираем прошивку NodeMCU. Общие замечания и информация для начинающих.
    Итак, эта информация будет полезна для начинающих. Повторим некоторые азы.
    1. Чтобы работать с ESP8266, будьте добры купить адаптер. Можно модуль прошивать через Ардуино, но я не знаю как это делается. Я рассуждаю так - это мое хобби, это не последний модуль, который я программирую, и мне должно быть ХОРОШО.
    Самый подходящий - PL2303:
    [​IMG]
    2. При заливке прошивки NodeMCU нога 2 модуля должна быть на земле (оранжевая линия). При программировании и при соединениях, ноги, наоборот, не должны быть "положены" на землю.
    Все соединяется так:
    [​IMG]
    Но у вас может быть другая версия PL2303. Не забудьте выставить питание 3.3 вольта. Смотрите на наименования ног. Ноги соединяются наоборот: Rx c Tx попарно. Там всего по четыре ноги для соединения, сложно запутаться, но бывает.
    При удачном соединении на включении на модуле помигивает синий диодик.

    3. Залили прошивку (как указано в посте 19.1) - заводим модуль в сеть.
    На модуле установлен интерпретатор языка Lua, что, в первую очередь для программистов С(С++) Крутых Ардуинщиков значит, что он поддерживает СОПРОГРАММЫ. Это:
    Источник. Страница 110.
    В частности, это значит, следующее: (речь идет о прошивке NodeMCU, не забываем!!!)
    • будучи заведенным в сеть однократно, модуль, при включении или потере сети, постоянно и сам(!) пытается к ней подсоединиться, и ничего для этого программно НЕ НАДО ДЕЛАТЬ, кроме особых случаев. В определенных случаях, в частности при работе по протоколу MQTT требуется лишь приостановить выполнение программы до тех пор, пока сеть не появится, и возобновить как только она будет подхвачена;
    • существует ряд (много) функций, работающих асинхронно. Это не привычно для специалистов по языку Ардуино (не ошибка, есть такой язык). В частности, в нашем линейном (ардуинном) мышлении мы привыкли, что код исполняется последовательно от команды к команде, в той последовательности, как мы его написали. Однако в Lua дело обстоит часто по-другому. В составе многих функций присутствует нечто, называемое callback-функция. Именно она и автоматически вызывается, после успешного или неуспешного выполнения основной функции.
    Например:
    Код (Lua):
    mqtt:connect(host[, port[, secure[, autoreconnect]]][, function(client)])
    Здесь function(client) - сработает только после успешного соединения с сервером.
    Что это значит? Вот что:
    Код (Lua):

    m:connect("192.168.11.118", 1880, 0, function(client) print("Connected 01") end)
    print ("Сonnected 02")
    Здесь две последовательные функции, каждая из которых выводит на печать "Соnnected" с цифрой.
    Логика ардуино говорит, что сначала будет напечатано Сonnected 01 а затем Сonnected 02. На самом деле, скорее всего, будет напечатано Сonnected 02 и лишь затем Сonnected 01. Почему? Потому что функция m:connect начинает свою асинхронную, самостоятельную работу по соединению с сервером и для этого требуется время. Однако, код не останавливается, и, приступив к соединению, функция m:connect передает исполнение кода дальше, самостоятельно выполняя свою задачу. И лишь когда эта задача будет выполнена, на печать выведется "Сonnected 01".

    4. Для заведения модуля в сеть и для программирования его, лучше всего подходит ESPlorer. К сожалению, автор что-то подзабросил его разработку, но инструмент отличный. Скачиваем, запускаем. Инструкций по работе с этой программой хватает.
    Что мы сделаем в первую очередь? Заведем модуль в сеть.
    Вариант первый.
    Набираем в окне Scripts => New
    Код (Lua):
    do
    wifi.setmode(wifi.STATION)
    wifi.sta.config("myssid","mypassword")
    wifi.sta.autoconnect(1)
    end
    И действуем как на картинке:
    [​IMG]

    Вариант второй.
    Мы создадим снипет, который заводит наш модуль в сеть - он пригодится нам еще сто раз. А именно:
    3311.jpg
    Как только мы сохраним этот снипет - в правой части ESPlorera появится кнопочка, нажатие на которую приводит к загрузке этого кода в модуль. Этот код остается в модуле до тех пор, пока не будет прямо заменен. Из текста понятно, что мы (1) устанавливаем режим клиента, (2) указываем сеть и пароль и (3) требуем от модуля автоматически восстанавливать соединение с сетью. Вот об этом третьем пункте то и не знают те, кто не читает мануалы/API, а учится по форумам.
    Через некоторое время даем команду
    =wifi.sta.getip()
    и в правой части окна ESPlorera видим приблизительно такую картинку:

    1234123.jpg
    Теперь, при каждом включении модуль будет без всяких указаний цепляться к сети и эту тему можно просто забыть.

    5. Мы пишем разные скрипты с разной степенью успеха, запускаем их на выполнение. Но только файл с названием init.lua автоматически запускается на исполнение при старте (включении, перезагрузке) модуля.
    Иногда исполнение скрипта можно остановить при его работе, иногда - нет, как например в случае, если модуль общается с Ардуино по UART.
    С целью избежать такой ситуации, я (по научению более опытных товарищей) использую минимум два файла: типовой init.lua и собственно исполняемый скрипт с любым другим названием. init.lua всегда такой:
    Код (C++):
    do
    FileToExecute="ArduinoUART06.lc"
    l = file.list()
    for k,v in pairs(l) do
      if k == FileToExecute then
        tmr.delay(30000)
        print("*** You have got 30 sec to stop timer 0 ***")
        print("*******    Execute: tmr.stop(5)     *******")
        tmr.alarm(0, 30000, 0, function()
          print("Executing ".. FileToExecute)
          dofile(FileToExecute)
        end)
      end
    end
    end
     
    Код запускается и тормозится на 30 секунд. ArduinoUART06.lc - это имя другого файла, который будет запущен через 30 секунд, если мы не выполним команду tmr.stop(0)
    О таком своем состоянии скрипт пишет в порт.
    tmr.stop(0)
    можно набрать вручную, а можно найти на вкладке "Commands" ESPlorera. Кроме того, можно и снипет сделать.
    Еще хорошей особенностью этого кода есть то, что при отсутствии файла с искомым именем он просто завершает работу ничего не говоря, тихонечко.

    Следующая заметка.
     
    Последнее редактирование: 25 мар 2016
  20. ИгорьК

    ИгорьК Оракул Модератор

    Код на устройстве проверили, критик?

    Вот он, работает, как ни странно:
    [​IMG]

    Совет правильный, но бесполезный в случае с Lua на ESP-8266.

    Именно чтение того что пишут другие заставляет меня искать свои решения: разбираться с творениями Си-программеров на синтаксисе Lua тоскливо и контр продуктивно. Я читаю книжки а не бредятину.
    Пусть опыта программирования у меня нет, но устройства мои работают.
     
    Последнее редактирование: 26 май 2017