Page 1 of 1

get a global (or persistent)counter to work in dzVents-script

Posted: Wednesday 18 January 2023 12:41
by RonkA
This post is the is start of my quest: viewtopic.php?t=39611

For another layer of difficulty i want to add is, when i press a button i can cycle through other lines of text on my lcd2004 display.
With the help from openAI i got a script in dzVents that in theory does wat i want but when it runs it gives an error.
Resolving this problem is a bridge to far for the artificial intelligence, essencialy it gave up:
If none of these steps solve the issue, you might consider posting the log files and more details about your setup in a domoticz forum. They will be able to help you troubleshoot the issue more effectively.
I have asked openAI to try and use a global counter, persistent data, user variables but everytime it failed.
One of the problems i found that Domoticz uses dzVents 3.1.8, openAI uses version version 3.8xxx, from than on i asked openAI to use version 3.1.8 to make the scripts.
OpenAI tried at some point to make something but it could'nt get it to work in dzVents but remade it into LUA, id prefer dzVents for getting the values from some devices.

So here we are, is there a way to get a (global) counter that counts from 1 to 3 and than resets to 1 so a buttonpress is sending different texts the display everytime..(There are 3 different texts in this script.)

OpenAI last script gives the following error:
Error: EventSystem: in Script #2: [string "..."]:13: attempt to index a nil value (global 'domoticz')

Code: Select all

-- Create a global variable to store the counter
global = global or {}
global.counter = global.counter or 0

local value1 = 123
local value2 = 456
local value3 = 789

-- Get the switch device by name
local switch = domoticz.devices("Schakelaar op display2004")

-- Check if the switch is turned off
if switch.state == "Off" then
    -- Increment the counter
    if global.counter < 3 then
        global.counter = global.counter + 1
    else
        global.counter = 1
    end
    -- Check the value of the counter
    if global.counter == 1 then
        -- Log the message and open the URL
       -- domoticz.log('Buffervat bovenin: ' .. value3, domoticz.LOG_INFO)
        domoticz.openURL('http://192.168.178.220/control?cmd=lcd,1,1,Electrakosten%FE' .. value1 ..'EUR')
        domoticz.log('Waterkosten vandaag: ' .. value2, domoticz.LOG_INFO)
        domoticz.openURL('http://192.168.178.220/control?cmd=lcd,2,1,%FEkosten%FEwater%FE' .. value2 ..'EUR')
        domoticz.openURL('http://192.168.178.220/control?cmd=lcd,3,1,%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE')
    elseif global.counter == 2 then
        -- Log the message and open the URL 
        --domoticz.log('Buffervat bovenin: ' .. value3, domoticz.LOG_INFO)
        domoticz.openURL('http://192.168.178.220/control?cmd=lcd,1,1,%FE%FE%FE%FEbuffervat%FE' .. value3 ..'%DFC')
        domoticz.openURL('http://192.168.178.220/control?cmd=lcd,2,1,%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE')
        domoticz.openURL('http://192.168.178.220/control?cmd=lcd,3,1,%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE')
    elseif global.counter == 3 then
        -- Log the message and open the URL
        domoticz.openURL('http://192.168.178.220/control?cmd=lcd,1,1,%FE%FE%FE%FE%FE%FE%FE%FETEST%FE%FE%FE%FE%FE%FE%FE%FE')
        domoticz.openURL('http://192.168.178.220/control?cmd=lcd,2,1,%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE')
        domoticz.openURL('http://192.168.178.220/control?cmd=lcd,3,1,%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE%FE')
    end
    -- Log the counter value
    domoticz.log("Counter value: " .. global.counter, domoticz.LOG_INFO)
end

Re: get a global (or persistent)counter to work in dzVents-script

Posted: Wednesday 18 January 2023 14:15
by willemd
Sometimes you have to rely on your own intelligence .... and your ability to read the documentation ;-)

Your script does not have the structure of a dzVents script as explained here https://www.domoticz.com/wiki/DzVents:_ ... _scripting

Re: get a global (or persistent)counter to work in dzVents-script

Posted: Friday 20 January 2023 13:09
by RonkA
Thanks willemd, Realy helpful. Can anybody else realy help me?

Re: get a global (or persistent)counter to work in dzVents-script

Posted: Friday 20 January 2023 14:15
by waltervl
I suppose you could read the wiki section on dzvents global data https://www.domoticz.com/wiki/DzVents:_ ... _variables

But I do not think you need global data. Do you have multiple scripts using this data? If yes you need global data. If not you can use Script level persistent variables (see the wiki).

And also willemd is right, this is not a good dzVents script.
Also the error Error: EventSystem: in Script #2: [string "..."]:13: attempt to index a nil value (global 'domoticz') does not lead to anything in your script so it seems you copied only a part of your total script.

Re: get a global (or persistent)counter to work in dzVents-script

Posted: Friday 20 January 2023 15:24
by RonkA
This is my now working dzVents script for getting some other info to send to my display than the standard text from an other script that updates every 20 seconds:

Code: Select all

-- dit komt van openai 

local logLevel = domoticz.LOG_ERROR
return {
    on = {
        devices = {'Schakelaar op display2004'},
    },
    execute = function(domoticz, device)
        if (device.state == 'Off') then

                local sensor1 = domoticz.devices('Electra kosten vandaag')
                local sensor2 = domoticz.devices('Waterkosten vandaag') 
                local sensor3 = domoticz.devices('Buffervat bovenin')
         
                local value1 = domoticz.utils.round(sensor1.sensorValue,2)
                local value2 = domoticz.utils.round(sensor2.sensorValue,2)               
                local value3 = domoticz.utils.round(sensor3.temperature,0)            
            
                domoticz.log('Buffervat bovenin: ' .. value3, domoticz.LOG_INFO)
                domoticz.openURL('http://192.168.178.220/control?cmd=lcd,1,1,%FE%FE%FE%FEbuffervat%FE' .. value3 ..'%DFC')
                
                domoticz.log('Electra kosten vandaag: ' .. value1, domoticz.LOG_INFO)
                domoticz.openURL('http://192.168.178.220/control?cmd=lcd,2,1,Electrakosten%FE' .. value1 ..'EUR')
                
                domoticz.log('Waterkosten vandaag: ' .. value2, domoticz.LOG_INFO)
                domoticz.openURL('http://192.168.178.220/control?cmd=lcd,3,1,%FEkosten%FEwater%FE' .. value2 ..'EUR') 

        end
    end
}
This works ok.
Now i wanted to add more functionality, by pressing a button multiple times other messages would display. I thought it wouldn't be too difficult but Boy i was wrong..
Via trail and error i found out that the least difficult way would be to get a small counter to run between 1 to 3 and back to 1 every time the button is pressed.
Because i am not sure what is the best method to do this i tried(with 'help' of openai) persistent data, global data, Global persistent data, shared helpers but No Bueno.

For the persistent variables i made a global_data.lua file:

Code: Select all

return {
    helpers = {
        Buttonpress = 1 
    }
}
and saved it to NAS-1/docker/domoticz/scripts/dzVents/scripts/ as i understood from the wiki. but it doesnt work.
One of the many failed attempts:

Code: Select all

-- dit komt van openai 

return {
    on = {
        devices = { 'Schakelaar op display2004' }
    },
    execute = function(domoticz, device)
    local commandArray = {}   
    local buttonPressed = dzVents.globalData.getOrSet('Buttonpress', 1)
        local sensor1 = domoticz.devices('Electra kosten vandaag')
        local sensor2 = domoticz.devices('Waterkosten vandaag') 
        local sensor3 = domoticz.devices('Buffervat bovenin')
        local value1 = domoticz.utils.round(sensor1.sensorValue,2)
        local value2 = domoticz.utils.round(sensor2.sensorValue,2)               
        local value3 = domoticz.utils.round(sensor3.temperature,0) 

        if device.state == 'Off' then
            if buttonPress == 1 then
                domoticz.log('Buffervat bovenin: ' .. value3, domoticz.LOG_INFO)
                commandArray['OpenURL']='http://192.168.178.220/control?cmd=lcd,1,1,Test%FE%FE%FE%FEbuffervat%FE' .. value3 ..'%DFC'
                dzVents.globalData.set('Buttonpress', 2)
            elseif buttonPress == 2 then
                domoticz.log('Electra kosten vandaag: ' .. value1, domoticz.LOG_INFO)
                commandArray['OpenURL']='http://192.168.178.220/control?cmd=lcd,1,1,Test%FEElectrakosten%FE' .. value1 ..'EUR'
                dzVents.globalData.set('Buttonpress', 3)
            elseif buttonPress == 3 then
                domoticz.log('Waterkosten vandaag: ' .. value2, domoticz.LOG_INFO)
                commandArray['OpenURL']='http://192.168.178.220/control?cmd=lcd,1,1,Test%FEkosten%FEwater%FE' .. value2 ..'EUR'
                dzVents.globalData.set('Buttonpress', 1)
            end
        end
   --   return commandArray
    end
}
The attempt before this it was written without the commandarray command but it failed, i asked openai to rewrite with and made this, so Yeah i'm stuck.. :(

Re: get a global (or persistent)counter to work in dzVents-script

Posted: Friday 20 January 2023 15:38
by waltervl
Well I think openAi is not a really experienced dzVents programmer...
Better try and think yourself.

Re: get a global (or persistent)counter to work in dzVents-script

Posted: Friday 20 January 2023 15:56
by RonkA
thnx!

Re: get a global (or persistent)counter to work in dzVents-script

Posted: Friday 20 January 2023 16:43
by RonkA
Also the error Error: EventSystem: in Script #2: [string "..."]:13: attempt to index a nil value (global 'domoticz') does not lead to anything in your script so it seems you copied only a part of your total script.
This is because this forum engine croped 3 empty lines from pasted text, this is where i state info over the script for myself.. The latter script i didn't remove this info...
Sorry about that.

Re: get a global (or persistent)counter to work in dzVents-script

Posted: Friday 20 January 2023 19:10
by willemd
For starters: You are checking on the value of ButtonPress (1, 2 or 3) but you have not defined what that is. You have defined ButtonPressed, which is not the same thing as ButtonPress.

You are probably getting an error message on that?

Re: get a global (or persistent)counter to work in dzVents-script

Posted: Saturday 21 January 2023 11:22
by willemd
try this

Code: Select all

local logLevel = domoticz.LOG_ERROR
return {
    on = {
        devices = {'Schakelaar op display2004'},
    },
    data = {
        buttonPress = { initial = 1},  -- this is the definition of the persistent variable for counting the number of times the button is pressed
    },
    execute = function(domoticz, device)
        if (device.state == 'Off') then   -- so the button is pressed and then released, both changes trigger this script but the "off state" then executes the below lines

            local sensor1 = domoticz.devices('Electra kosten vandaag')
            local sensor2 = domoticz.devices('Waterkosten vandaag') 
            local sensor3 = domoticz.devices('Buffervat bovenin')
         
            local value1 = domoticz.utils.round(sensor1.sensorValue,2)
            local value2 = domoticz.utils.round(sensor2.sensorValue,2)               
            local value3 = domoticz.utils.round(sensor3.temperature,0)  

            domoticz.data.buttonPress=domoticz.data.buttonPress+1   -- increase the counter and reset to 1 if needed
            if domoticz.data.buttonPress>3 then
                domoticz.data.buttonPress=1
            end          
            
            if domoticz.data.buttonPress==1 then
                domoticz.log('Buffervat bovenin: ' .. value3, domoticz.LOG_INFO)
                domoticz.openURL('http://192.168.178.220/control?cmd=lcd,1,1,%FE%FE%FE%FEbuffervat%FE' .. value3 ..'%DFC') -- I assume this is the command to update the display?
            else
                if domoticz.data.buttonPress == 2 then
                    domoticz.log('Electra kosten vandaag: ' .. value1, domoticz.LOG_INFO)
                    domoticz.openURL('http://192.168.178.220/control?cmd=lcd,2,1,Electrakosten%FE' .. value1 ..'EUR')
                else
                    if domoticz.data.buttonPress == 3 then
                        domoticz.log('Waterkosten vandaag: ' .. value2, domoticz.LOG_INFO)
                        domoticz.openURL('http://192.168.178.220/control?cmd=lcd,3,1,%FEkosten%FEwater%FE' .. value2 ..'EUR') 
                    end
                end
            end
        end
    end
}


Re: get a global (or persistent)counter to work in dzVents-script

Posted: Saturday 21 January 2023 11:56
by RonkA
Hi, if i run this immediatly this error occurs:
Error: EventSystem: in display Script #1: [string " local logLevel = domoticz.LOG_ERROR ..."]:1: attempt to index a nil value (global 'domoticz')



I see you use tabs very consistant, is this just good practice or is it mandatory to get the script to work correctly?

Re: get a global (or persistent)counter to work in dzVents-script

Posted: Saturday 21 January 2023 13:28
by willemd
I think you can remove the first line and add the following just before the word "execute".

Code: Select all

logging = {
		level = domoticz.LOG_INFO,
		marker = 'display test',
	},

The tabs are just for readibility (and because I am used to python, where it is mandatory)

Re: get a global (or persistent)counter to work in dzVents-script

Posted: Saturday 21 January 2023 18:52
by RonkA
Replacing 1ine 1 gave:
Knipsel.JPG
Knipsel.JPG (20.73 KiB) Viewed 1120 times
So i placed line 5 to line 1:
Knipsel1.JPG
Knipsel1.JPG (19.14 KiB) Viewed 1120 times
,error gone but in the log this gives immediately:
Error: EventSystem: in display Script #1: [string "return { ..."]:3: attempt to index a nil value (global 'domoticz')
I have the funny feeling my dzvents is broken.. :?

Re: get a global (or persistent)counter to work in dzVents-script

Posted: Saturday 21 January 2023 19:15
by willemd
I think the order of the sections matters. You should put the logging section just before the word "execute".
If I run below script I get the "testing the buttonpress script" message in the log file and the device state.

Always good to put log messages in between while doing development.

Code: Select all


return {
    on = {
        devices = {'Schakelaar op display2004'},
    },
    data = {
        buttonPress = { initial = 1},  -- this is the definition of the persistent variable for counting the number of times the button is pressed
    },
    logging = {
		level = domoticz.LOG_INFO,
		marker = 'display test',
	},
    execute = function(domoticz, device)
    
        domoticz.log('testing the buttonpress script', domoticz.LOG_INFO)
        domoticz.log('device.state ' .. device.state, domoticz.LOG_INFO)
        
        if (device.state == 'Off') then   -- so the button is pressed and then released, both changes trigger this script but the "off state" then executes the below lines

            local sensor1 = domoticz.devices('Electra kosten vandaag')
            local sensor2 = domoticz.devices('Waterkosten vandaag') 
            local sensor3 = domoticz.devices('Buffervat bovenin')
         
            local value1 = domoticz.utils.round(sensor1.sensorValue,2)
            local value2 = domoticz.utils.round(sensor2.sensorValue,2)               
            local value3 = domoticz.utils.round(sensor3.temperature,0)  

            domoticz.data.buttonPress=domoticz.data.buttonPress+1   -- increase the counter and reset to 1 if needed
            if domoticz.data.buttonPress>3 then
                domoticz.data.buttonPress=1
            end          
            
            domoticz.log('buttonpress value ' .. domoticz.data.buttonPress, domoticz.LOG_INFO)
            
            if domoticz.data.buttonPress==1 then
                domoticz.log('Buffervat bovenin: ' .. value3, domoticz.LOG_INFO)
                domoticz.openURL('http://192.168.178.220/control?cmd=lcd,1,1,%FE%FE%FE%FEbuffervat%FE' .. value3 ..'%DFC') -- I assume this is the command to update the display?
            else
                if domoticz.data.buttonPress == 2 then
                    domoticz.log('Electra kosten vandaag: ' .. value1, domoticz.LOG_INFO)
                    domoticz.openURL('http://192.168.178.220/control?cmd=lcd,2,1,Electrakosten%FE' .. value1 ..'EUR')
                else
                    if domoticz.data.buttonPress == 3 then
                        domoticz.log('Waterkosten vandaag: ' .. value2, domoticz.LOG_INFO)
                        domoticz.openURL('http://192.168.178.220/control?cmd=lcd,3,1,%FEkosten%FEwater%FE' .. value2 ..'EUR') 
                    end
                end
            end
        end
    end
}

Top

Re: get a global (or persistent)counter to work in dzVents-script

Posted: Saturday 21 January 2023 20:46
by RonkA
Yes, now we getting somewhere..
When i copied the second last script i pasted it over the wrong script... a lua script :oops:
Now i started with a Clean dzVents script and it came alive:
2023-01-21 20:27:02.545 Error: dzVents: Error: (3.1.8) display test: There was a problem writing the storage values
2023-01-21 20:27:02.545 Error: dzVents: Error: (3.1.8) display test: /opt/domoticz/dzVents/runtime/persistence.lua:24: /opt/domoticz/userdata/scripts/dzVents/data/__data_Script #1 displaytest 1.lua: No such file or directory
So made data directory and its alive..

A few buttonpresses cycles the texts as wanted! Hurray!! :D
Thank you for getting me out of the vortex of going insane.