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

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

  1. dimm71

    dimm71 Нерд

    Понял. Уже переделал и всё заработало. Спасибо.
     
  2. SergeiL

    SergeiL Оракул Модератор

    Ну, это вопрос конечно философский.

    Например, зимой собираюсь на дачу. Езжу не часто. Для того, чтобы приехать в прогретый дом, нужно заранее включить отопление. То есть, переключить систему поддержания температуры для определенных помещений с 5 градусов ( там где есть трубы с водой) на, к примеру 22 градуса. В других помещениях можно просто включить систему поддержания определенной температуры. Еду один, верх греть не нужно.

    Далее процесс поддержания заданной температуры конечно автоматизирован.

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

    Не проще ли просто, заранее, к примеру утром на работе, сесть и задать новые температуры для нужных помещений.

    С остальным согласен. Этой зимой планирую модернизировать существующую систему на даче. Уже прикупил Leonardo ETH и протестировал на нем Ethernet c mqtt. Не сразу, но все заработало (там чип W5500). Хочу завести на данный модуль контроль напряжения на двух 12В АКБ, ток разряда, доп. датчики и т. д. В будущем, автоматизировать процесс отключения части оборудования для предотвращения глубокого разряда. Сюда же планирую подключить и предложенный Вами вариант перезагрузки LTE роутера по 12В (все оборудование питается от двух АКБ 12В на плавающем заряде).

    За эти два дня появилась идея, как можно попытаться зарезервировать интернет канал, без СМС.
    Как вариант, подготовить второй, роутер с СИМ картой другого оператора и настройками локальной сети, точно такими же как у основного LTE роутера.

    Если выясняется, что тестируемый в интернете сайт не отвечает, после нескольких рестартов (по Вашей схеме), питание с основного роутера автоматически отключается, а на резервном роутере включается.

    Далее через некоторое время можно попытаться вернуть все обратно…

    В этой ситуации, конечно теряется внешний IP адрес, но по mqtt связь будет, почта уйдет, и Push пройдет. Соответственно и управление оборудованием будет доступно.

    К сожалению, у нас в регионе только один оператор мобильной связи предоставляет внешние IPадреса, да и то несколько криво. Предоставляемый внешний IP адрес доступен только с другого оператора. С других мобильных устройств этого же оператора внешние IP адреса не доступны :-(.
     
  3. Root Of Life

    Root Of Life Нерд

    Появился интересный вопрос, ответ на который гугл и яндекс мне так и не подсказали.

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

    В одном случае опенхаб на винде, в другом на малине.
     
  4. ИгорьК

    ИгорьК Гуру

    1. Парсить файл можно тем способом, который поддерживает то, что парсит. В Си и Shell, полагаю, это по-разному.
    2. Чтение файла из опенхаб ничем не отличается от чтения файла из неопенхаб.
    (Вопрос не засчитан :) )
     
  5. alp69

    alp69 Форумчанин

    Мне кажется, что я даже знаю какой...;)
    ...если они зарегистрированы в одном регионе... Так?
     
  6. SergeiL

    SergeiL Оракул Модератор

    Ну да, только на Северо-Западе такая ерунда. Город на Неве, С 1998г. на бывшем "NWGSM".
    Абсолютно верно, как объясняют знакомые технари, им не сделать биллинг при подключении к внешним IP, из своей же сети. Поэтому и закрыли.
    Тех.Дир. Меги, лично обещал решить проблему еще лет пять назад, но... воз и ныне там.
    Поэтому ношу, на всякий случай, в сумке старый iPhone4 жены с симкой от МТС, для возможности в реал-тайме подключиться к регистратору.
     
  7. alp69

    alp69 Форумчанин

    Симку в модем. Модем в роутер, поддерживающий ddns.net (не dyndns). Тогда и статическая симка не понадобится.;)
    Или измените топологию своей системы. Если дома есть проводной инет - разместите сервер mqtt дома. И все. Дома то проще статический ip организовать, чем на даче.
     
    Последнее редактирование: 25 ноя 2016
  8. SergeiL

    SergeiL Оракул Модератор

    Посмотрел ddns.net, мне показалось, что это аналог dyndns, может ошибаюсь. Так работает, только если динамические адреса являются внешними. Для адресов из серой подсети (а у мобильщиков так всегда) такой вариант не проходит, они за NAT-ом. В таком варианте можно поднять VPN, между домом, с белым IP, и дачным роутером, с серым IP, и заходить в дачную локальную сеть через подключение домой. Пока есть внешний IP не парюсь.

    Так и сделано.
    Внешний статический IP на даче был сделан для подключения к регистратору. Не хочу зависеть от китайских облачные сервисов.
     
  9. alp69

    alp69 Форумчанин

    Ddns и dyndns практически одну и ту же услугу предоставляют. Только у ddns еще осталось чуть-чуть бесплатного. Однако мегафоновские роутеры (сколько с ними сталкивался) поддерживают в основном dyndns. По этой причине завел себе симку с выделенным ip.
     
  10. dimm71

    dimm71 Нерд

    Я давно отказался от dyndns. Все это можно сделать самому с помощью Яндекса, своего домена и скрипта запущенного на роутере с Linux. Все это будет работать как со статическим так и динамическим Real-IP. Если модем подключен к малине, то скрипт можно запустить и на малине
     
    Последнее редактирование: 26 ноя 2016
  11. Securbond

    Securbond Гуру

    А если бы Вы еще на этом форуме подробную инструкцию написали, с примером скрипта, думаю многие были бы Вам благодарны.
     
    alp69 нравится это.
  12. dimm71

    dimm71 Нерд

    Очень много писать. Давно все придумано за меня. Вот, первое, что нашел в Яндексе. http://www.lissyara.su/?id=2242


    если что не понятно - подскажу.

    P.S. Базовое понимание работы в Linux обязательно.
    Так же обратите внимание, что скрипт по ссылке заточен под FreeBSD. В Linux`е нужно немного подправить.

    Вот мой (под Linux) скрипт и он стоит на роутере. Он ещё и отправляет уведомление на почту, если IP-адрес изменился и информирует, на всякий случай, каким он стал. Подставляйте свои значения. Будте предельно внимательны.
    Код (C++):
    #!/bin/sh

    PATH=/opt/sbin:/opt/bin:/opt/usr/sbin:/opt/usr/bin:/opt/usr/local/sbin:/opt/usr/local/bin:/sbin:/bin:/usr/bin:/usr/bin:/usr/local/sbin:/usr/local/bin; export PATH
    NET=vlan2 # указать свой интерфейс
    TIME=300 # время периодичности проверки в сек.
    LOG=/opt/var/log/ip.log
    DNS=dns1.yandex.ru

    # Отправка почты с Yandex.ru
    login=*******            # Сюда пишем Логин от яндекс-почты до @
    pass=*******            # Сюда пароль
    sendto=*******    # Адрес почты куда будут приходить отчеты о смене IP-адреса
    sendfrom=$login@yandex.ru    # Здесь ничего НЕ меняем

    # moy_domen.TK [B]подставить свои значения[/B]
    DOMEN="moy_domen.tk"
    DOMEN_TOK=f19ec5e75294393448a666757650667c71d9c09f8a63f67ea1531dea
    DOMEN_ID=27751058
    WWW_ID=27581060

    while :
       do
    # поиск ай-пи с помощью сайта-информатора
    #MYIP=`curl -s http://ip.anikin.pw/ 2>>$LOG`
    # поиск ай-пи с помощью логов от маршрутизатора
    #MYIP=`tail -40 /var/log/router.log | grep IP= | awk '{print $11}' | sed -e 's/IP=//' | sed -e 's/,//' | tail -1 2>>$LOG`
    # поиск ай-пи с помощью ifconfig
    #nvram get wan0_ipaddr >> /opt/var/log/ip.log
    #MYIP=`ifconfig $NET |grep "inet addr:" |sed 's/addr://g'| awk '{print $2}'`
    MYIP=`nvram get wan0_ipaddr`
    # ай-пи в днс яндекса
    NSIP=`host $DOMEN $DNS | grep has | awk '{print $4}'`
    IPSAVE=`tail -1 $LOG | awk '{print $1}' | egrep -v -E "^#|^$"`

    # Текст письма с данными
    TEXT="Смена IP-адреса на роутере \n\n На Вашем роутере сменился IP-адрес $(date +%F) в $(date +%R).\n Ваш текущий IP-адрес - $MYIP \n Прежний - $IPSAVE"

    if [ $MYIP != $NSIP ]
          then
    # команда замены ай-пи в ДНС яндекса для moy_domen.tk
    curl -ks "https://pddimp.yandex.ru/nsapi/edit_a_record.xml?token=$DOMEN_TOK&domain=$DOMEN&record_id=$DOMEN_ID&content=$MYIP"
    curl -ks "https://pddimp.yandex.ru/nsapi/edit_a_record.xml?token=$DOMEN_TOK&domain=$DOMEN&subdomain=www&record_id=$WWW_ID&content=$MYIP"
          else
          echo ok
    fi

    # Записываем в лог IP-адрес, если поменялся. И отправляем почту.
    if [ $MYIP != $IPSAVE ]
          then
          echo "$MYIP    $(date +%F)    $(date +%R)" >> $LOG
          echo -e "Subject: $TEXT" | /opt/bin/msmtp --host="smtp.yandex.ru" --port=465 --protocol=smtp --domain="yandex.ru" --tls=on --tls-certcheck=off --tls-starttls=off --auth=plain --user="$login" --passwordeval="echo '$pass'" --from="$sendfrom" --maildomain="yandex.ru" $sendto
          else
          echo ok
    fi
          sleep $TIME
    done
    Ну, и если установлен WEB сервер, то можно через него в удобочитаемом виде смотреть лог IP
    index_ip.php
    Код (C++):
    <p><h2>Список IP-адресов</h2></p>

    <?php

    $file_name = file('/opt/var/log/ip.log');

    echo '<table valign="middle" bordercolor="#BEBEBE" cellspacing="0" cellpadding="3" width="400" border="1">
        <tr>
    <th style="color:red">№</th>
    <th style="color:red">IP-адрес</th>
    <th style="color:red">Дата</th>
    <th style="color:red">Время</th>
        </tr>'
    ;

    for($i=0;$i<sizeof($file_name);$i++){$sub = explode('<->', $file_name[$i]);

    echo '<tr>
    <td align="center">'
    . ($i+1)  .'</td>
    <td align="center">'
    . $sub[0] .'</td>
    <td align="center">'
    . $sub[1] .'</td>
    <td align="center">'
    . $sub[2] .'</td>
        </tr>'
    ;
    }
    echo '</table>';
    ?>
     
     
    Последнее редактирование: 11 дек 2016
    Securbond и alp69 нравится это.
  13. dimm71

    dimm71 Нерд

    Ну вот, просили скрипт и тишина... :)
     
  14. alp69

    alp69 Форумчанин

    Решение неплохое, но не подходит для тех, кто (или):
    1. Не имеет прошитого роутера (openwrt?).
    2. Не имеет аккаунта на Яндексе.
    3. Не имеет достаточного опыта в freebsd и linux.
    Но определенная степень упертости и желания позволят решить проблему динамического ip.:)
     
  15. dimm71

    dimm71 Нерд

    На самом деле не обязательно вешать на роутер. Можно на любое устройство с Linux в домашней сети. Пусть та же малина - нужно только немного скрипт подправить. Просто роутер напрямую "смотрит" в Интернет и всегда включен.
    Нет аккаунта на Яндексе?! - регистрация бесплатная и быстрая :)
    Вот немного в Linux (хоть чуть-чуть) нужно понимать, а так в статье всё очень доступно написано.
    Да, вечер на настройку я потратил, чтоб заработал скрипт. Потом всякие улучшательства докручивал.
    Да, и ещё... там хоть и предлагают домен в зоне .tk взять бесплатно, но меня не впечатлило. Через пол года перестал работать. Без предупреждения аккаунт закрыли. Лучше взять в зоне .ru. Сейчас на jino.ru их продают за 39 руб. за первый год.
     
    Последнее редактирование: 28 ноя 2016
    alp69 нравится это.
  16. ИгорьК

    ИгорьК Гуру

    alp69 нравится это.
  17. Жозен

    Жозен Нуб

    вот обьясните, вы всегда так на новеньких реагируете? что плохого что мне захотелось поделиться ссылкой с полезной информацией? причем тут спам??
     
  18. Жозен

    Жозен Нуб

    ну какого еще спамера...честно, я не понимаю такого отношения. здесь все кидают ссылки на хорошие ресурсы и не вижу ничего плохого в том чтобы поделиться своим
     
  19. alp69

    alp69 Форумчанин

    А чего, объясните, хорошего (полезного) в Вашей ссылке может почерпнуть сообщество, самодельщиков? Или Вы просто среагировали на выдернутое из названия "умный дом"? Прочитайте название темы полностью.
    Вашей ссылке место в разделе "сделаю проект". Да и там врядли народ оценит.
    Как то так.
     
    Последнее редактирование: 29 ноя 2016
  20. ИгорьК

    ИгорьК Гуру

    43.Читаем счетчики расхода воды. Beta.
    Начнем, однако. Со схемы. Она невероятно сложна:
    Water2.jpg
    И код (Beta!!! Работает устойчиво, но возможно изменение логики):
    Код (Lua):
    --[[
    cfg = {
      ip = "192.168.0.111",
      netmask = "255.255.255.0",
      gateway = "192.168.0.1"
    }
    --]]

    water = {
        bat = 3,
        hot = 0,
        cool = 0
    }

    Broker="broker.mqtt-dashboard.com"
    port=1883
    myClient="water017w31"
    pass="pass"
    publish = true

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

    function connecting(call)
        print('Connecting')
        wifi.setmode(wifi.STATION)
        wifi.sta.config("mypoint", "mypassword", 0)
        -- wifi.sta.setip(cfg)
        wifi.sta.connect()

        function getWiFi()
            tmr.alarm(5, 500, 1, function()
                if wifi.sta.status() == 5 and wifi.sta.getip() ~= nil then
                    getConnect(call)
                    tmr.unregister(5)
                    tmr.start(6)
                end
            end)
        end

        function getConnect(call)
            print("Got WiFi!")
            m:connect(Broker, port, 0, 0,
                function(conn)
                    tmr.stop(6)
                    print("Connected")
                    if call then
                        call()
                    else
                        m:subscribe(myClient.."/#",0, function(conn)
                            print("Subscribed")
                        end)
                    end
            end)
        end
        getWiFi()
      --  tmr.register(6, 90000, 1, function()
      --      getConnect()
      --  end)
    end


    function publ(datt)
        water.bat = adc.readvdd33()/1000
        print ("Bat : "..water.bat )
        local topic = myClient.."/data"
        local dt = cjson.encode(water)
        print (topic.." : "..dt )
        if(datt) then
            topic = myClient.."/report"
            dt = datt
        end

        m:publish(topic, dt,1,1,function(conn)
            print("Published!")
            closeWiFi()
            publish = true
            --collectgarbage()
        end)
    end

    m:on("message", function(conn, topic, data)
        if (string.find(topic, "state")) == nil then
            local top = string.gsub(topic, myClient.."/","")
            if top == "cool" then water.cool =  tonumber(data)  end
            if top == "hot" then  water.hot = tonumber(data) end
        end
        if water.cool ~= 0 and water.hot ~=0 then
            m:unsubscribe(myClient.."/#", function(conn) print("unsubscribe success") end)
            publ("Got and Ready!")
        end
    end)

    function closeWiFi()
        wifi.setmode(wifi.NULLMODE)
        -- wifi.sta.disconnect()
        print("WiFi switched OFF")
    end

    function debounce (func)
      local last = 0
      local delay = 50000
      return function (...)
      local now = tmr.now()
      local delta = now - last
      if delta < 0 then delta = delta + 2147483647 end;
      if delta < delay then return end;
      last = now
      return func(pinn)
      end
    end

    function onChange (which)
        if(which == "cool") then
            water.cool = water.cool + 10
            print("Cool got "..water.cool.." liters.")
        else
            water.hot = water.hot + 10
            print("Hot got "..water.hot.." liters.")
        end

        if publish then
            publish = false
            connecting(publ)
        end
    end
    function setPins()
        gpio.mode(3, gpio.INT)
        gpio.trig(3, 'down', debounce(onChange, "hot"))
        gpio.mode(4, gpio.INT)
        gpio.trig(4, 'down', debounce(onChange, "cool"))
        wifi.setmode(wifi.NULLMODE)
    end
    setPins()
    connecting()
    Начальные значения устанавливаются через MqttSpy. При первом запуске устройство соединяется с брокером и подписывается на свой топик.
    С брокера должны прийти данные о холодной и горячей воде.
    Устройство принимает их, отвечает в топик "report": "Got and Ready!" и отсоединяется от WiFi.
    После этого соединения устанавливаются только после сработки любого из контактов. Вновь соединение с wifi, отправка данных на брокер и рассоединение с wifi.
    Water31.jpg
    Вариант два. Расход отправляется раз в час, или не отправляется, если расхода не было:
    Код (Javascript):
    water = {
        cool = 0,
        hot = 0,
        bat = 3,
        unit = "water01"
    }
    sent = {
        cool = 0,
        hot = 0,
    }
    timeNextCheck = 3600000 -- час до следующей проверки

    Broker="broker.mqtt-dashboard.com"
    port=1883
    myClient="water017w31"
    pass="pass"

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

    function connecting(call)
        print('Connecting')
        wifi.setmode(wifi.STATION)
        wifi.sta.config("mypoint", "mypassword", 0)
        -- wifi.sta.setip(cfg)
        wifi.sta.connect()

        function getWiFi()
            tmr.alarm(5, 500, 1, function()
                if wifi.sta.status() == 5 and wifi.sta.getip() ~= nil then
                    getConnect(call)
                    tmr.unregister(5)
                    tmr.start(6)
                end
            end)
        end

        function getConnect(call)
            print("Got WiFi!")
            m:connect(Broker, port, 0, 0,
                function(conn)
                    tmr.stop(6)
                    print("Connected")
                    if call then
                        call()
                    else      
                        m:subscribe(myClient.."/#",0, function(conn)
                            print("Subscribed")
                        end)
                    end
            end)
        end
        getWiFi()
        tmr.register(6, 90000, 1, function()
            getConnect()
        end)
    end


    function publ(datt)
        water.bat = adc.readvdd33()/1000
        print ("Bat : "..water.bat )
        local topic = myClient.."/data"
        local dt = cjson.encode(water)
        print (topic.." : "..dt )
        if(datt) then
            topic = myClient.."/report"
            dt = datt
        end

        m:publish(topic, dt,1,1,function(conn)
            print("Published!")
            closeWiFi()
            sent.cool = water.cool
            sent.hot = water.hot
            --collectgarbage()
        end)
    end

    m:on("message", function(conn, topic, data)
        if (string.find(topic, "state")) == nil then
            local top = string.gsub(topic, myClient.."/","")
            if top == "cool" then water.cool =  tonumber(data)  end
            if top == "hot" then  water.hot = tonumber(data) end
        end
        if water.cool ~= 0 and water.hot ~=0 then
            m:unsubscribe(myClient.."/#", function(conn) print("unsubscribe success") end)
            publ("Got and Ready!")
        end
        -- collectgarbage()
    end)

    function closeWiFi()
        wifi.setmode(wifi.NULLMODE)
        -- wifi.sta.disconnect()
        print("WiFi switched OFF")
    end

    function debounce (func, pinn)
      local last = 0
      local delay = 50000
      return function (...)
      local now = tmr.now()
      local delta = now - last
      if delta < 0 then delta = delta + 2147483647 end;
      if delta < delay then return end;
      last = now
      return func(pinn)
      end
    end

    function onChange (which)
        if(which == "cool") then
            water.cool = water.cool + 10
            print("Cool got "..water.cool.." liters.")
        else
            water.hot = water.hot + 10
            print("Hot got "..water.hot.." liters.")
        end
    end
    function setPins()
        gpio.mode(3, gpio.INT)
        gpio.trig(3, 'down', debounce(onChange, "hot"))
        gpio.mode(4, gpio.INT)
        gpio.trig(4, 'down', debounce(onChange, "cool"))
        wifi.setmode(wifi.NULLMODE)
    end
    setPins()
    connecting()

    tmr.alarm(1, timeNextCheck, tmr.ALARM_AUTO,
        function()
            -- print(water.cool, sent.cool, water.hot, sent.hot)
            if((water.cool ~= sent.cool) or (water.hot ~= sent.hot)) then
                connecting(publ)
            end
        end)

    Продолжение: http://forum.amperka.ru/threads/arduino-esp8266-raspberry-pi-2-openhab-Умный-дом-азы-управления.5043/page-61#post-95532
     
    Последнее редактирование: 11 дек 2016
    Securbond, SergeiL и alp69 нравится это.