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

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

  1. NE_XT

    NE_XT Гик

    Ну вот ТС обиделся, а что вы думали начиная свои публикации, вам дырку на жопе залижут от благодарности за:
    Я действительно в этой теме не стараюсь никого ничему учить, а, в основном, даю ссылки на чужие посты, придерживаясь определенной последовательности и лишь давая некоторые комментарии. В этой теме я вообще сознательно отсекаю определенный круг читателей. Умный - найдет путь, дурак и халявщик - займется критикой, начинающий - обойдет стороной.
    ИгорьК - вы не дебил, как сами предполжили, у вас просто больное самолюбие, не ярко выраженное - но устойчивой формы.
    Да и когда человек говорит о ком-то, то прежде всего он говорит о себе, ну это из психологии.
    И моя фраза: "ибо только автор может понимать ход своих мыслей" не должна обижать психически нормальный людей, так как её нужно воспринимать так как есть, а не додумывать.
    А вот подпись у вас - дебильная
    ;)

    Опять обидетесь?
     
    pilnikov нравится это.
  2. Sevic71

    Sevic71 Нерд

    Приветствую участников форума!
    В свободное время понемногу играюсь с openhub на малинке, на данный момент собрал комплект openhab-mqtt-RF433 для работы с беспроводными датчиками и исполнителями, работающими на частоте 433 МГц. В частности, удалось "завести" управление розетками и чтение температуры с беспроводного датчика, кот. идет в комплекте Assistant AH-1972 ( например, http://meteostantsiya.com.ua/meteostantsii/assistant-ah-1972-detail ) . В общем-то все работает как хотелось, но есть одна недоделка - датчик погодной станции выдает температуру и влажность в одном сообщении, соответственно я конвертирую его в одно сообщение MQTT, в котором температура и влажность разделены просто пробелом. В таком варианте не удается прописать рабочий биндинг на itemы openhab, чтобы два items типа Number, один из которых Temperature, а второй Humidity апдейтились из одного mqtt сообщения. Т.е. если я помещаю в тело сообщения одно из значений (либо температуру, либо влажность) и прописываю соотв. биндинг типа status на соответствующий айтем (либо temperature либо humidity) все работает. Это я к тому, что протокольная часть настроена и отрабатывает, равно как и "одиночные" биндинги. Но, хочется все-таки реализовать схему, когда одно сообщение MQTT c двумя значениями в "теле" будет апдейтить два айтема. Никто не сталкивался с такой необходимостью? В принципе, я могу по приему пакета метеодатчика из эфира выбросить на mqtt два сообщения в два разных топика, но интересно же решить задачку сос стороны openhab. Подозреваю что кастомные фильтры (или парсеры в терминах openhab) могут помочь, но так глубоко в openhab еще не зарылся. В общем, буду рад любым идеям.
    Ну и второй вопрос по прошивкам для ESP8266 генерируемым из http://nodemcu-build.com/index.php . Как у них с переполнением памяти? Понятно, что все зависит от скрипта, который будет крутиться на ESP, но все же, в сравнении со стандартными прошивками NodeMCU ? Я предполагаю, что исключение "ненужных" пакетов должно положительно сказаться на использовании heap, но с другой стороны, если я и так не загружаю в heap ненужные мне модули, то какая разница? Год назад игрался с NodeMCU, даже поставил один модуль в отопительный котел в качестве термостата и даже работает. Но вот проблемы с постоянным out of memory в свое время отбили напрочь охоту заниматься этой веткой. Помнится, после загрузки ESP 32 kB свободно, но стоит один раз считать DS18B20 и отправить данные на сервер, и все, память кончилась... Выбрался из ситуации поочередным выполнением процедур с принудительной выгрузкой каждой процедуры после ее завершения, и даже работает. Но это бесило... Как там сейчас, все тоже?
     
    Последнее редактирование: 8 фев 2016
  3. ИгорьК

    ИгорьК Гуру

    Это ко всем относится или только ко мне?
    А как надо? Я не в теме. Я в ПТУ не учился.
    Вы все еще настаиваете? :) Постоветуйтесь с NE_XT. У него про ОпенХаб немного, но жизнь он знает хорошо :)
     
  4. ИгорьК

    ИгорьК Гуру

    Дык... Делаете итем, а потом пишете скрипт, с началом "when item updated...", после чего начинаете парсить данные и отправлять на два других итема. Не думаю что кто-то сталкивался, но если Вам интересно - ваш вызов :)

    ИМХО, прошивка стала работать стабильнее. И именно сборка на сервере теперь является стандартной, а не та, что зашита в загрузчик. Об этом прямо и говорится в документации.

    Heap - не используется (по крайней мере в Lua, здесь нет команд на выделение памяти и возврате ее обратно в кучу), ее размер - показатель эффективности работы программы. Кстати, если heap меньше некоторого размера, можно программно ресетить модуль, чем я иногда раньше занимался. Но теперь вроде и не нужно.

    Это не проблема модуля - это правило (способ жизни) Lua. Загрузил модуль, отработал, выгрузил. Выполнил collectgarbage(). Это несколько похоже на суть работы в C(СРР) malloc() free() и т.п. Но не все до этого доходят, а ардуинщики - подавно. Так что это нормально.
     
    Последнее редактирование: 8 фев 2016
    netmaster нравится это.
  5. alp69

    alp69 Форумчанин

    Сдался...:D
     
  6. netmaster

    netmaster Гик

    Собственно такую схему и хочу организовать, только приезжать будет сразу много данных.
    Паровоз типа так SensorID_1;Type;Value; ... SensorID_n;Type;Value (Туре = Status,Command)
    А вот топиков с mosqutto только два RX и TX сама ESP только MQTT UART соединитель.

    Код (Java):
    -- variables
    MQTTCLIENTID = "Boil"
    MQTTSRV = "10.0.20.20"
    MQTTPORT = 8266
    MQTTUSER = "test"
    MQTTPASS = "pass"
    KEEPALIVE = 180
    -- object/floor/room/controller/way
    SUBTOPIC = "/Home/0/Boil/"..MQTTCLIENTID.."/RX"
    PUBTOPIC = "/Home/0/Boil/"..MQTTCLIENTID.."/TX"
    LWT = "/LWT"
    TERMINATOR = "\n"
    DEBUG = true

    m = mqtt.Client(MQTTCLIENTID, KEEPALIVE, MQTTUSER, MQTTPASS) --Объявление MQTT клиента
    m:lwt(LWT,MQTTCLIENTID.." offline", 0, 0) --Сообщение OpenHab о обрыве связи
    m:on("offline", function(client)
    local run, mode = tmr.state(1)
    if DEBUG == true then print("on offline") end
    if run == false then --При первом запуске пропустим сообщение т.к таймер уже запущен
      print("Offline") -- Сообщение Arduino о статусе связи
      tmr.alarm(1, 6000, 1, mqtt_connect)
    end
    run, mode = nil, nil
    collectgarbage()
    end)

    uart.on("data",TERMINATOR, function(data)--Функция обработки информаци из UART
    if data=="quit\r\n" then
      uart.on("data") -- Отключим функцию обработчик данных UART
      if DEBUG == true then print("UART Callback detach") end
    else
      m:publish(PUBTOPIC,data,2,0, function(client) -- Публикуем на брокер
       print("SendOK") -- Сообщение Arduino об успешном опубликовании
      end)
    end
    end, 0)

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

    tmr.alarm(1, 6000, 1, function() --Попробуем подключится к MQTT
    mqtt_connect()
    end)

    function mqtt_connect()
    if DEBUG == true then print ("Call MQTT connection") end
    m:connect(MQTTSRV,MQTTPORT,0,function(client)
      if DEBUG == true then print("MQTT connect") end
      tmr.stop(1) -- Соединились с MQTT успешно
      m:subscribe(SUBTOPIC, 2, function(client) -- Попробуем подписаться к топикам
       if DEBUG == true then print("Subscribe success") end
       m:publish(LWT,MQTTCLIENTID.." online",2,0, function(client)  --Сообщение OpenHab об установке связи
        print("Online") -- Сообщение Arduino о статусе связи  
       end)
      end)
    end)
    end

    Отлажено, проверок сделано много разных. Если есть конструктивная критика, всегда пожалуйста.
     
    ИгорьК нравится это.
  7. ИгорьК

    ИгорьК Гуру

    Делали проверку на длительное отключение Интернета? Если Интернета нет, а данные из UART модуль пытается отправить на OpenHab, в конце концов он зависает. Может я не внимательно смотрю, но в функции m: on("offline", function(client) не вижу запрета на попытку отправить данные, и не вижу фунции m: on("online", function(client) с разрешением на такую отправку.
    ИМХО, возможно я чего-то недопонял.
     
    netmaster нравится это.
  8. ИгорьК

    ИгорьК Гуру

    Я где-то тут предлагал вариант общения, когда модуль принимает от ардуино пару X:Y и отправляет в виде разных топиков X со значением Y. Вроде вполне сносно работает. Или надо именно все свалить в кучу а потом парсить на стороне OpenHab? В чем смысл?
     
  9. netmaster

    netmaster Гик

    Спасибо за критику.
    Передаст контролеру Offline, и до тех пор пока он не получит Online - ничего отправлять не будет.
    Если данные переданы в OpenHab то контролер получит SendOK.

    У меня топиков только на отсылку 7 штук. Проще все сложить в 1 пакет и отправить, тем более что парсин-то простой типа split по ; И если захочется еще топик добавить, то луа код править не надо, т.е. модуль работает как некоторый инителектуальный провод не более того. Все решения по пересылке данных будет принимать контролер, смысла делать логику на моей esp8266 v1 я не вижу смысла.
     
    Последнее редактирование: 8 фев 2016
    ИгорьК нравится это.
  10. netmaster

    netmaster Гик

    Упс... А алмаз то, я прошляпил! Обязательно проверю эту тему. Как я писал раньше... теория это конечно хорошо, но без практики...

    Еще один, для тех кто конечно не слеп.
     
  11. ИгорьК

    ИгорьК Гуру

    У меня 2/3 исполнительных и информационных устройств на даче, малина с OpenHab - в городе. Интернет, бывает, пропадает часов на 10. Это не страшно - все работает и самостоятельно, но вот как раз устройство такого рода, транслирующее данные из спячки не выходило.
    Тестировал: включал/выключал Интернет - вроде работает. Долго думал в чем дело...В логике отдельного ESP8266 - вроде все правильно. А забываешь, что модуль не сам данные шлет, а их туда заталкивают...
     
  12. netmaster

    netmaster Гик

    Тему проверил делать имеено так - отрабатываем PUBACK сообщение

    Код (Java):
    uart.on("data",TERMINATOR, function(data)--Функция обработки информаци из UART
    if data=="quit\r\n" then
      uart.on("data") -- Отключим функцию обработчик данных UART
      if DEBUG == true then print("UART Callback detach") end
    else
      tmr.alarm(2, 2000, 1, publish_error)
      m:publish(PUBTOPIC,data,2,0, function(client) -- Публикуем на брокер
       tmr.stop(2)
       print("SendOK") -- Сообщение Arduino об успешном опубликовании
      end)
    end
    end, 0)

    function publish_error()
    tmr.stop(2)
    print("SendErr") -- Сообщение Arduino об неуспешном опубликовании
    end
     
     
    ИгорьК нравится это.
  13. ИгорьК

    ИгорьК Гуру

    Что это дает? Ок, ошибка в отправке. Причин может быть несколько. В том числе и на стороне OpenHab. Какой системный вывод мы сделаем из сообщения об ошибке при отправке?
     
  14. netmaster

    netmaster Гик

    Это значит, что москит данных не получил, связь в Offline

    Хотите сделать квитирование, да это можно - но это задача не esp8266 это уже реализация на контролере и OpenHab.

    См. выше - далее уже контролер решает, что ему делать дальше.

    Вообще-то OpenHab может и не быть вовсе.
     
  15. Sevic71

    Sevic71 Нерд

    Извините что вмешиваюсь, но вот интересно вызов
    "m:publish(PUBTOPIC,data,2,0, function(client) -- Публикуем на брокер"
    работает синхронно? Если так, то наверное метод publish возвращает какой-то результат который можно проанализировать и решить что делать дальше. Если это асинхронный метод, то конечно так просто не получится, поскольку результат появится позже. Но даже асинхронные методы возвращают результат, но обычно вызывая асинхронную функцию - обработчик, которая устанавливается при вызове. Но тут явно никакие обработчики результата не назначаются. пойду почитаю доку на publish, скоро надо будет использовать, но без анализа результата как то неправильно получается. Все же операция сильно неоднозначная..
     
  16. ИгорьК

    ИгорьК Гуру

    ИМХО, результат этой операции никакого значения не имеет. Если она неуспешна - что Вы будете делать?
    Имеет значение информация от m: on("offline", function(client) . Вот после получения информации об разъединении, следует останавливать попытки что-то передать. А если сама передача не была успешной... ну, еще раз надо пробовать.
     
  17. Sevic71

    Sevic71 Нерд

    "Вот после получения информации об разъединении, следует останавливать попытки что-то передать." - ну я где-то тоже самое и подразумевал. просто если publish синхронный и внем нет встроенного таймаута, то на нем при отсутствии связи с брокером программа остановится "навсегда". Судя по всему "m: on("offline", function(client)" срабатывает в асинхронном контексте и дает шанс разрулить такую ситуацию. Я просто не использовал mqtt в Lua, но предполагаю из опыта по другим библиотекам что она все-таки асинхронная
     
  18. netmaster

    netmaster Гик

    Рассматривайте весь кусочек кода, что я запостил выше.
    Интересен именно обрабочик т.е.function(client) - возвращаемые значения от m:publish полный бред когда связи уже нет, а таймаут не истек т.е. еще не было вызова m:eek:n("offline"

    Уф... я тут оптестировался, целый стенд собрал ;)
     
    Последнее редактирование: 9 фев 2016
  19. ИгорьК

    ИгорьК Гуру

    Именно так.
     
  20. Sevic71

    Sevic71 Нерд

    "ИМХО, результат этой операции никакого значения не имеет" с этим спорить "в общем случае" не стану, хотя все зависит от проектируемой концепции обмена данными. Если требуется гарантированная доставка всех данных, тогда результат важен. Я, например, любой сетевой обмен реализую через буфер типа FIFO и удаляю данные из него только после успешной передачи, иначе повтор N раз и если не получилось принимаю меры в зависимости от возмоджностей протокола (ожидание-реконнект-рестарт программы).

    "возвращаемые значения от m:publish полный бред" - в смысле она возвращает бредовый результат? Тогда ой.