Архив данных (сервер недоступен)

Подключение исполнительных устройств, датчиков, контроллеров.

Модератор: immortal

Gofk
Сообщения: 7
Зарегистрирован: Вт дек 26, 2017 10:44 pm
Благодарил (а): 0
Поблагодарили: 0

Re: Архив данных (сервер недоступен)

Сообщение Gofk » Чт янв 11, 2018 11:45 am

Эммм... тихо сам с собою? ))))
Аватара пользователя
xor
Сообщения: 2038
Зарегистрирован: Сб ноя 22, 2014 8:45 pm
Благодарил (а): 284 раза
Поблагодарили: 629 раз

Re: Архив данных (сервер недоступен)

Сообщение xor » Чт янв 11, 2018 11:47 am

Gofk писал(а):Эммм... тихо сам с собою? ))))
Ага))

Отправлено с моего Redmi 4X через Tapatalk
Gofk
Сообщения: 7
Зарегистрирован: Вт дек 26, 2017 10:44 pm
Благодарил (а): 0
Поблагодарили: 0

Re: Архив данных (сервер недоступен)

Сообщение Gofk » Чт янв 11, 2018 11:52 am

xor писал(а):Есть логи фиксированной структуры, т.е., вы знаете, что первый элемент-дата, второй-температура датчика 1 и тд. Надо это хозяйство засунуть в таблицу истории
...
Скармливаем лог пхп скрипту, он его парсит по-строчно. Зная имяОбъекта.Свойство, вставляем в таблицу истории , заменяя поле added временем из лога.
...
Нужно распарсить, найти объекты, по ним определить id, работа с SQL -- практика.
Тут какая засада. Нужно тогда в лог писать и идентификатор объекта/свойства (привет domoticz). А когда в системе какие-нибудь изменения будут - всё отвалится нафиг.
Мне кажется единственный рабочий вариант - для каждого датчика в логе писать уникальный (!) ID. А привязку к объекту делать на принимающей стороне. Опять же, как это сейчас с данными по MQTT происходит. Но это не только скрипт нужен, но и вся обвязка в виде пользовательского интерфейса и т.д.
Аватара пользователя
xor
Сообщения: 2038
Зарегистрирован: Сб ноя 22, 2014 8:45 pm
Благодарил (а): 284 раза
Поблагодарили: 629 раз

Re: Архив данных (сервер недоступен)

Сообщение xor » Чт янв 11, 2018 11:59 am

Gofk писал(а):
xor писал(а):Есть логи фиксированной структуры, т.е., вы знаете, что первый элемент-дата, второй-температура датчика 1 и тд. Надо это хозяйство засунуть в таблицу истории
...
Скармливаем лог пхп скрипту, он его парсит по-строчно. Зная имяОбъекта.Свойство, вставляем в таблицу истории , заменяя поле added временем из лога.
...
Нужно распарсить, найти объекты, по ним определить id, работа с SQL -- практика.
Тут какая засада. Нужно тогда в лог писать и идентификатор объекта/свойства (привет domoticz). А когда в системе какие-нибудь изменения будут - всё отвалится нафиг.
Мне кажется единственный рабочий вариант - для каждого датчика в логе писать уникальный (!) ID. А привязку к объекту делать на принимающей стороне. Опять же, как это сейчас с данными по MQTT происходит. Но это не только скрипт нужен, но и вся обвязка в виде пользовательского интерфейса и т.д.
Посмотрите, как gps, esp, noolite обрабатываются пхпэшками.

Отправлено с моего Redmi 4X через Tapatalk
Аватара пользователя
xor
Сообщения: 2038
Зарегистрирован: Сб ноя 22, 2014 8:45 pm
Благодарил (а): 284 раза
Поблагодарили: 629 раз

Re: Архив данных (сервер недоступен)

Сообщение xor » Чт янв 11, 2018 12:36 pm

Ага-ага. У себя я собираю данные с сети модулей, правда, в реальном времени, модуль передает свой номер, номер внутреннего ресурса, значение. Внутри МЖД уже распихивает это по линкованным объектам, свойствам

Отправлено с моего Redmi 4X через Tapatalk
Gofk
Сообщения: 7
Зарегистрирован: Вт дек 26, 2017 10:44 pm
Благодарил (а): 0
Поблагодарили: 0

Re: Архив данных (сервер недоступен)

Сообщение Gofk » Сб янв 13, 2018 2:41 pm

Ну что-то типа такого на модуле может быть. Так сказать, черновик.
Общая логикаПоказать
По первому таймеру (5 секунд) фиксируем показания. Время получаем с NTP-сервера. Показания через MQTT передаем на сервер и записываем построчно в файл на SD-карте (test.txt). Очевидно, что при этом можно добавить идентификаторы датчиков и т.д.
По второму таймеру (30 секунд) просто переименовываем файл на карточке в test_to_send.txt. При записи текущих данных создается новый файл test.txt и выгрузка архивов не пересекается с записью данных в файл.
Далее просто проходим построчно по файлу test_to_send.txt и передаем строки в отдельный топик MQTT.
По окончанию файл test_to_send.txt удаляем.
Проверено, работает. Архивы выплевывает очень шустро.
Собственно, логику можно накрутить любую. Записывать данные только тогда, когда их не удалось передать. Выгружать по HTTP. Это не принципиально.
И сам формат записи, естественно, нужно в божеский вид приводить, а не записывать как придется.
А вот что с этими данными делать на принимающей стороне - вопрос. Можно в лоб запихивать в базу. Но некрасиво...
И сам код:
main.luaПоказать

Код: Выделить всё

function getTime()
    sntp.sync('ru.pool.ntp.org',
    function(sec,usec,server)
        print('sync', sec, usec, server)
        pin = 4
        status, temp, humi, temp_dec, humi_dec = dht.read(pin)
        if file.open("/SD0/test.txt", "a+") and status == dht.OK then
            file.write('sync '..';'..sec..';'..usec..';'..server.." - ")
            file.write(string.format("DHT Temperature:%d.%03d;Humidity:%d.%03d\r\n",
                math.floor(temp),
                temp_dec,
                math.floor(humi),
                humi_dec))
                file.close()
            m = mqtt.Client("ESP8266_1", 120)
            m:on("connect", function(client) print ("MQTT online") end)
            m:on("offline", function(client) print ("MQTT offline") end)
            m:on("message", function(client, topic, data) 
                print("<-- "..topic .. ":"..data ) 
            end)
            m:connect("192.168.0.30", 1883, 0, function(client)
                print("MQTT client connected")
                client:subscribe("#", 0, function(client) print("subscribe success") end)
                client:publish("dht21/temp", temp, 0, 0)
                client:publish("dht21/hum", humi, 0, 0)
            end,
            function(client, reason)
                print("MQTT failed reason: " .. reason)
            end)
            m:close();
            print("MQTT client disconnected")          
        elseif status == dht.ERROR_CHECKSUM then
            print( "DHT Checksum error." )
        elseif status == dht.ERROR_TIMEOUT then
            print( "DHT timed out." )
        end   
    end,
    function()
        print('failed!')
    end, true) 
end

function sendArchive()
    file.rename("/SD0/test.txt","/SD0/test_to_send.txt")
    if file.exists("/SD0/test_to_send.txt") then
        print("File exists or renamed")
        m1 = mqtt.Client("ESP8266_1_archive", 300) 
        m1:connect("192.168.0.30", 1883, 0, function(client)
                print("MQTT client connected")
                fd = file.open("/SD0/test_to_send.txt", "r")
                if fd then
                    print("ARCHIVE START")
                    line = file.readline()
                    while line do                                           
                        client:publish("dht21/archive", line, 0, 0)
                        line = file.readline()
                    end
                    file.close()
                    file.remove("/SD0/test_to_send.txt")
                end
            end,
            function(client, reason)
                print("MQTT failed reason: " .. reason)
            end)
        m1:close();  
    else
        print("Error file renaming")    
    end
end

r1tmr = tmr.create():alarm(5000, tmr.ALARM_AUTO, getTime)
r2tmr = tmr.create():alarm(30000, tmr.ALARM_AUTO, sendArchive)
init.luaПоказать

Код: Выделить всё

function startup()
    print("Running")    
    spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
    vol = file.mount("/SD0", 8)
    if not vol then
        print("...retry mounting")
        vol = file.mount("/SD0", 8)
        if not vol then
            error("SD-card mount failed")
        else            
            file.close("init.lua")
            dofile("main.lua")    
        end
    else        
        file.close("init.lua")
        dofile("main.lua")      
    end
end

print("Connecting to WiFi access point...")
wifi.setmode(wifi.STATION)
local wificfg={}
wificfg.ssid='wifiUser'
wificfg.pwd='wifiPassword'
wifi.sta.config(wificfg)
wificfg = nil
tmr.create():alarm(1000, tmr.ALARM_AUTO, function(cb_timer)
    if wifi.sta.getip() == nil then
        print("Waiting for IP address...")
    else
        cb_timer:unregister()
        print("WiFi connection established, IP address: " .. wifi.sta.getip())
        print("You have 3 seconds to abort")
        print("Waiting...")
        tmr.create():alarm(3000, tmr.ALARM_SINGLE, startup)
    end
end)
 
Теперь бы еще разобраться, как этот код в человеческий вид привести. Никак не могу логику LUA осознать :)
Ответить