Page 1 of 1

Time and getISO problem

Posted: Monday 17 April 2023 14:04
by ricorico94
Hi,

There must be something that I don't understand about Time variables and data. I had a script running properly for a long time, but not wokring anymore since I had to reinstall and upgrade to newer domtoicz/dzvents version. I was probably not coding properly and benefitting from some trick, but now, I can't understand why it doesn't work..
I'm now using Domoticz 2023.1, on Buster, with DZvents 3.1.8.
I can't succeed making work properly the getISO command. In below script (simplified version of my script to manage a small OPS for the raspberry), I want to keep memory of last "reset date/time" and display that date/time in clear text in the log as well as showing how many minutes since last reset.
But despite getISO works on another script I tested, using local variable, here it doesn't work.

Code: Select all

return
{
    on =
    {
        timer =
        {
            'every 1 minutes',                -- causes the script to be called every 3 minutes
        },
    },
    data = {
	   lastReset = {initial= ''}
	},
    logging =
    {
        level = domoticz.LOG_DEBUG,
        marker = getVoltage,
    },

    execute = function(dz)

        
		local Time = require('Time')
        if dz.data.lastReset == nil then 
            dz.log('testscript lastReset is NIL ', dz.LOG_INFO)
            dz.data.lastReset=Time()
            dz.log('testscript lastReset is now set at '..dz.data.lastReset.getISO(), dz.LOG_INFO)
        end
        if dz.data.lastReset == nil then 
            dz.log('testscript lastReset is still NIL !!', dz.LOG_INFO)
        else
            dz.log('testscript lastReset is not anymore NIL !!  ', dz.LOG_INFO)
            local temptime=dz.data.lastReset
            if temptime == nil then 
            dz.log('testscript temptime is NIL ', dz.LOG_INFO)
        else
            dz.log('testscript valeur de temptime'..temptime.getISO(), dz.LOG_INFO)
            end
            
        end
        if dz.data.lastReset ~= nil then 
            dz.log('testscript lastReset is not NIL and can be displayed !!'..dz.data.lastReset.getISO(), dz.LOG_INFO)
        end
        

		if (true ) then 
				
				dz.log('testscript critical warning domoticz UPS under too low voltage, starting reset', dz.LOG_INFO)
					local now= Time()
					dz.data.lastReset = now
				
		end
		
		dz.log('testscript last reset at time :'..dz.data.lastReset.getISO(), dz.LOG_INFO)
		dz.log(' testscriptlast reset at '..dz.data.lastReset.getISO()..' which means in minutes :'..dz.data.lastReset.minutesAgo, dz.LOG_INFO)
		
    end
}
(Note: there are many "if" statements in script above, but the target of these is only to try understanding when variable is NIL and why getISO() returns this error message..

In fact, when the script reaches dz.log instructions with .getISO(), I receive error message like :
2023-04-17 13:53:00.476 Error: dzVents: Error: (3.1.8) An error occurred when calling event handler Test2 script
2023-04-17 13:53:00.476 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Test2 script.lua:36: attempt to call a nil value (field 'getISO')

What I don't understand, is that in my test above, I test is the value of dz.data.lastReset is NIL and if yes, I initialize it at Time() and it seems working because next I see message :
2023-04-17 13:55:00.491 Status: dzVents: Info: ------ Start internal script: Test2 script:, trigger: "every 1 minutes"
2023-04-17 13:55:00.492 Status: dzVents: Info: testscript lastReset is not anymore NIL !!
2023-04-17 13:55:00.492 Status: dzVents: Info: ------ Finished Test2 script
but then I get the error message shown above. And with all the "IF" I put, I see that the value should not be NIL since scripts runs through the ELSE displaying "not anymore NIL"
I tried also to go through a local variable (cf code above with temptime), but it fails also.

If I do a script with simply

Code: Select all

local Time = require('Time')
	local tonight = Time()
	dz.log('test script tonight value:'..tonight.getISO(), dz.LOG_INFO)
	dz.data.lastReset = tonight
this does work..

So can you help me understanding what I do wrong ?

Also, maybe an extra question : to initialize the global variable lastReset upon first run, i use the " lastReset = {initial= ''} "statement. Is there a way to initialize it as a predefined date/time or even the current date/time ? When I try something like {initial=Time()} I have error message, bprobably because I don't have yet the "local Time=require ('Time') before the initialization.

Thanks a lot for your help !

Re: Time and getISO problem

Posted: Monday 17 April 2023 14:52
by willemd
What if you print the lastReset with a different format or unformatted? Can you see that the value of lastReset is as expected?

Re: Time and getISO problem

Posted: Monday 17 April 2023 16:04
by ricorico94
If I simply use statement such as (row 53): dz.log('testscript last reset at time :'..dz.data.lastReset, dz.LOG_INFO)

then I get no value displayed (even for the 'temptime' local variable), only text messages and an error for trying to concatenate:
2023-04-17 16:00:00.428 Status: dzVents: Info: ------ Start internal script: Test2 script:, trigger: "every 1 minutes"
2023-04-17 16:00:00.429 Status: dzVents: Info: testscript lastReset is not anymore NIL !!
2023-04-17 16:00:00.429 Status: dzVents: Info: testscript valeur de temptime
2023-04-17 16:00:00.429 Status: dzVents: Info: testscript lastReset is not NIL and can be displayed !!
2023-04-17 16:00:00.429 Status: dzVents: Info: testscript critical warning domoticz UPS under too low voltage, starting reset
2023-04-17 16:00:00.429 Status: dzVents: Info: ------ Finished Test2 script
2023-04-17 16:00:00.429 Error: dzVents: Error: (3.1.8) An error occurred when calling event handler Test2 script
2023-04-17 16:00:00.429 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Test2 script.lua:53: attempt to concatenate a table value (field 'lastReset')

Re: Time and getISO problem

Posted: Monday 17 April 2023 16:53
by willemd
This indicates it is a table so you should be able to use dumpTable to see the contents. That might help you in the next step of analysis.

Re: Time and getISO problem

Posted: Monday 17 April 2023 18:35
by ricorico94
well, when I checked the file with data in domoticz/scripts/dzvents/data, the variable was not empty, but with mixed fields..
The problem is probably due to a misuse of Time variables.. but even with very simple script, I get an error:

Code: Select all

return
{
    on =
    {
        timer =
        {
            'every 1 minutes',                -- causes the script to be called every 3 minutes
        },
    },
    data = {
	   lastReset = {initial= ''}
	},
    logging =
    {
        level = domoticz.LOG_DEBUG,
        marker = getVoltage,
    },
    execute = function(dz)
		local Time = require('Time')
        if dz.data.lastReset == nil then 
            dz.data.lastReset=Time()
            dz.log('testscript lastReset is now set at '..dz.data.lastReset.getISO(), dz.LOG_INFO)
        end
        if dz.data.lastReset ~= nil then 
            dz.log('testscript lastReset is not NIL and can be displayed !!'..dz.data.lastReset.getISO(), dz.LOG_INFO)
        end
    end
}
Logically, this script should start with lastReset being NIL, and then being assigned current Time value, and then no change..
but still errors:
2023-04-17 18:27:00.391 Status: dzVents: Info: ------ Start internal script: Test4 script:, trigger: "every 1 minutes"
2023-04-17 18:27:00.392 Status: dzVents: Info: ------ Finished Test4 script
2023-04-17 18:27:00.392 Error: dzVents: Error: (3.1.8) An error occurred when calling event handler Test4 script
2023-04-17 18:27:00.392 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Test4 script.lua:25: attempt to call a nil value (field 'getISO')

There must be something I don't understand on how to use variables/objects or the getISO, minutesago, etc. functions.

Re: Time and getISO problem

Posted: Monday 17 April 2023 19:06
by Kedi
In the data section you prefill the data with an empty string.

Code: Select all

lastReset = {initial= ''}
So change:

Code: Select all

if dz.data.lastReset == nil then
with

Code: Select all

if dz.data.lastReset == '' then
B.t.w. The fill you use (dz.data.lastReset=Time())is a very big array not a string.
Look here for functions and methodes: https://www.domoticz.com/wiki/DzVents:_ ... nd_methods

Re: Time and getISO problem

Posted: Tuesday 18 April 2023 9:59
by ricorico94
Hi,
I followed your advice and changed the test script this way:

Code: Select all

return
{
    on =
    {
        timer =
        {
            'every 1 minutes',                -- causes the script to be called every 3 minutes
        },
    },
    data = {
	   lastReset = {initial= ''}
	},
    logging =
    {
        level = domoticz.LOG_DEBUG,
        marker = getVoltage,
    },
    execute = function(dz)
		local Time = require('Time')
        if dz.data.lastReset == '' then 
            dz.data.lastReset=Time()
            dz.log('test4script lastReset is now set at '..dz.data.lastReset.getISO(), dz.LOG_INFO)
        end
        if dz.data.lastReset ~= nil then 
            dz.log('test4script lastReset is not NIL and can be displayed !!'..dz.data.lastReset.getISO(), dz.LOG_INFO)
        end
        dz.log('test4script lastReset regular check value :'..dz.data.lastReset.getISO(), dz.LOG_INFO)
    end
}
Now, the weird thing is that here's the log of 1st time run, which looks ok:
2023-04-18 09:24:00.650 Status: dzVents: Info: ------ Start internal script: Test4 script:, trigger: "every 1 minutes"
2023-04-18 09:24:00.651 Status: dzVents: Info: test4script lastReset is now set at 2023-04-18T07:24:00Z
2023-04-18 09:24:00.651 Status: dzVents: Info: test4script lastReset is not NIL and can be displayed !!2023-04-18T07:24:00Z
2023-04-18 09:24:00.651 Status: dzVents: Info: test4script lastReset regular check value :2023-04-18T07:24:00Z
2023-04-18 09:24:00.654 Status: dzVents: Info: ------ Finished Test4 script
but the 2d time run (and next ones) shows error, despite I don't change value of lastReset:
2023-04-18 09:25:00.503 Status: dzVents: Info: ------ Start internal script: Test4 script:, trigger: "every 1 minutes"
2023-04-18 09:25:00.504 Status: dzVents: Info: ------ Finished Test4 script
2023-04-18 09:25:00.504 Error: dzVents: Error: (3.1.8) An error occurred when calling event handler Test4 script
2023-04-18 09:25:00.504 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Test4 script.lua:25: attempt to call a nil value (field 'getISO')
(row 25 is the "dz.log('test4script lastReset is not NIL and can be displayed !!'..dz.data.lastReset.getISO(), dz.LOG_INFO)" in last IF statement.

Any idea on why getISO() would work on 1st run and not the 2d one ?

Re: Time and getISO problem

Posted: Tuesday 18 April 2023 10:17
by Kedi
You still fill the data with an time object in:

Code: Select all

dz.data.lastReset=Time()
Just fill it with a datestring of your format. And don't use getISO because that presumes an time object.
Read and try to understand the Wiki about the time object.

Re: Time and getISO problem

Posted: Tuesday 18 April 2023 10:51
by ricorico94
Hi,
I was aiming at using a time object, so that I can use functions like 'minutesAgo' and simple calculations on time values, etc.
Do you mean that these script persistent variables can not be objects ? If I want an object, we must create and use a Global Variable ?
In other words, the script variables that we access through 'dz.data.myscriptvariable ' can only be text or numeric values, or arrays of such values ? (no structured object) ?
And is there any reaosn why the getISO() cal works on first run, but not later on ?

I read multiple times the wiki about the time object, but it seems I misunderstood on what we can apply such time object..

Re: Time and getISO problem

Posted: Tuesday 18 April 2023 11:27
by Kedi
You can fill the dz.data.lastReset with an Time 'object', but you have to be consistent in using it as such.
Time() fills the dz.data.lastReset with more then 4200 bytes.
This one has to be changed:

Code: Select all

        if dz.data.lastReset ~= nil then 

Re: Time and getISO problem

Posted: Tuesday 18 April 2023 11:41
by ricorico94
I'm not sure I understand what you mean. In my script, right after initializing at ' ', I assign the Time object to it, so it shouldn't be NIL afterwards, correct ? So which kind of test should I do to check that it's now a Time object with some value ?

And the next question, is: if I can fill it with the Time object as I did (if I did it properly ?), then why the .getISO() shows error ? In the wiki, the .getISO is listed.. In my script, if I use dz.data.lastReset.rawDateTime , it works, but if I use dz.data.lastReset.getISO() , it fails.

Re: Time and getISO problem

Posted: Tuesday 18 April 2023 14:19
by Kedi
I think ( did not test) that something like this might help.

Code: Select all

        if dz.data.lastReset.time ~= nil then 
or

Code: Select all

        if dz.data.lastReset.rawDateTime ~= nil then 
getISO is a function and rawDateTime is data
In this case you cannot use a function to get to this data, I suppose.

Re: Time and getISO problem

Posted: Tuesday 18 April 2023 23:02
by ricorico94
I can use such workaround and also only use text data for my data, thanks for your help.

However, if anyone could clarify why the functions don't seem to work despite it used to work in previous version of domoticz and dzcents, I'd like to understand.. I lose here interesting features of time object.