ESP-8266. Alarm to Telegram, Pushsafer or Pushover: temerature, movement, siren.

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

Метки:
  1. ИгорьК

    ИгорьК Гуру

    Пока Телеграм не закрыли... Зато все просто как грибы и водоросли.

    Это абсолютно рабочий типаПроект. Вызван он тем, что (по слухам) ветка dev от NodeMCU правильно работает по протоколу https.
    UPD: и ветка мастер теперь работает правильно.
    Проверил: работает правильно. Родился такой, малоактуальный в летнее время, скрипт контроля температуры где-нибудь зачем-нибудь, а постом ниже - и нарушения пространства.

    ТипаПроект состоит из четырех файлов. Главный - main.lua:
    Код (Lua):
    do
    -- Минимальная температура, ниже которой информация отправляется на Телеграм
    mint = 27
    -- Адрес датчика контроля температуры
    tr = '2856837B040000A5'
    -- Интервал проверки датчика в секундах
    int =  30

    dat = ""
    flag = false

    local snd = function()
          flag = false
          tmr.create():alarm(10000, 0, function(t)
             dofile('sendteleg.lua')
          end)
    end

    local send = function()
        local temp = {}
        ds = require('_ds18b20')
        local function myWork()
           package.loaded["_ds18b20"]=nil
           ds = nil
            dat = "{"
           for k, v in pairs(temp) do
               if k == tr and tonumber(v) < mint then flag = true end
                 dat = dat..'t'..k..":"..v..','
           end
           dat = dat..'}'
            print(dat)
           if flag then snd() end

        end
        ds.getTemp(temp, myWork, 4, 750)
    end
    send()
    tmr.create():alarm(int*1000, 1, send)
    end
    Важные вещи:
    • Между измерением температуры и ее отправкой в Телеграм есть пауза 10 секунд. Это связано с тем, что модулю надо время для очистки памяти после измерения температуры.
    • Скрипт работает с любым количеством датчиков DS18b20 (дата подтянута 4.7 ком) . Датчик вешать на ногу 4 иначе править строку "ds.getTemp(temp, myWork, 4, 750) ". 4 - нога датчика.
    • Адрес контрольного датчика. Адреса всех датчиков выводятся скриптом в консоль, поэтому во второй строке скрипта адрес указывается именно для вашего датчика, который вы обязательно увидите при правильном соединении.
    • Установите в скрипте значение переменной mint больше разумного и данные будут отправляться постоянно с интервалом, что задается переменной int.
    • Файл sendteleg.lua надо обязательно править в соответствии с данными вашего бота. В прилагаемом файле никаких данных нет. Запуск "как есть" вызовет ошибку.
    • Все мои модули ESP-8266 запаяны большой памятью, поэтому я не знаю, будет ли этот скрипт работать на ESP-1, не проверял. На NodeMCU работать будет точно. Для ESP-1 вероятность очень велика.
    • Несложно, также, доработать это устройство как датчик охраны, когда при соединении с PIR датчиком также отправляется телеграмма.
    При заказе прошивки действовать так:
    UPD. Мастер тоже годится.

    upload_2018-4-9_14-21-0.png

    и так:

    upload_2018-4-9_14-22-40.png

    Остальные файлы в приложении.

    Вот как это работает:
    upload_2018-4-9_14-48-44.png

    Измерена температура с двух датчиков, датчик, что подсвечен желтым - контрольный, данные ушли на мой бот.


    Не забываем перед всеми манипуляциями завести модуль в сеть, выполнив один раз код:
    Код (Lua):
    do
    wifi.setmode(wifi.STATION)
    wifi.sta.clearconfig()
    local scfg = {}
    scfg.auto = true
    scfg.save = true
    scfg.ssid = 'ВАША_АР'
    scfg.pwd = 'ВАШПАРОЛЬ'
    wifi.sta.config(scfg)
    wifi.sta.connect()
    tmr.create():alarm(15000, tmr.ALARM_SINGLE, function() print('\n', wifi.sta.getip()) end)
    end
     

    Вложения:

    • Amperka02.zip
      Размер файла:
      2,3 КБ
      Просмотров:
      420
    Последнее редактирование: 11 апр 2018
    Arduino_man, IvanUA, Airbus и 2 другим нравится это.
  2. ИгорьК

    ИгорьК Гуру

    Продолжим. Добавим PIR на ногу pinal. Кстати, PIR питается от 5 вольт, но сигнал выдает 3.3.
    Правим скрипт main.lua и получаем не только оповещалку о температуре, но и о нарушении пространства:

    Код (Lua):
    do
    minn = 27 -- Контрольная температура
    tr = '2856837B040000A5' -- Адрес контрольного датчика
    int =  30 -- Интервал замера температуры в секундах
    pinds = 4 -- Нога DS18b20
    pinal = 7 -- Нога PIR датчика

    gpio.mode(pinal, gpio.INPUT)

    dat = ""
    biz = false
    flag = false

    local snd = function()
          flag = false
          tmr.create():alarm(1000, 0, function(t)
             dofile('sendteleg_old.lua')
          end)
    end

    -- local sndalarm = function()
    sndalarm = function()
          biz = true
          dat = "Alarm!!!"
          dofile('sendteleg.lua')
    end

    gpio.trig(pinal, "up", sndalarm)

    local send = function()
        if biz then return end
         local temp = {}
        ds = require('_ds18b20')
        local function myWork()
           package.loaded["_ds18b20"]=nil
           ds = nil
            dat = "{"
           for k, v in pairs(temp) do
               if k == tr and tonumber(v) < minn then flag = true end
                 dat = dat..'t'..k..":"..v..','
           end
           dat = dat..'}'
            print(dat)
           if flag and not biz then snd() end
        end
        ds.getTemp(temp, myWork, ponds, 750)
    end
    send()
    tmr.create():alarm(int*1000, 1, send)
    end
    Теперь у нас доклад о татях и холоде.

    пысы, может сирену добавить?
     
    Последнее редактирование: 9 апр 2018
    Airbus и atompost нравится это.
  3. ИгорьК

    ИгорьК Гуру

    Посмотрел на слив памяти - не течет:

    upload_2018-4-9_17-34-46.png

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

    Код (Lua):
    do
    minn = 15
    tr = '2856837B040000A5'
    int =  30
    pinds = 4
    pinal = 7
    countsend = 2

    count = 0

    gpio.mode(pinal, gpio.INPUT)

    dat = ""
    biz = false
    flag = false

    local snd = function()
          flag = false
          tmr.create():alarm(5000, 0, function(t)
             dofile('sendteleg.lua')
          end)
    end

    -- local sndalarm = function()
    sndalarm = function()
          biz = true
          dat = "Alarm!!!"
          dofile('sendteleg.lua')
    end

    gpio.trig(pinal, "up", sndalarm)

    local send = function()
        count = count + 1
         if biz then return end
         local temp = {}
        ds = require('_ds18b20')
        local function myWork()
           package.loaded["_ds18b20"]=nil
           ds = nil
            dat = "{"
           for k, v in pairs(temp) do
               if k == tr and tonumber(v) < minn then flag = true end
                 dat = dat..'t'..k..":"..v..','
           end
           dat = dat..'}'
            print(dat)
           print(node.heap())
            if (flag and not biz) or (count > countsend and not biz)then
               if count > countsend then count = 0 end
               snd()
            end
        end
        ds.getTemp(temp, myWork, ponds, 750)
    end
    send()
    tmr.create():alarm(int*1000, 1, send)
    end
     
    Последнее редактирование: 9 апр 2018
    IvanUA и Airbus нравится это.
  4. ИгорьК

    ИгорьК Гуру

    Что еще добавить. Файл sendteleg.lua можно записать в таком виде, что не удобно, но экономит существенно память:
    Код (Lua):
    if not dat then return end
    local curl = 'GET /bot123456789:AAAAAaaaaaAAAAaaaa-aaasss777eeeaaaa/sendMessage?chat_id=123456789&text='..dat..'\r\nHost: api.telegram.org\r\n\r\n'

    local srv = tls.createConnection()
    srv:on("receive", function(sck, c)
         c = nil
         print('\nSent at heap: '..node.heap()..'\n')
         sck:close()
         curl, sck = nil, nil  
    end)
    srv:on("connection", function(sck, c)
        sck:send(curl)
    end)
    srv:connect(443,"api.telegram.org")
     
    IvanUA и Airbus нравится это.
  5. Airbus

    Airbus Радиохулиган Модератор

    Скоро закроют.Остался Blynk
     
    Последнее редактирование: 13 апр 2018
  6. ИгорьК

    ИгорьК Гуру

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

    Код (Lua):
    do
    minn = 15 -- controlled temperature
    tr = '2856837B040000A5' -- address of control DS18b20
    int =  30 -- interval to ask DS1820 for temperatuer
    pinds = 4 -- DS18b20 pin
    pinal = 7 -- pin for PIR
    pinsr = 8 -- Siren pin
    countsend = 10 -- interval times to send data to Telegram

    askt = tmr.create()
    count = 0

    gpio.mode(pinal, gpio.INPUT)
    gpio.mode(pinsr, gpio.OUTPUT)
    gpio.write(pinsr, gpio.LOW)

    dat = ""
    flag = false

    siren = function(makeoff)
        if not stopsirentmr then
            print('gpio.HIGH')
            gpio.write(pinsr, gpio.HIGH)
            stopsirentmr = tmr.create()
                stopsirentmr:alarm(30000, 0, function()
                siren(true)
            end)
        end

        if not makeoff then
            stopsirentmr:stop()
              dat = "Alarm!!!"
            stopsirentmr:start()
              snd()
        end

        if makeoff then
            stopsirentmr = nil
              tmr.start(askt)
            gpio.write(pinsr, gpio.LOW)
            print('gpio.LOW')
        end
    end


    snd = function()
        tmr.stop(askt)
        tmr.create():alarm(3000, 0, function(t)
        dofile('sendteleg_new.lua')
        end)
    end

    gpio.trig(pinal, "up", siren)

    local send = function()
        count = count + 1
         local temp = {}
        ds = require('_ds18b20')
        local function myWork()
            package.loaded["_ds18b20"]=nil
            ds = nil
            dat = ""
              for k, v in pairs(temp) do
                if k == tr and tonumber(v) < minn then flag = true end
                dat = dat..'t'..k..":"..v..','
            end
            print(dat)
            if flag or (count > countsend) then
                flag = false
                count = 0
                snd(true)
            end
        end
        ds.getTemp(temp, myWork, pinds, 750)
    end
    send()
    askt:alarm(int*1000, 1, send)
    end
    _ds18b20.lua - first message.

    sendteleg_new.lua
    :
    Код (Lua):
    if not dat then return end
    local curl = 'GET /bot123456789:aaaaAAAAaaaaAAAAAA-aa22aa22aa22aa22/sendMessage?chat_id=123456789&text='..dat..'\r\nHost: api.telegram.org\r\n\r\n'

    local srv = tls.createConnection()
    srv:on("receive", function(sck, c)
        c = nil
        print('\nSent at heap: '..node.heap()..'\n')
        sck:close()
        curl, sck = nil, nil
        if flagalarm then
            makealarm()
        end
        tmr.start(askt)
    end)
    srv:on("connection", function(sck, c)
        sck:send(curl)
    end)
    srv:connect(443,"api.telegram.org")

    IvanUA, принимай вахту :)
     
    Последнее редактирование: 17 апр 2018
  7. SergeiL

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

    Ну, я еще поборюсь :)
    Вот поднял машинку с Убунтой в Итальянском датацентре за 1 евро в месяц.
    Посмотрим, что получится :)
     
    Egony и ИгорьК нравится это.
  8. ИгорьК

    ИгорьК Гуру

    Как это объяснить датчику движения, что напрямую шлет запрос на телегу? Это уже другое устройство.
     
  9. ИгорьК

    ИгорьК Гуру

    Вообще, интересная мысль. IP - белый? То есть, можно делать http/tcp - запрос к этой машинке?
     
  10. SergeiL

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

    Прописать на роутере, чтобы трафик для телеграм отправлять в VPN тунель.
    IP белый.
     
    ИгорьК нравится это.
  11. ИгорьК

    ИгорьК Гуру

    Даже не знаю, стоит этим заниматься или нет. У меня не было устройств, работающих с Телеграм. То что в текущих условиях сделать их можно - да. Но нужно ли усложнять, или поискать другое решение... IFTTT например... Подумать надо.
    Для вашего случая, когда уже есть рабочее железо - это, безусловно, решение. Но стоит ли делать новые устройства - пока не уверен.

    Плюс ситуации с последней прошивкой от NodeMCU в том, что стало возможным отправлять безошибочные tls запросы. А уж куда их отправлять напрямую с модуля - надо поразмышлять.
     
  12. SergeiL

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

    Согласен! Можно найти что-то другое.
    Но я больше занялся этим, потому, что неизвестно, что дальше...
    А так, щелкнул выключателем на компе или телефоне, и выходишь уже в Италии!
     
    Airbus и ИгорьК нравится это.
  13. ИгорьК

    ИгорьК Гуру

    Цена удивительная... Давайте, рекламируйте.
     
    Airbus нравится это.
  14. SergeiL

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

    Сам удивился! Пошаговая инструкция здесь
    Работает, пингуется. Только VPN, буду L2TP ставить.
     
    Airbus, Egony и ИгорьК нравится это.
  15. ИгорьК

    ИгорьК Гуру

    Надо хватать. "Разбомбят" этот сервис наши сограждане быстро, исчерпают ресурс :)
     
    Airbus и SergeiL нравится это.
  16. ИгорьК

    ИгорьК Гуру

    И что оказалось... Если поменять содержимое скрипта sendteleg_new.lua - вся эта лабуда без проблем отправляется на сервис pushsafer.com. С этим сервисом легко работает и Domotocz, что тоже определило выбор.

    До некоторого предела сервис бесплатен - для Alarm вполне хватит, но и свыше этого цены не заоблачные.
    Что еще доставляет, так это возможность отправки сообщений по протоколу http, а не только по https.
    Шифрование требует многомного памяти.
    Но если за вами кто-то подглядывает и подслушивает - включаете шифрование, добавив ОДНУ буковку в адрес сайта в скрипте. Вот он - пользуйтесь на здоровье и безопасность:

    Код (Lua):
    if wifi.sta.status() ~= 5 then return end
    if not dat then dat = 'Alarm!!!' end
    http.post('http://www.pushsafer.com/api', 'Content-type: application/x-www-form-urlencoded\r\n' , 'k=ЗДЕСЬ_ВАШ_АПИКЛЮЧ&m='..dat,
        function(code, data)
            if (code < 0) then
                print("HTTP request failed")
            else
                print(code, data)
            end
            if not flagalarm then tmr.start(askt) end
        end)
     
    Последнее редактирование: 18 апр 2018
    IvanUA и SergeiL нравится это.
  17. SergeiL

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

    Посмотрел доки OH, в Actions есть поддержка Pushsafer.
    Там есть поддержка и обычного e-mail.
    Как вариант, для информационных, не критических, сообщений - самое то! Как запасной вариант будет.
     
  18. ИгорьК

    ИгорьК Гуру

    а для критических?
     
  19. SergeiL

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

    На iPhone - Prowl. Быстрее и надежнее ничего не видел. Задержка 1-2 секунды, с 2016-го не заметил ни одного недошедшего сообщения. Лимит по отправке - 1000 сообщений в час. Куда уж лучше! :)

    Просто Prowl клиент построен в виде Alarm панели. Когда все аварии прочитаны, и не требуют каких либо действий нажимаешь очистить, и панель чистая.

    И как мне кажется, удобней разделять критику и менее важную информацию, которая может приходить и без звука. Увидел новые сообщения - просмотрел.
    А иначе перестаешь реагировать, привыкаешь,что постоянно что-то сыпется..
     
    Последнее редактирование: 17 апр 2018
  20. ИгорьК

    ИгорьК Гуру

    Сейчас отправляю сообщения из ESP-8266 на Pushsafer и на Pushover - все доходит железно и сразу.
    Полагаю, все эти системы работают одинаково. Не совсем понимаю деление на обычные и критические сообщения.
    ИМХО, критические - push любой системы, а все остальное - ОН, Domoticz, etc.