need a loop for reading messages for logging  [Solved]

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Re: need a loop for reading messages for logging

Post by pvklink »

it is the dashticz environment....
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Re: need a loop for reading messages for logging

Post by pvklink »

in the domoticz env it is ok...
strange thing is that my old scripts also write to this text device with

msgtxt = 'Alarm is uitgezet, scenes worden gedeactiveerd....'
timertekst = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. msgtxt .. '<br>' .. dz.devices('timerlog').text
dz.devices('timerlog').updateText(timertekst)

and with this it works in dashticz and domoticz...
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Re: need a loop for reading messages for logging

Post by pvklink »

Lines attached is only when the script has executed more than one
globalMessage(add, message .. ' AVOND AAN: huiskamerverlichting wordt AAN gezet...')

before globalMessage() -- dump

When it concerns only one globalMessage(add, message .. ' AVOND AAN: huiskamerverlichting wordt AAN gezet...')
all went OK!
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: need a loop for reading messages for logging

Post by waaren »

pvklink wrote: Sunday 30 June 2019 22:22 Lines attached is only when the script has executed more than one
globalMessage(add, message .. ' AVOND AAN: huiskamerverlichting wordt AAN gezet...')

before globalMessage() -- dump

When it concerns only one globalMessage(add, message .. ' AVOND AAN: huiskamerverlichting wordt AAN gezet...')
all went OK!
Next try.

Code: Select all

return 
{
    data = 
    {
        myGlobalVar = { initial = 12 }
    },

    helpers = 
    {
        alertLidl = function(dz, action, period)
            local controlVar = dz.variables("controlVar")
            local value = controlVar.value
            if controlVar.value ~= action then
                controlVar.set(action) 
                if period then
                    controlVar.set(value).afterSec(period)
                    dz.log("alert requested; controlVar set to " .. action .. ". It will return to ".. value .. " after " .. period .. " seconds." ,dz.LOG_FORCE)
                else
                    dz.log("alert requested; controlVar set to " .. action  ,dz.LOG_FORCE)
                end
            else
                dz.log("No changed needed; controlVar is already set to " .. value,dz.LOG_DEBUG)
            end
    end,
    
    addMessage = 
        function(dz, item, info, message, messages)
            local trigger =  item.isDevice and (", Device: " .. item.name ) or (", Timer: " .. item.trigger)
            messages[#messages + 1] = {}
            messages[#messages].log  = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
            messages[#messages].text = dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' : ' .. message 
            return messages
		end,
    
    dumpMessages = 
        function(dz, messages)
            local maxLines = 8                               -- user configurable 
            local dashticz = true                            -- true or false
            local textDevice = dz.devices('timerlog')        -- user configurable 
    
            local currentText = textDevice.text
            local newText = currentText
            local lf = "\r\n"
            local dashticzLF = "<br>"
            

            
            for i, record in ipairs(messages) do
                dz.log(record.log, dz.LOG_INFO)
                lf = dahshticz and (lf .. dashticzLF) or lf
                newText = record.text .. lf .. newText
            end
            
            dz.log(newText, dz.LOG_INFO)
            
            if newText ~= currentText then
                lines = dz.utils.stringSplit(newText, lf)  -- create lines table from newText string
                newText = table.concat(lines,lf, 1, (math.min(maxLines,#lines))) -- recreate newText string from first maxLines 
                textDevice.updateText(newText) 
            end    
    	end,
       
    }
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Re: need a loop for reading messages for logging

Post by pvklink »

Got it working!
I added a <br>, does that makes sence ?

messages[#messages].text = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. message .. '<br>'

Code: Select all

return 
{
    data = 
    {
        myGlobalVar = { initial = 12 }
    },

    helpers = 
    {
        alertLidl = function(dz, action, period)
            local controlVar = dz.variables("controlVar")
            local value = controlVar.value
            if controlVar.value ~= action then
                controlVar.set(action) 
                if period then
                    controlVar.set(value).afterSec(period)
                    dz.log("alert requested; controlVar set to " .. action .. ". It will return to ".. value .. " after " .. period .. " seconds." ,dz.LOG_FORCE)
                else
                    dz.log("alert requested; controlVar set to " .. action  ,dz.LOG_FORCE)
                end
            else
                dz.log("No changed needed; controlVar is already set to " .. value,dz.LOG_DEBUG)
            end
    end,
    
    addMessage = 
        function(dz, item, info, message, messages)
            local trigger =  item.isDevice and (", Device: " .. item.name ) or (", Timer: " .. item.trigger)
            messages[#messages + 1] = {}
            messages[#messages].log  = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
            --messages[#messages].text = dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' : ' .. message -- deze werkt met local if <br> en lines en newText disablen
            messages[#messages].text = dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' : ' .. message .. '<br>'
            return messages
        end,
    
    dumpMessages = 
        function(dz, messages)
            local textDevice = dz.devices('timerlog')
            local currentText = textDevice.text
            local newText = currentText
	    --local lf = '<br>'
            --local lf = "\n"
            local lf = "\r\n"
            local maxLines = 8
            
            for i, record in ipairs(messages) do
                dz.log(record.log, dz.LOG_INFO) 
                newText = record.text .. lf .. newText
            end
            
            dz.log(newText, dz.LOG_INFO)
            
            if newText ~= currentText then
                lines = dz.utils.stringSplit(newText, lf)  -- create lines table from newText string
                newText = table.concat(lines, lf, 1, (math.min(maxLines,#lines))) -- recreate newText string from first maxLines 
                textDevice.updateText(newText) 
            end    
        end,       
    }
}
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Re: need a loop for reading messages for logging

Post by pvklink »

ok, that did not work even... my domoticz textfield gets extra linefeeds....

I have one config that both domoticz and dashticz are ok:
It works, so no need for digging :-)

I have still two other issues:
one is releated to this log functionality.
When my script logs with ADD messages and calls another script with the same add messages calls, i loose some info....
looks difficult to solve that! a script can add more then one logs and write onetime and calls another script that also has more logs and also writes onetime. Logging must work in comination and seperate...

other is a new topic and more an advise how to split my script in parts
I will post it after my son is ready (needs my pc for exams..)

working global_data:

Code: Select all

return 
{
    data = 
    {
        myGlobalVar = { initial = 12 }
    },

    helpers = 
    {
        alertLidl = function(dz, action, period)
            local controlVar = dz.variables("controlVar")
            local value = controlVar.value
            if controlVar.value ~= action then
                controlVar.set(action) 
                if period then
                    controlVar.set(value).afterSec(period)
                    dz.log("alert requested; controlVar set to " .. action .. ". It will return to ".. value .. " after " .. period .. " seconds." ,dz.LOG_FORCE)
                else
                    dz.log("alert requested; controlVar set to " .. action  ,dz.LOG_FORCE)
                end
            else
                dz.log("No changed needed; controlVar is already set to " .. value,dz.LOG_DEBUG)
            end
    end,
    
    addMessage = 
        function(dz, item, info, message, messages)
            local trigger =  item.isDevice and (", Device: " .. item.name ) or (", Timer: " .. item.trigger)
            messages[#messages + 1] = {}
            messages[#messages].log  = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
            messages[#messages].text = dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' : ' .. message 
            --messages[#messages].text = dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' : ' .. message .. '<br>'
            return messages
        end,
    
    dumpMessages = 
        function(dz, messages)
            local textDevice = dz.devices('timerlog')
            local currentText = textDevice.text
            local newText = currentText
	    local lf = '<br>'
            --local lf = "\n"
            --local lf = "\r\n"
            local maxLines = 8
            
            for i, record in ipairs(messages) do
                dz.log(record.log, dz.LOG_INFO) 
                newText = record.text .. lf .. newText
            end
            
            dz.log(newText, dz.LOG_INFO)
            
            if newText ~= currentText then
                --lines = dz.utils.stringSplit(newText, lf)  -- create lines table from newText string
                --newText = table.concat(lines, lf, 1, (math.min(maxLines,#lines))) -- recreate newText string from first maxLines 
                textDevice.updateText(newText) 
            end    
        end,       
    }
}
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Re: need a loop for reading messages for logging

Post by pvklink »

Logging works OK!
I am rewriting all my scripts to use this..

Only with ifttt control var script i cant find why it is missing a value!
i renamed action to actionx because ifttt and globalmessage uses action

I think that it has something to do with global_data
local trigger = item.isDevice and (", Device: " .. item.name ) or (", Timer: " .. item.trigger)
iftttvar i not a device or timer..


2019-07-03 10:08:06.001 Error: dzVents: Error: (2.4.24) ifttt: An error occurred when calling event handler DZ_ifttt
2019-07-03 10:08:06.001 Error: dzVents: Error: (2.4.24) ifttt: /home/pi/domoticz/scripts/dzVents/scripts/global_data.lua:28: attempt to concatenate field 'trigger' (a nil value)

Code: Select all

local iftttvar = "iftttvar"  

return 
{
    on =    
    { variables = { iftttvar },   
    },
                    
    logging =
    {   
        level = domoticz.LOG_DEBUG,
        marker = 'ifttt',
   },

    execute = function(dz, item, info)
        local validBaseTypes = { device=true, group=true, scene=true, uservariable=false, camera=false }
        local validActions = { ON=true, OFF=true }
        result = dz.utils.stringSplit(item.value,'/')
        local name = result[1]
        local action = string.upper(result[2])
        local parm1 = result[3]
        local stype = result[4]

    local messageTable = {}
    local add = 'add'
        
    local function globalMessage(actionx, message )
        if actionx == add then
            messageTable = dz.helpers.addMessage(dz, item, info, message, messageTable )
        else
            dz.helpers.dumpMessages(dz, messageTable)
        end
    end

        if parm1 == nil then parm1 = 'undefined' end -- par1 is de selectornaam of selectorlevel
        if stype == nil then stype = 'undefined' end -- stype is of par naam 1 of level is 2

        local function getBaseType(name)
            for i, tuple in ipairs(_G.domoticzData) do 
                if tuple.name == name then 
                    return tuple.baseType, tuple.id 
                end
            end
        end
        
        local baseType, idx = getBaseType(name)
        if baseType and validBaseTypes[baseType] then
            local target 
            if baseType == 'device' then 
                target = dz.devices(name)
            elseif baseType == 'group' then 
                target = dz.groups(name)
            elseif baseType == 'scene' then 
                target = dz.scenes(name) 
                validActions.OFF = nil -- No Off action for scenes
            end
            if validActions[action] then
                if action == 'ON' then 
                    if parm1 ~= 'undefined' then
                        if stype == '1' or stype == 'undefined' then
                            globalMessage(add, ' IFTTT AAN: ,settings: ' .. item.value)
                            target.switchSelector(parm1) --parm selector_name 
                        elseif stype == '2' then
                            globalMessage(add, ' IFTTT AAN: ,settings: ' .. item.value)
                            target.switchSelector(tonumber(parm1)) --parm selector_id
                        else -- foute waarde
                            globalMessage(add, ' IFTTT AAN: ,foute waarde: settings: ' .. item.value)
                        end
                    else
                        globalMessage(add, ' IFTTT AAN: ,settings: ' .. item.value)
                        target.switchOn() 
                    end
                elseif action == 'OFF' then 
                    globalMessage(add, ' IFTTT AAN: ,settings: ' .. item.value )
                    target.switchOff() 
                else -- no other actions implemented yet
                    globalMessage(add, ' IFTTT AAN: ,foute action waarde: settings: ' .. action) 
                end
            else 
                globalMessage(add, ' IFTTT AAN: , action: '  .. action .. ' is not implemented for '  .. baseType .. ' Name ' .. name .. '!')

            end
        elseif baseType then
            globalMessage(add, ' IFTTT AAN: , onbekende basetype: ' .. baseType)    --  dz.LOG_ERROR evt ook doorgeven 

        else
            globalMessage(add, ' IFTTT AAN: , name not found!: ' .. name )

        end

        globalMessage() -- dump

    end
}



Code: Select all

return 
{
    data = 
    {
        myGlobalVar = { initial = 12 }
    },

    helpers = 
    {
        alertLidl = function(dz, action, period)
            local controlVar = dz.variables("controlVar")
            local value = controlVar.value
            if controlVar.value ~= action then
                controlVar.set(action) 
                if period then
                    controlVar.set(value).afterSec(period)
                    dz.log("alert requested; controlVar set to " .. action .. ". It will return to ".. value .. " after " .. period .. " seconds." ,dz.LOG_FORCE)
                else
                    dz.log("alert requested; controlVar set to " .. action  ,dz.LOG_FORCE)
                end
            else
                dz.log("No changed needed; controlVar is already set to " .. value,dz.LOG_DEBUG)
            end
    end,
    
    addMessage = 
        function(dz, item, info, message, messages)
            local trigger =  item.isDevice and (", Device: " .. item.name ) or (", Timer: " .. item.trigger)
            messages[#messages + 1] = {}
            messages[#messages].log  = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
            messages[#messages].text = dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' : ' .. message 
            --messages[#messages].text = dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' : ' .. message .. '<br>'
            return messages
        end,
    
    dumpMessages = 
        function(dz, messages)
            local textDevice = dz.devices('timerlog')
            local currentText = textDevice.text
            local newText = currentText
	    local lf = '<br>'
            --local lf = "\n"
            --local lf = "\r\n"
            local maxLines = 8
            
            for i, record in ipairs(messages) do
                dz.log(record.log, dz.LOG_INFO) 
                newText = record.text .. lf .. newText
            end
            
            dz.log(newText, dz.LOG_INFO)
            
            if newText ~= currentText then
                --lines = dz.utils.stringSplit(newText, lf)  -- create lines table from newText string
                --newText = table.concat(lines, lf, 1, (math.min(maxLines,#lines))) -- recreate newText string from first maxLines 
                textDevice.updateText(newText) 
            end    
        end,       
    }
}
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: need a loop for reading messages for logging

Post by waaren »

pvklink wrote: Wednesday 03 July 2019 10:14 Only with ifttt control var script i cant find why it is missing a value!
I think that it has something to do with global_data
local trigger = item.isDevice and (", Device: " .. item.name ) or (", Timer: " .. item.trigger)
iftttvar i not a device or timer..
Yes, that is indeed why you see the error. Try and replace that part of global data with

Code: Select all

addMessage = 
        function(dz, item, info, message, messages)
            local trigger  
            if item.isDevice then trigger = ", Device: " .. item.name
            elseif item.isTimer then trigger = ", Timer: " .. item.trigger 
            elseif item.isVariable then trigger = ", Variable: " .. item.name 
            else trigger = ", Unknown trigger"
            end    
            messages[#messages + 1] = {}
            messages[#messages].log  = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
            messages[#messages].text = dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' : ' .. message 
            --messages[#messages].text = dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' : ' .. message .. '<br>'
            return messages
        end,
    
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Re: need a loop for reading messages for logging

Post by pvklink »

Yessssssssss, IFTTT now also works with the new logging...

Also made a script with a command to clean the log..

dz.devices('timerlog').updateText(dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' :' .. ' TIMERLOG CLEAN: timerlog wordt geschoond...')

Or is it better to place this in your helper function ?

local function globalMessage(action, message )
if action == add then
messageTable = dz.helpers.addMessage(dz, item, info, message, messageTable )
elseif action == del then
dz.devices('timerlog').updateText(message)
else
dz.helpers.dumpMessages(dz, messageTable)
end
end

or even in the global_data ?

logging looks great!

looks great!
Naamloos.png
Naamloos.png (57.93 KiB) Viewed 1248 times
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Nested script, messages lost

Post by pvklink »

Last problem, is a hard one.
I have nested scripts an both scripts uses the globamessages at their own and in combination.
When this test scripts calls the usb lamp, only the usb lamps logs are shown not 0-1-2 from the testscript and when i remark the usb lamp, i do get the 0-1-2 from the testscript/

I thought this was easy to fix by adding extra globalMessage() -- dump before calling the nested script so all the current logs where written...
but no !

Code: Select all

return {
    on = { devices = { 'test' }},
    
    execute = function(dz, item, info)

    local messageTable = {}
    local add = 'add'
        
    local function globalMessage(action, message )
        if action == add then
            messageTable = dz.helpers.addMessage(dz, item, info, message, messageTable )
        else
            dz.helpers.dumpMessages(dz, messageTable)
        end
    end        -- dz.devices('timerlog').updateText(dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' : leeg')

        globalMessage(add, ' test 0 voor usb')

        --globalMessage() -- dump
    
        dz.devices('usb lamp').switchSelector(40)   -- the script for usb lamp also writes to the log !!!when is is not remarked out the other logs are not visible
        --dz.devices('Bewegingsservice').switchOff()
        
        globalMessage(add, ' test 1 na usb')
        globalMessage(add, ' test 2 na usb')

        globalMessage() -- dump

end
}

}
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Re: need a loop for reading messages for logging

Post by pvklink »

A temporary solution for the nested scripts is to set some logging off
logcode 0 message rule not written, 1 = dom log, 2 txtbox log, 3 =all written
dont now if this is the way to do it....

global_data

Code: Select all

addMessage = 
        function(dz, item, info, message, messages, logcode)
	-- logcode 0=no message written, 1= message domoticz log written, 2 =message = textbox, 3= all written
	-- what if logcode nil is, then default = 3
	if logcode > 0 then
	            local trigger  
	            if item.isDevice then 
		trigger = ", Device: " .. item.name
	            elseif item.isTimer then 
		trigger = ", Timer: " .. item.trigger 
	            elseif item.isVariable then 
		trigger = ", Variable: " .. item.name 
	            else trigger = ", Unknown trigger"
	            end    
	            messages[#messages + 1] = {}
		if logcode =1 or logcode = 3 then
		            messages[#messages].log  = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
		if logcode =2 or logcode = 3 then
		            messages[#messages].text = dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' : ' .. message 
		            --messages[#messages].text = dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' : ' .. message .. '<br>'
		end
	end 
           return messages
        end,
    
    dumpMessages = 
        function(dz, messages)
            local textDevice = dz.devices('timerlog')
            local currentText = textDevice.text
            local newText = currentText
	    local lf = '<br>'
            --local lf = "\n"
            --local lf = "\r\n"
            local maxLines = 8
            
            for i, record in ipairs(messages) do
                dz.log(record.log, dz.LOG_INFO) 
                newText = record.text .. lf .. newText
            end
            
            dz.log(newText, dz.LOG_INFO)
            
            if newText ~= currentText then
                --lines = dz.utils.stringSplit(newText, lf)  -- create lines table from newText string
                --newText = table.concat(lines, lf, 1, (math.min(maxLines,#lines))) -- recreate newText string from first maxLines 
                textDevice.updateText(newText) 
            end    
        end,       
example test to see if loglevels working

Code: Select all

return {
    on = { devices = { 'test' }},
    
    execute = function(dz, item, info)

    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.devices('timerlog').updateText(message)
        elseif action == chg then 
            dz.helpers.dumpMessages(dz, messageTable)
        end
 
    end

        --globalMessage(del, 'nu verwijderen') -- delete
        
        globalMessage(add, ' test 0 voor usb',0)

--        globalMessage() -- dump
    
        --dz.devices('usb lamp').switchSelector(40)   -- the script for usb lamp also writes to the log !!!when is is not remarked out the other logs are not visible
        --dz.devices('Bewegingsservice').switchOff()
        
        globalMessage(add, ' test 1 na usb',0)
        globalMessage(add, ' test 2 na usb',0)
        globalMessage(add, ' test 3 na usb',0)
        globalMessage(add, ' test 4 na usb',0)
        globalMessage(add, ' test 5 na usb',logcode)

        globalMessage(chg) -- dump
            
end
}
Last edited by pvklink on Thursday 04 July 2019 15:25, edited 1 time in total.
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Nested script, messages lost

Post by waaren »

pvklink wrote: Thursday 04 July 2019 10:03 Last problem, is a hard one.
I have nested scripts an both scripts uses the globamessages at their own and in combination.
There is no such thing as nested scripts in the domoticz Eventsystem.
The Eventsystem is single threaded meaning that a script needs to be finished before a next script can start.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Re: need a loop for reading messages for logging

Post by pvklink »

mmm,strange my testscript writes log messages ok when activate test and disabling the usb lamp that is calling its own script also with log messages...
but when enabling the usb lamp in the test script, the test logs get lost and only the usb lamp one appear
see the test script above...
Last edited by pvklink on Thursday 04 July 2019 16:13, edited 1 time in total.
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: need a loop for reading messages for logging

Post by waaren »

pvklink wrote: Thursday 04 July 2019 15:37 mmm,strange my testscript writes log messages ok when activate test and disabling the usb lamp that is calling its own script also with log messages...
see the test script above...
Probably because they both use the same domoticz object so there 'currenttext' is the same for both. A way to prevent this type of conflict is to get 'currenttext' from a variable in global data and not from the text device.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Re: need a loop for reading messages for logging

Post by pvklink »

Got it working! THANKS again @WAAREN
The usb logging is showing up now!
Strange thing is that the USB logs are logged later!

1. is this a good way to add the delete function ? it is working...
2. do i need the dz parameter in
globalMessage(dz,del, dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' :' .. ' TIMERLOG CLEAN: timerlog wordt geschoond...') -- delete
3. last thing is to add logcode 1,2,3 to addMessage to 1= log domoticz.log, 2= log global, 3 log both

then time for a holiday and no more scripting. I can check remote (via logs) if everything works ok!
Naamloos.png
Naamloos.png (40.86 KiB) Viewed 1225 times
my test script

Code: Select all

return {
    on = { devices = { 'test' }},
    
    execute = function(dz, item, info)

    local logcode = 3
    local messageTable = {}
    local add = 'add'
    local del = 'del'
    local chg = 'chg'
        
    local function globalMessage(dz, 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

        --globalMessage(dz,del, dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' :' .. ' TIMERLOG CLEAN: timerlog wordt geschoond...') -- delete
        globalMessage(dz,del, dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' :' .. ' TIMERLOG CLEAN: timerlog wordt geschoond...' .. '<br>') -- delete
        
        globalMessage(dz,add, ' test 0 voor usb',1)
        globalMessage(dz,add, ' test 1 voor usb',1)

        dz.devices('usb lamp').switchSelector(40)   -- the script for usb lamp also writes to the log !!!when is is not remarked out the other logs are not visible
        --dz.devices('Bewegingsservice').switchOff()
        
        globalMessage(dz,add, ' test 2 na usb',0)
        globalMessage(dz,add, ' test 3 na usb',0)
        globalMessage(dz,add, ' test 4 na usb',3)
        globalMessage(dz,add, ' test 5 na usb',0)
        globalMessage(dz,add, ' test 6 na usb',logcode)

        globalMessage(dz,chg) -- dump
            
end
}
my global_data.lua

Code: Select all

return 
{
    data = 
    {
        myGlobalVar = { initial = 12 },
        mylogging = {initial = 'Eerst aanmaak van global variable mylogging in global_data.lua'},
    },

    helpers = 
    {
        alertLidl = function(dz, action, period)
            local controlVar = dz.variables("controlVar")
            local value = controlVar.value
            if controlVar.value ~= action then
                controlVar.set(action) 
                if period then
                    controlVar.set(value).afterSec(period)
                    dz.log("alert requested; controlVar set to " .. action .. ". It will return to ".. value .. " after " .. period .. " seconds." ,dz.LOG_FORCE)
                else
                    dz.log("alert requested; controlVar set to " .. action  ,dz.LOG_FORCE)
                end
            else
                dz.log("No changed needed; controlVar is already set to " .. value,dz.LOG_DEBUG)
            end
    end,
    
    addMessage = 
        function(dz, item, info, message, messages)
            local trigger  
            if item.isDevice then 
		trigger = ", Device: " .. item.name
            elseif item.isTimer then 
		trigger = ", Timer: " .. item.trigger 
            elseif item.isVariable then 
		trigger = ", Variable: " .. item.name 
            else trigger = ", Unknown trigger"
            end    
            messages[#messages + 1] = {}
            messages[#messages].log  = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
            messages[#messages].text = dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' : ' .. message 
            return messages
        end,
    
    dumpMessages = 
        function(dz, messages)
            local textDevice = dz.devices('timerlog')
	    local currentText = dz.globalData.mylogging
            local newText = currentText
	    local lf = '<br>'					--local lf = "\n" 	--local lf = "\r\n"	--PVK \n of \r\n UITGEZET ANDERS werkt dashticz niet
            local maxLines = 8
            
            for i, record in ipairs(messages) do
                dz.log(record.log, dz.LOG_INFO) 
                newText = record.text .. lf .. newText
            end
            
            dz.log(newText, dz.LOG_INFO)
            
            if newText ~= currentText then
                --lines = dz.utils.stringSplit(newText, lf)  -- create lines table from newText string						--PVK UITGEZET ANDERS werkt dashticz niet
                --newText = table.concat(lines, lf, 1, (math.min(maxLines,#lines))) -- recreate newText string from first maxLines 		--PVK UITGEZET ANDERS werkt dashticz niet
                textDevice.updateText(newText) 
		dz.globalData.mylogging = newText  -- ADDED

            end    
        end,       
    }
}
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: need a loop for reading messages for logging

Post by waaren »

pvklink wrote: Thursday 04 July 2019 18:21 2. do i need the dz parameter in
No. You don't need it.
don't forget to remove it from both the calls to the function and from the function declaration.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Re: need a loop for reading messages for logging

Post by pvklink »

Works!
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Re: need a loop for reading messages for logging

Post by pvklink »

Busy with the last part.

want to call the logfunctie with the logcode: 0 no log, 1 = domoticz log, 2 = global var log, 3 = all
0 and 3 works ok!

globalMessage(add, ' BASISVOORZIENING AAN: ...',1)

this is the function:

Code: Select all

    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
logcode = 0 is working ok.
When using logcode 1 (only domoticz) i get:

Code: Select all

019-07-06 13:53:05.460 (zwavepluspvk) Light/Switch (printer)
2019-07-06 13:53:05.416 Error: dzVents: Error: (2.4.24) Timers: An error occurred when calling event handler DZ_schakelgroepen
2019-07-06 13:53:05.416 Error: dzVents: Error: (2.4.24) Timers: /home/pi/domoticz/scripts/dzVents/scripts/global_data.lua:58: attempt to concatenate field 'text' (a nil value)
this is my global_data.lua

Code: Select all

return 
{
    data = 
    {
        myGlobalVar = { initial = 12 },
        mylogging = {initial = 'Eerst aanmaak van global variable mylogging in global_data.lua'},
    },

    helpers = 
    {
        alertLidl = function(dz, action, period)
            local controlVar = dz.variables("controlVar")
            local value = controlVar.value
            if controlVar.value ~= action then
                controlVar.set(action) 
                if period then
                    controlVar.set(value).afterSec(period)
                    dz.log("alert requested; controlVar set to " .. action .. ". It will return to ".. value .. " after " .. period .. " seconds." ,dz.LOG_FORCE)
                else
                    dz.log("alert requested; controlVar set to " .. action  ,dz.LOG_FORCE)
                end
            else
                dz.log("No changed needed; controlVar is already set to " .. value,dz.LOG_DEBUG)
            end
    end,
    
    addMessage = 
        function(dz, item, info, message, messages,logcode)
            local trigger  
            if item.isDevice then 
		trigger = ", Device: " .. item.name
            elseif item.isTimer then 
		trigger = ", Timer: " .. item.trigger 
            elseif item.isVariable then 
		trigger = ", Variable: " .. item.name 
            else trigger = ", Unknown trigger"
            end    
            messages[#messages + 1] = {}
	    if logcode == 1 or logcode == 3 then
        	    messages[#messages].log  = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
	    end
	    if logcode >= 2 then
	            messages[#messages].text = dz.time.rawDate .. '  ' .. dz.time.rawTime .. ' : ' .. message 
	    end
            return messages
        end,
    
    dumpMessages = 
        function(dz, messages)
            local textDevice = dz.devices('timerlog')
	    local currentText = dz.globalData.mylogging
            local newText = currentText
	    local lf = '<br>'					--local lf = "\n" 	--local lf = "\r\n"	--PVK \n of \r\n UITGEZET ANDERS werkt dashticz niet
            local maxLines = 8
            
            for i, record in ipairs(messages) do
                dz.log(record.log, dz.LOG_INFO) 
                newText = record.text .. lf .. newText
            end
            
            dz.log(newText, dz.LOG_INFO)
            
            if newText ~= currentText then
                --lines = dz.utils.stringSplit(newText, lf)  -- create lines table from newText string						--PVK UITGEZET ANDERS werkt dashticz niet
                --newText = table.concat(lines, lf, 1, (math.min(maxLines,#lines))) -- recreate newText string from first maxLines 		--PVK UITGEZET ANDERS werkt dashticz niet
                textDevice.updateText(newText) 
		dz.globalData.mylogging = newText  -- ADDED

            end    
        end,       
    }
}
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: need a loop for reading messages for logging

Post by waaren »

pvklink wrote: Saturday 06 July 2019 14:01 globalMessage(add, ' BASISVOORZIENING AAN: ...',1)
2019-07-06 13:53:05.416 Error: dzVents: Error: (2.4.24) Timers: /home/pi/domoticz/scripts/dzVents/scripts/global_data.lua:58: attempt to concatenate field 'text' (a nil value)
When using the parm 1, you don't enter anything in the text field of the messages record in function addMessage but in function dumpMessages you still expect something to be there. dzVents (Lua) is quite powerful but without a wand it cannot perform magic :D

Just curious why you would want to use these functions if you only want to send something to the logfile.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
pvklink
Posts: 822
Joined: Wednesday 12 November 2014 15:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest b
Contact:

Re: need a loop for reading messages for logging

Post by pvklink »

i have lot of devices (100) and lot of scripts and i am rewriting them all in dzvents, 99% is working but can be organized better...
so no more groups, triggers timers in domoticz, all in dzvents :-)
So i have made a lot of checkpoints where i write to the logs when testing my script.
I write to domoticz (but that has a lot of entries and hard to search and i have my own log with the most important entries, events etc.

Some events i want to see in domoticz, some in my log and sometime when scripts are not working ok, i changes these logrules from ,0 to ,3 to see what is going wrong..

I am very happy with it and it works ok!
i understand the problem with value 1 and 2 now...when only write to domoticz and not to global i dont get something back...
so my local logging function has to split domoticz and global logging in two executing parts...?
Raspberry (raspbian on rpi 3) , Domoticz Beta, dzVents , RFXtrx433e, P1, Hue, Yeelight, Zwave+, X10, ESP(easy), MQTT,Weather Underground, System Alive Checker, Domoticz Remote Server to RPI with Google Assistant,
Jablotron connection, Ikea
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest