Export last hour CSV object log file to external or local FTP server from LogicMachine #
Task #
Once an hour, create a CSV file with all object logs and send
to an external FTP server with IP 192.168.1.11, login ftplogin,
password ftppassword. In case you want to download the file
manually from LM local FTP server, it is available in
directory /home/ftp
Scheduled script #
In Scripting -> Scheduled add the script which will run once an hour and add following code into the Script editor.

require('socket.ftp')
-- ftp file
url = 'ftp://ftplogin:ftppassword@192.168.1.11/%s.csv'
date = os.date('%Y-%m-%d_%H-%M')
ftpfile = string.format(url, date)
-- get past hour data (3600 seconds)
logtime = os.time() - 60 * 60
-- csv buffer
buffer = {
'"date","type","destination","name","datatype",' ..
'"value","source","sender","login/meta"'
}
-- get object logs
query = [[
SELECT ol.*, o.name, o.datatype
FROM objectlog ol
LEFT JOIN objects o ON ol.address=o.id
WHERE logtime >= ?
ORDER BY id DESC
]]
function fmtdpt(dpt)
if dpt >= 1000 then
dpt = string.format('%0.3f', dpt / 1000)
end
return dpt
end
for _, row in ipairs(db:getall(query, logtime)) do
id = tonumber(row.address) or 0
ia = tonumber(row.src) or 0
logdate = os.date('%Y.%m.%d %H:%M:%S', math.floor(row.logtime))
etype = row.eventtype
textdpt = nil
if (etype == 'write' or etype == 'response') and row.datatype then
textdpt = fmtdpt(row.datatype)
value = grp.decodevalue(row.datahex, row.datatype)
else
value = ''
end
buffer[ #buffer + 1 ] = string.format('%q,%q,%q,%q,%q,%q,%q,%q,%q',
logdate,
etype,
buslib.decodega(id),
row.name or '',
tostring(textdpt or ''),
tostring(value),
ia > 0 and buslib.decodeia(ia) or 'local',
row.sender or '',
row.meta or ''
)
end
-- upload to ftp only when there's data in buffer
if #buffer > 1 then
res, err = socket.ftp.put(ftpfile, table.concat(buffer, '\r\n'))
end
-- error while uploading
if err then
alert('FTP upload error: %s', tostring(err))
end
Write to an existing FTP file #
Replace these lines:
if #buffer > 1 then
res, err = socket.ftp.put(ftpfile, table.concat(buffer, '\r\n'))
end
With these:
if #buffer > 1 then
data = table.concat(buffer, '\r\n')
ltn12 = require('ltn12')
res, err = socket.ftp.put({
host = '192.168.1.40',
user = 'ftp',
password = 'ftp',
command = 'appe',
argument = 'log.csv',
source = ltn12.source.string(data)
})
end
Local FTP CSV storage #
Modify the original script as follows.
Step 1 #
Replace this line:
url = 'ftp://ftplogin:ftppassword@192.168.1.11/%s.csv'
With this:
url = '/home/ftp/%s.csv'
Step 2 #
Replace these lines:
-- upload to ftp only when there's data in buffer
if #buffer > 1 then
result, err = socket.ftp.put(ftpfile, table.concat(buffer, '\r\n'))
end
-- error while uploading
if err then
alert('FTP upload error: %s', tostring(err))
end
With these:
if #buffer > 1 then
data = table.concat(buffer, '\r\n')
io.writefile(ftpfile, data)
end
Step 3 #
Create a scheduled script that runs once a day to remove old logs (60 is a number of days to keep old logs):
function cleanup(dir, days)
local now, files, mtime, delta
now = os.time()
files = io.ls(dir) or {}
for _, file in ipairs(files) do
file = dir .. '/' .. file
_, mtime = io.stat(file)
if mtime then
delta = (now - mtime) / 86400
if delta > days then
os.remove(file)
end
end
end
end
cleanup('/home/ftp', 60)