question regarding device.changed  [Solved]

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

Moderator: leecollings

Post Reply
Gravityz
Posts: 652
Joined: Wednesday 16 December 2015 19:13
Target OS: NAS (Synology & others)
Domoticz version: 2025.1
Location: Netherlands
Contact:

question regarding device.changed

Post by Gravityz »

Hello,

i need to theck on a device to see if it has changed.

i currently have a script which is triggered by a device.

so if the device goes from OFF to ON it triggers the script but also when going from ON to OFF

The problem however is that this script is also trigggered when the device goes from ON to ON (device is triggered from another script but it was already on)

so i either need to chreck it's previous state(and i do not want to use anotrher virtual switch

Question: will device. changed work for this?

Eg, will this ony be set to true if the device goes from ON to OFF and OFF to ON (the device has changed) but will it be false when it goes from ON to ON or OFF to OFF(the device is triggered but the state has not changed)

.checkFirst will not work in my case because i have also other devices which need to react on this change
thanks
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: question regarding device.changed

Post by waaren »

Gravityz wrote: Saturday 27 April 2019 19:10 So i either need to chreck it's previous state(and i do not want to use anotrher virtual switch
Question: will device. changed work for this?
No
Eg, will this only be set to true if the device goes from ON to OFF and OFF to ON (the device has changed) but will it be false when it goes from ON to ON or OFF to OFF(the device is triggered but the state has not changed)

To do this you will have to safe previous state somewhere. My preference would be to do this using a dzVents persistent variable like.

Code: Select all

return {
            on =    {
                      devices = { 1886 },
                    },
    
    data =  { 
                lastState = { initial = "" }
            },
    
    execute = function(dz, item)
        if item.state ~= dz.data.lastState then
            print("device " .. item.name .. " has changed state to " .. item.state)
            dz.data.lastState = item.state
        else
            print("device " ..  item.name .. " has kept state " .. item.state)
        end
    end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Gravityz
Posts: 652
Joined: Wednesday 16 December 2015 19:13
Target OS: NAS (Synology & others)
Domoticz version: 2025.1
Location: Netherlands
Contact:

Re: question regarding device.changed

Post by Gravityz »

thanks, will try it.

at first i wanted to skip double on messages only but it might be better to skip double messages totally.


will this work? especially the " if (checkParms() and LastStatus ~= Line) "

-- this scripts holds all the globally persistent variables and helper functions
-- see the documentation in the wiki
-- NOTE:
-- THERE CAN BE ONLY ONE global_data SCRIPT in your Domoticz install.

return {
-- global persistent data
data = {
LastStatus = { initial = "" }
},

-- global helper functions
helpers = {
addRollingTextLine = function(domoticz, textDevice, line, maxLines)
-- code
local time=domoticz.time.rawTime
time=time..' -- '
local function stringSplit(str)
local lines = {}
for s in str:gmatch("[^\r\n]+") do
table.insert(lines, s)
end
return lines
end

local function checkParms()
if not textDevice or ( type(textDevice) ~= "string" and type(textDevice) ~= "table" ) then
domoticz.log("textDevice should be of type table or string; now: " .. (tostring(textDevice) or type(textDevice)),domoticz.LOG_ERROR)
return false
elseif type(textDevice) == "string" then
textDevice = domoticz.devices(textDevice)
end
if not line then
domoticz.log("No text supplied",domoticz.LOG_ERROR)
return false
end
if not maxLines then maxLines = 5 end -- default
return true
end

if (checkParms() and LastStatus ~= Line) then
local lines = textDevice.text or ""
lines = stringSplit(lines)
line=time..line
lines[0] = line
local newText = ""
for i = 0, ( maxLines - 1) do
newText = newText .. ( lines or "" ) .. "\r\n"
end
textDevice.updateText(newText)
LastStatus = Line
else
return false
end
end
}
}
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: question regarding device.changed

Post by waaren »

Gravityz wrote: Sunday 28 April 2019 9:33 at first i wanted to skip double on messages only but it might be better to skip double messages totally.
will this work? especially the " if (checkParms() and LastStatus ~= Line) "
I don't understand what you ask in relation to the topic.
And please use code tags when posting code.

You can "tag" your code by typing
code.png
code.png (783 Bytes) Viewed 2769 times
around your code. (use the </> button in the forum editor
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Gravityz
Posts: 652
Joined: Wednesday 16 December 2015 19:13
Target OS: NAS (Synology & others)
Domoticz version: 2025.1
Location: Netherlands
Contact:

Re: question regarding device.changed

Post by Gravityz »

My mistake.

thought i used code but i used text !!!!

question is simple.

will this check work

checkparms() (which is a function) will return TRUE or FALSE
LastStatus ~= Line (which both are strings) will return TRUE or FALSE

but i do not know if i can combine the outcome of a function with a compare


Code: Select all

if (checkParms() and LastStatus ~= Line) then
here is the complete code

Code: Select all

-- this scripts holds all the globally persistent variables and helper functions
-- see the documentation in the wiki
-- NOTE:
-- THERE CAN BE ONLY ONE global_data SCRIPT in your Domoticz install.

    return {
	-- global persistent data
    data = {
	    LastStatus = { initial = "" }
	},

	-- global helper functions
	helpers = {
		addRollingTextLine = function(domoticz, textDevice, line, maxLines)
			-- code
			    local time=domoticz.time.rawTime
                time=time..' -- '
		    local function stringSplit(str)
                local lines = {}
                for s in str:gmatch("[^\r\n]+") do
                    table.insert(lines, s)
                end
                return lines
            end
            
            local function checkParms()
                if not textDevice or ( type(textDevice) ~= "string" and type(textDevice) ~= "table" ) then
                    domoticz.log("textDevice should be of type table or string; now: " .. (tostring(textDevice) or type(textDevice)),domoticz.LOG_ERROR)
                    return false
                elseif type(textDevice) == "string" then 
                    textDevice = domoticz.devices(textDevice) 
                end    
                if not line then
                    domoticz.log("No text supplied",domoticz.LOG_ERROR)
                    return false
                end
                if not maxLines then maxLines = 5 end          -- default
                return true
            end
                
            if (checkParms() and LastStatus ~= Line) then
                local lines = textDevice.text or ""
                lines = stringSplit(lines)
                line=time..line
                lines[0] = line
                local newText = ""
                for i = 0, ( maxLines - 1) do 
                    newText = newText ..  ( lines[i] or "" ) .. "\r\n" 
                end
                textDevice.updateText(newText)
                LastStatus = Line
            else
                return false
            end
    end 
		}
}
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: question regarding device.changed  [Solved]

Post by waaren »

Gravityz wrote: Sunday 28 April 2019 12:28 question is simple. will this check work

checkparms() (which is a function) will return TRUE or FALSE
LastStatus ~= Line (which both are strings) will return TRUE or FALSE

but i do not know if i can combine the outcome of a function with a compare
Yes that is possible. If the function returns anything different then false or nil it will be considered true.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Gravityz
Posts: 652
Joined: Wednesday 16 December 2015 19:13
Target OS: NAS (Synology & others)
Domoticz version: 2025.1
Location: Netherlands
Contact:

Re: question regarding device.changed

Post by Gravityz »

thanks
Gravityz
Posts: 652
Joined: Wednesday 16 December 2015 19:13
Target OS: NAS (Synology & others)
Domoticz version: 2025.1
Location: Netherlands
Contact:

Re: question regarding device.changed

Post by Gravityz »

Hmmmmmm

still not working.

it seems that the LastStatus string can not be compared with the line string.

if i simply do

Code: Select all

if LastStatus ~= line then
it does not seem to work

i printed out both strings in the log and they look exactly the same

could it be that the variables are somehow not the same type (string) and therefor can not be compared
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: question regarding device.changed

Post by waaren »

Gravityz wrote: Monday 29 April 2019 19:38 it seems that the LastStatus string can not be compared with the line string.
could it be that the variables are somehow not the same type (string) and therefor can not be compared
Not if the print looks the same.

Can you please share your complete script and global_data.lua. If you do not want to do this here then via PM is also OK
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Gravityz
Posts: 652
Joined: Wednesday 16 December 2015 19:13
Target OS: NAS (Synology & others)
Domoticz version: 2025.1
Location: Netherlands
Contact:

Re: question regarding device.changed

Post by Gravityz »

lux script which call global_data helper function but the idea is that if global_data helper gets passed with a string which is the same as the previous one it will not update/rotate the text device.

Code: Select all

return {
    active = true,
    on = {
        timer = {
            'Every 5 minutes between 50 minutes before sunset and sunset'
        }
    },
    execute = function(domoticz, device)
        if (domoticz.devices('Lux woonkamer').lux  < 17 and domoticz.devices('Woonkamer schedule').state == 'Off') then
            local results = domoticz.helpers.addRollingTextLine(domoticz, 'Status', 'Het is donker, lampen eerder aan', '5')
            domoticz.devices('Woonkamer schedule').switchOn()
           end
    end
}
so a look at the global_data script should give an idea what is going wrong.
it should work but it is not.

i tried several ways to compare LastStatus with line but they all fail

i have multiple scripts calling the global_data helper but they all parse the data the same way.

global_data

Code: Select all

-- this scripts holds all the globally persistent variables and helper functions
-- see the documentation in the wiki
-- NOTE:
-- THERE CAN BE ONLY ONE global_data SCRIPT in your Domoticz install.

    return {
	-- global persistent data
    data = {
	    'LastStatus'
	},

	-- global helper functions
	helpers = {
		addRollingTextLine = function(domoticz, textDevice, line, maxLines)
			-- code
			    local time=domoticz.time.rawTime
                time=time..' -- '
		    local function stringSplit(str)
                local lines = {}
                for s in str:gmatch("[^\r\n]+") do
                    table.insert(lines, s)
                end
                return lines
            end
            
            local function checkParms()
                if not textDevice or ( type(textDevice) ~= "string" and type(textDevice) ~= "table" ) then
                    domoticz.log("textDevice should be of type table or string; now: " .. (tostring(textDevice) or type(textDevice)),domoticz.LOG_ERROR)
                    return false
                elseif type(textDevice) == "string" then 
                    textDevice = domoticz.devices(textDevice) 
                end    
                if not line then
                    domoticz.log("No text supplied",domoticz.LOG_ERROR)
                    return true
                end

                if not maxLines then maxLines = 5 end          -- default
                return true
            end
                
            if (checkParms() and LastStatus ~= line) then
                local lines = textDevice.text or ""
                lines = stringSplit(lines)
                LastStatus = line
                line=time..line
                lines[0] = line
                local newText = ""
                for i = 0, ( maxLines - 1) do 
                    newText = newText ..  ( lines[i] or "" ) .. "\r\n" 
                end
                textDevice.updateText(newText)
            else
                return false
            end
    end 
		}
}
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: question regarding device.changed

Post by waaren »

Gravityz wrote: Monday 29 April 2019 20:09 lux script which call global_data helper function but the idea is that if global_data helper gets passed with a string which is the same as the previous one it will not update/rotate the text device.
Can you please try with this global_data.lua ? I marked the changed lines with -- Changed

Code: Select all

-- this scripts holds all the globally persistent variables and helper functions
-- see the documentation in the wiki
-- NOTE:
-- THERE CAN BE ONLY ONE global_data SCRIPT in your Domoticz install.

    return {
	-- global persistent data
    
    data = { 
                LastStatus = { initial = "notset" },   -- Changed
           },

	-- global helper functions
	helpers = {
		addRollingTextLine = function(domoticz, textDevice, line, maxLines)
			-- code
			    local time=domoticz.time.rawTime
                time=time..' -- '
		    local function stringSplit(str)
                local lines = {}
                for s in str:gmatch("[^\r\n]+") do
                    table.insert(lines, s)
                end
                return lines
            end
            
            local function checkParms()
                if not textDevice or ( type(textDevice) ~= "string" and type(textDevice) ~= "table" ) then
                    domoticz.log("textDevice should be of type table or string; now: " .. (tostring(textDevice) or type(textDevice)),domoticz.LOG_ERROR)
                    return false
                elseif type(textDevice) == "string" then 
                    textDevice = domoticz.devices(textDevice) 
                end    
                if not line then
                    domoticz.log("No text supplied",domoticz.LOG_ERROR)
                    return true
                end

                if not maxLines then maxLines = 5 end          -- default
                return true
            end
                
            if (checkParms() and domoticz.globalData.LastStatus ~= line) then   -- Changed
                local lines = textDevice.text or ""
                lines = stringSplit(lines)
                domoticz.globalData.LastStatus = line   -- Changed
                line=time..line
                lines[0] = line
                local newText = ""
                for i = 0, ( maxLines - 1) do 
                    newText = newText ..  ( lines[i] or "" ) .. "\r\n" 
                end
                textDevice.updateText(newText)
            else
                return false
            end
    end 
    }
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Gravityz
Posts: 652
Joined: Wednesday 16 December 2015 19:13
Target OS: NAS (Synology & others)
Domoticz version: 2025.1
Location: Netherlands
Contact:

Re: question regarding device.changed

Post by Gravityz »

that seems to be working.
thanks, would not have figured this out myself

will let the script run for a day to see if it really does the job

does this mean that a global_data variable has to be used this way in every other script, including the global_data script it is declared in

seems strange, escpecially since the testing was done inside the global_data script and the variable printed from within the script seemed to hold the correct string.
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: question regarding device.changed

Post by waaren »

Gravityz wrote: Monday 29 April 2019 21:45 does this mean that a global_data variable has to be used this way in every other script, including the global_data script it is declared in
Yes
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Gravityz
Posts: 652
Joined: Wednesday 16 December 2015 19:13
Target OS: NAS (Synology & others)
Domoticz version: 2025.1
Location: Netherlands
Contact:

Re: question regarding device.changed

Post by Gravityz »

Thanks Waaren
tested it overnight and it works
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest