Page 1 of 1

fileexist

Posted: Friday 25 October 2019 10:07
by pvklink
Hi,

I write my motion output on a local share because my NAS sleeps at nighttime (GREEN EARTH policy).
When my NAS wakes up (6.00-24:00) i want to check if there are files from motion and if they do, move them to a mounted nas folder on my rpi.

So i did a lttle check if the fileexist option works, but i always get NOT EXIST ?

Code: Select all

return {
	on = {
		devices = {'test'},
		timer = {'every 10 minutes'},
	    },
	execute = function(dz)
    if dz.utils.fileExists("/mnt/mntroot/*.*") then
        dz.notify('FILE EXIST') 
	os.execute('sudo mv /mnt/mntroot/*.* /mnt/mntnas/')
    else
        dz.notify('FILE NOT EXIST') 
    end

end
}

Re: fileexist

Posted: Friday 25 October 2019 11:48
by waaren
pvklink wrote: Friday 25 October 2019 10:07 fileExists works but i always get NOT EXIST ?
The fileExists function can only check on full qualified filenames and cannot handle wildcards (same as the underlying io.open). To achieve this you will have to use io.popen.

Please check below script.

Code: Select all

return 
{
    on = 
    {
        devices = {'test'},
        timer = {'every 10 minutes'},
    },

    execute = function(dz)

        local sourceDir = '/mnt/mntroot'
        local targetDir = '/mnt/mntnas'

        local function osCommand(cmd)
            local fileHandle     = assert(io.popen(cmd, 'r'))
            local commandOutput  = assert(fileHandle:read('*a'))
            local returnTable    = {fileHandle:close()}
            if returnTable[3] ~= 0 then
                dz.log('\nCommand:       ' .. cmd .. '\nReturnCode:    ' .. returnTable[3] ..'\ncommandOutput: ' .. commandOutput,dz.LOG_ERROR)
            end
            return commandOutput
        end

        local function fileCount(dir)
            return tonumber(osCommand('ls ' .. dir .. ' | wc -l'))
        end    

        if fileCount(sourceDir) > 0 then
            dz.notify('FILE(s) EXIST') 
            osCommand('sudo mv ' .. sourceDir .. '/* '  .. targetDir .. '/')
        else
            dz.notify('FILE(s) NOT EXIST') 
        end
    end
}

Re: fileexist

Posted: Friday 25 October 2019 19:27
by pvklink
ahhh, thanks!

Does this script also works with files that are created at the same time that the script executes?
Motion is writing on source /mnt/mntroot and i dont know if there is somekind of locking that prohibits moving... or that the script moves incomplete files?

Another problem is that my nas (target) is not available between 2400 and 600, i think i can solve this by :
on = { timer = { 'every 15 minutes Between 06:05 and 24:00on mon,tue,wed,thu,fri,sat,sun' },

Re: fileexist

Posted: Friday 25 October 2019 21:33
by waaren
pvklink wrote: Friday 25 October 2019 19:27 Does this script also works with files that are created at the same time that the script executes?
Motion is writing on source /mnt/mntroot and i dont know if there is somekind of locking that prohibits moving... or that the script moves incomplete files?
No need to worry about that if you are on (a kind of) Linux. Linux file system is smart enough to deal with that using a system of pointers / iNodes. If you are interested how it works
Another problem is that my nas (target) is not available between 2400 and 600, i think i can solve this by :
on = { timer = { 'every 15 minutes Between 06:05 and 24:00on mon,tue,wed,thu,fri,sat,sun' },
Between must must be lower case. You wil not see an error but the rule will not evaluate identical. (need to look into that)
[EDIT] Timer rule text is no longer case sensitive in domoticz V4.11421 and later.

To stay on the safe side I would use

Code: Select all

on = { timer = { 'every 15 minutes between 06:05 and 23:59' },

Re: fileexist  [Solved]

Posted: Friday 25 October 2019 21:46
by pvklink
it works PERFECT!

Code: Select all

local timer_overdag = 'every 15 minutes between 06:05 and 23:59 on mon,tue,wed,thu,fri,sat,sun'         -- OVERDAG
local timer_nacht   = 'every 15 minutes between 00:05 and 06:00 on mon,tue,wed,thu,fri,sat,sun'         -- NACHT

return 
{
    on = { timer = {timer_overdag,timer_nacht},
        devices = {'filecopy'},
    },

    execute = function(dz,item,info)

        if (item.isDevice and item.name == 'filecopy' and item.state == 'On') or item.isTimer then
            local sourceDir = '/mnt/mntroot'
            local targetDir = '/mnt/mntnas'

            local function osCommand(cmd)
                local fileHandle     = assert(io.popen(cmd, 'r'))
                local commandOutput  = assert(fileHandle:read('*a'))
                local returnTable    = {fileHandle:close()}
                if returnTable[3] ~= 0 then
                    dz.log('\nCommand:       ' .. cmd .. '\nReturnCode:    ' .. returnTable[3] ..'\ncommandOutput: ' .. commandOutput,dz.LOG_ERROR)
                end
                return commandOutput
            end

            local function fileCount(dir)
                return tonumber(osCommand('ls ' .. dir .. ' | wc -l'))
            end    

            if fileCount(sourceDir) > 0 then
                dz.notify('NAS: Er zijn bestanden op de SHARE aanwezig...') 
                dz.devices('motion files aanwezig').switchOn()

                if (item.isDevice and item.name == 'filecopy' and item.state == 'On') or (item.isTimer and item.trigger == timer_overdag) then
                    osCommand('sudo mv ' .. sourceDir .. '/* '  .. targetDir .. '/')
                    dz.notify('NAS: Er zijn bestanden verplaatst...') 
                    dz.devices('motion files aanwezig').switchOff()
                end
            else
                dz.notify('NAS: Er zijn geen bestanden op de SHARE aanwezig...') 
                dz.devices('motion files aanwezig').switchOff()
            end
        
            if item.isDevice and item.name == 'filecopy' and item.state == 'On' then
                item.switchOff().afterSec(5)
            end
        end
    end
}

Re: fileexist

Posted: Friday 25 October 2019 23:31
by pvklink
Hi @waaren
script works perfect, sync works also perfect !
I added the global message construction and some addons.

Only one scriptline(loggingline) does not work, the one with:
globalMessage(add, '\nCommand: ' .. cmd .. '\nReturnCode: ' .. returnTable[3] ..'\ncommandOutput: ' .. commandOutput .. '',logcode) or
the original;
--dz.log('\nCommand: ' .. cmd .. '\nReturnCode: ' .. returnTable[3] ..'\ncommandOutput: ' .. commandOutput,dz.LOG_ERROR)

see code below.
I also dont understand why this has a value of 3...

p.

Code: Select all

local timer_overdag = 'every 15 minutes between 06:10 and 00:25 on mon,tue,wed,thu,fri,sat,sun'         -- OVERDAG dan wel syncen
local timer_nacht   = 'every 15 minutes between 00:35 and 06:00 on mon,tue,wed,thu,fri,sat,sun'         -- NACHT dan niet syncen
--
-- nas gaat om 6 aan en 0030 uit en op ma di do ook van 9-14 uit --dit laatste is nog niet verwerkt
-- dz.log('\nCommand:       ' .. cmd .. '\nReturnCode:    ' .. returnTable[3] ..'\ncommandOutput: ' .. commandOutput,dz.LOG_ERROR)  deze regel doet t nog niet komt dit door [3] waar is deze 3 voor?
-- /mnt/mntroot nog aan een extra usb stick koppelen 

return 
{
    on = { timer = {timer_overdag,timer_nacht},
        devices = {'filecopy'},
    },

    execute = function(dz,item,info)

        if (item.isDevice and item.name == 'filecopy' and item.state == 'On') or item.isTimer then

            local logcode = 3
            local messageTable = {}
            local add = 'add'
            local del = 'del'
            local chg = 'chg'
        
            local function globalMessage(action, message, logcode)
 
                if logcode == nil then logcode = 3 end
 
                if action == add and logcode > 0 then
                    messageTable = dz.helpers.addMessage(dz, item, info, message, messageTable, logcode)
                elseif action == del then
                    dz.globalData.mylogging = message
                    dz.devices('timerlog').updateText(message)
                elseif action == chg then 
                    dz.helpers.dumpMessages(dz, messageTable)
                end
 
            end

            local sourceDir = '/mnt/mntroot'
            local targetDir = '/mnt/mntnas'

            local function osCommand(cmd)
                local fileHandle     = assert(io.popen(cmd, 'r'))
                local commandOutput  = assert(fileHandle:read('*a'))
                local returnTable    = {fileHandle:close()}
                if returnTable[3] ~= 0 then
-- The globalMessage does not work.. why is that ?  the dz.log below also does not work why the 3
                    globalMessage(add, '\nCommand:       ' .. cmd .. '\nReturnCode:    ' .. returnTable[3] ..'\ncommandOutput: ' .. commandOutput .. '',logcode)
                    --dz.log('\nCommand:       ' .. cmd .. '\nReturnCode:    ' .. returnTable[3] ..'\ncommandOutput: ' .. commandOutput,dz.LOG_ERROR)
                end
                return commandOutput
            end

            local function fileCount(dir)
                return tonumber(osCommand('ls ' .. dir .. ' | wc -l'))
            end    

            if fileCount(sourceDir) > 0 then
                globalMessage(add, ' NAS: Er zijn bestanden op de SHARE aanwezig...',logcode)
                dz.devices('motion files aanwezig').switchOn()

                if (item.isDevice and item.name == 'filecopy' and item.state == 'On') or (item.isTimer and item.trigger == timer_overdag) then
                    osCommand('sudo mv ' .. sourceDir .. '/* '  .. targetDir .. '/')
                    globalMessage(add, ' NAS: Er zijn bestanden verplaatst...',logcode)
                    dz.devices('motion files aanwezig').switchOff()
                end
            else
                globalMessage(add, ' NAS: Er zijn geen bestanden op de SHARE aanwezig...',logcode)
                dz.devices('motion files aanwezig').switchOff()
            end
        
            if item.isDevice and item.name == 'filecopy' and item.state == 'On' then
                item.switchOff().afterSec(5)
            end
            globalMessage(chg) -- dump

        end
    end
}

Re: fileexist

Posted: Saturday 26 October 2019 1:53
by waaren
pvklink wrote: Friday 25 October 2019 23:31 Only one scriptline(loggingline) does not work, the one with:

Code: Select all

globalMessage(add, '\nCommand:       ' .. cmd .. '\nReturnCode:    ' .. returnTable[3] ..'\ncommandOutput: ' .. commandOutput .. '',logcode)
or
the original;

Code: Select all

--dz.log('\nCommand:       ' .. cmd .. '\nReturnCode:    ' .. returnTable[3] ..'\ncommandOutput: ' .. commandOutput,dz.LOG_ERROR)
The line is not incorrect in itself but the .. '' at he end of the message does nothing. It can be removed.

Code: Select all

globalMessage(add, '\nCommand:       '  .. cmd  .. '\nReturnCode:    ' .. returnTable[3]  .. '\ncommandOutput: ' .. commandOutput,logcode)
but this line will only be reached when returnTable[3] is not equal to 0. This will happen if the io.popen failed or came back with a warning. When the io.popen executed without problems returnTable[3] will be equal to 0 and the line will not be evaluated
I don't think you will be very surprised by the fact that returnTable is.... a table. It is populated with the result of the fileHandle:close() which are 3 values.
returnTable[1] is true if the command terminated successfully, or nil otherwise.
returnTable[2] A string "exit" if the command terminated normally or "<signal>" if the command was terminated by a signal
returnTable[3] The numeric exit code from the command. (0 all ok, > 0 otherwise)

Re: fileexist

Posted: Saturday 26 October 2019 9:44
by pvklink
Thanks!
i added the theorie to the script for learning purpose..and it is running....

i also made a node-red script for this sync, but it is instable with partial syncing...
So dzevents look like 'haarlemmerolie' .... and works as ever...

next part is adding a seperate usb stick and mount it for this motion storage so that my main OS stays intact.