Time condition - question/improvement

Don't hesitate to post if you have an improvement idea
Post Reply
KamilR
Posts: 3
Joined: 20 Jun 2020, 23:26

Time condition - question/improvement

Post by KamilR »

Time Condition can execute on a given time. My question is how often is this checked?

I've run some tests with just this one line/condition in some cases it finishes 0,9 sec after a given time, and sometimes it goes down to like 300 ms.
It would be great to be able to set not only HH:mm:ss but also miliseconds so that I can be sure for it to start let say 00:00:00:000 and not something like 00:00:00:800
Execution duration shows 0,001 seconds in all cases - so my question is - where the rest of this time goes ? I

KamilR
Posts: 3
Joined: 20 Jun 2020, 23:26

Re: Time condition - question/improvement

Post by KamilR »

Another issue I have with 'Time condition' is that is usually takes 50-60ms to execute but sometimes in randomly goes up to 800-900ms
Attachments
test.jpg
test.jpg (123.68 KiB) Viewed 475 times

KamilR
Posts: 3
Joined: 20 Jun 2020, 23:26

Re: Time condition - question/improvement

Post by KamilR »

Any idea how to go around this?
Let say I need to script start exactly at 00:00:00:001 (HH:mm:ss:fff), and the closer I get to this, the better

eureka
Posts: 89
Joined: 08 Mar 2016, 22:18

Re: Time condition - question/improvement

Post by eureka »

Create a cronjob?

ErikN
Posts: 2
Joined: 04 Feb 2021, 15:01

Re: Time condition - question/improvement

Post by ErikN »

I took a look at cronjob today but I am not sure how you would have it execute the script? It’s possible to have it run it daily at a certain time but the problems occurs for me on figuring out how to make cronjob do that.

eureka
Posts: 89
Joined: 08 Mar 2016, 22:18

Re: Time condition - question/improvement

Post by eureka »

The idea I suggested .. running a daily cronjob .. is written up
in articles, blogs such as this one here ..

https://www.jessicayung.com/automate-ru ... g-crontab/

So the suggestion is you write a cronjob to run a command at a certain time .. daily ..
The cronjob will be written in /etc/cron.daily
This cronjob command might run an Actiona script .. actexec /path/to/my/Actiona.ascr
at specified precise time .. or it could be a Python script which is run.

That is the theory.

minx
Posts: 11
Joined: 24 Jan 2021, 20:51

Re: Time condition - question/improvement

Post by minx »

Did a test using Execution.sleep(ms)

Test code reads text file holding target time. Parses it, set up a date object with set time, sleep the difference, then call a function printing the time at execution / the target time.

As you can see below it is pretty accurate.

One would typically have to start the script a little before target time as loading of the Actiona environment etc. takes time. (By cron for example as mentioned earlier.)

test-timer.js

Code: Select all

// Read text from file
function file2string (file) {
	var fh = new File();
	fh.open(file, File.ReadOnly);
	var txt = fh.readText().trim();
	fh.close();
	return txt;
}
// Input: HH:MM:SS.nnn
function timestr2date(ts) {
	var vt = ts.split(/[:.]/);
	var d = new Date();
	d.setHours(vt[0]);
	d.setMinutes(vt[1]);
	d.setSeconds(vt[2]);
	d.setMilliseconds((vt[3] + "00").substr(0, 3));
	// Increment to next day if time has passed.
	if (d.getTime() < Date.now())
		d.setDate(d.getDate() + 1);
	return d;
}
// Zero pad times (helper for date2timestr)
function tz(t, w) {
	return ("000" + t).substr(-w);
}
// Return YYYY-MM-DD HH:mm:ss.nnn from a Date object.
function date2timestr(d) {
	return [
		d.getFullYear(),
		tz(d.getMonth() + 1, 2),
		tz(d.getDate(), 2),
	].join('-') + " " +
	[
		(" " + d.getHours()).substr(-2),
		tz(d.getMinutes(), 2),
		tz(d.getSeconds(), 2),
	].join(':') + '.' + tz(d.getMilliseconds(), 3);
}
// Print status before sleep
function print_wait(t_time, sleep) {
	Stdio.println("NOW   : " + date2timestr(new Date()));
	Stdio.println("TARGET: " + date2timestr(t_time));
	Stdio.println("SLEEP : " + sleep + "ms (Aprox)");
}

// Arg 1 is the function to call when target time is reached.
// Arg 2 is the target time as HH:MM:SS:nnn
function schedule(what_to_do, stime) {
	var t_time = timestr2date(stime);
	var sleep = t_time.getTime() - Date.now();

	print_wait(t_time, sleep);
	// Recalculate on sleep call to remedy call to
	// print_wait overhead.
	Execution.sleep(t_time.getTime() - Date.now());
	what_to_do();
}

// The (dummy) work function.
// Prints time on call after sleep.
function work () {
	Stdio.println("WORK  : " + date2timestr(new Date()));
}

// Get the target time from the text file.
var ttime = file2string("runat.txt");
// Start the countdown
schedule(work, ttime);
Example output:

The date commands before and after gives one a little hint on load and exit time.

Code: Select all

$ echo "12:09:00.000" >runat.txt; date +"%F %T.%N"; actexec -cQ test-timer.js ; date +"%F %T.%N"
2021-02-05 12:08:46.972689826
NOW   : 2021-02-05 12:08:47.142
TARGET: 2021-02-05 12:09:00.000
SLEEP : 12858ms (Aprox)
WORK  : 2021-02-05 12:09:00.000
2021-02-05 12:09:00.027783928

Code: Select all

$ echo "12:09:45.100" >runat.txt; date +"%F %T.%N"; actexec -cQ test-timer.js ; date +"%F %T.%N"
2021-02-05 12:09:38.973075294
NOW   : 2021-02-05 12:09:39.136
TARGET: 2021-02-05 12:09:45.100
SLEEP : 5964ms (Aprox)
WORK  : 2021-02-05 12:09:45.100
2021-02-05 12:09:45.131307586

Code: Select all

$ echo "12:10:10.123" >runat.txt; date +"%F %T.%N"; actexec -cQ test-timer.js ; date +"%F %T.%N"
2021-02-05 12:10:00.727193336
NOW   : 2021-02-05 12:10:00.913
TARGET: 2021-02-05 12:10:10.123
SLEEP : 9210ms (Aprox)
WORK  : 2021-02-05 12:10:10.123
2021-02-05 12:10:10.155037491
Had a few times where there is a 1ms discrepancy, but all over good results.

minx
Posts: 11
Joined: 24 Jan 2021, 20:51

Re: Time condition - question/improvement

Post by minx »

An example that is more tailored for Actiona GUI:

The Time Condition element has an overhead that can be eliminated using pure JavaScript.

NB! Using this script the execution completely halts. That is: you can not stop the script once running. Only way is to kill the process. Thus make sure you save work before running if you are not sure.

That is the price to pay for higher accuracy :lol:

Elements TOC

actiona-timer-test-overview-1.png
actiona-timer-test-overview-1.png (22.57 KiB) Viewed 62 times
001 - Target seconds / milliseconds

A variable for test purposes. It defines the target time to execute in the form of ss.mmm as variable ss_mmm.

Hour and minute is set by test function.
actiona-timer-test-001.png
actiona-timer-test-001.png (4.67 KiB) Viewed 62 times

Code: Select all

var ss_mmm = "30.000";
002 - The continue_at_time script

The actual timer. It has the global function continue_at_time(str target_time[, bool print sleep time])

For example: continue_at_time("22:15:00.0", true)

Code: Select all

// Input: HH:MM:SS.nnn
function timestr2date(ts) {
	var vt = ts.split(/[:.]/);
	var d = new Date();
	d.setHours(vt[0]);
	d.setMinutes(vt[1]);
	d.setSeconds(vt[2]);
	// Note: 1 => 001 , 10 => 010 etc.
	d.setMilliseconds(("00" + vt[3]).substr(-3));
	// Increment to next day if time has passed.
	if (d.getTime() < Date.now())
		d.setDate(d.getDate() + 1);
	return d;
}
function continue_at_time(str_time, print_sleep_amount) {
	var t_time = timestr2date(str_time);
	if (print_sleep_amount) {
		var sleep = t_time.getTime() - Date.now();
		Console.print("Sleep: " + sleep + "ms");
	}
	// Calculate on call
	Execution.sleep(t_time.getTime() - Date.now());
}
003 - Test continue_at_time()

Testing the continue_at_time() function.

Uses the previously defined global ss_mmm to set time to sleep. Print time to Console.

Code: Select all

function test_timer(print_time_on_continue) {
	var t_now = new Date();
	// Use the global ss_mmm variable for seconds / millseconds
	var t_exec = [t_now.getHours(), t_now.getMinutes(), ss_mmm].join(':');
	continue_at_time(t_exec);
	if (print_time_on_continue) {
		Console.print("Continuing at: " + (new Date()).toISOString());
	}
}

test_timer(true);
003 - Next script Print time

Loading and executing next action has an overhead. This script simply print time; to show the lag. Here it is around 10-15ms but would be system dependant + likely dependant on other factors.

Code: Select all

(function () {
	var t_now = new Date();
	Console.print("Next script: " + t_now.toISOString());
})();
Using Time condition

You could add a Time condition to compare:
actiona-timer-test-time_cond.png
actiona-timer-test-time_cond.png (26.53 KiB) Viewed 62 times
Disable the other scripts and see the difference.


The Time condition is heavier / uses more time to execute then the pure JS version.
Last edited by minx on 06 Feb 2021, 03:57, edited 2 times in total.

minx
Posts: 11
Joined: 24 Jan 2021, 20:51

Re: Time condition - question/improvement

Post by minx »

The ascr file and sample results.

Using JavaScript

Here time was set at: 02:34:50.000Z
actiona-timer-test-using_js.png
actiona-timer-test-using_js.png (19.41 KiB) Viewed 61 times

«Next script» has a delay of 12ms. The test script calling the continue at function has a delay of 0ms.

Using Time Condition

Here time was set at: 02:50:00Z
actiona-timer-test-using_time_condition.png
actiona-timer-test-using_time_condition.png (13.17 KiB) Viewed 61 times

«Next script» has a delay of 738ms.

The script
timer-test.ascr
(3.97 KiB) Downloaded 5 times

Post Reply