Script to control uptime

Greetings,
friends, it will be possible to make a script so that I can know at what time the electric service is interrupted and resumed in my equipment, it could be done using the uptime of my RB.

To retrieve the uptime:

/system resource> :put [get uptime];

And in into a variable:

{
:local getUptime [/system resource get uptime]
:put $getUptime
}

thank you my friend, but with this script is the moment when the equipment is turned off due to the power cut and also when the electricity is restored?
is there some way for the acript to record in a .txt file. So I know the time when the electric service was interrupted and the time when the service was restored. Thank you.

You can use the firewall-protocols 7 as a place to store a variable value.

You create a global variable which defines the mechanism to write/read to variables into layer7 protocol:

:global persistVar do={
	:local varName $1;
	:local varValue $2;
	:local varID [/ip firewall layer7-protocol find name="$varName"];

	:if ([:typeof $varValue] = "nothing") do={
		:if ($varID != "") do={
			:set $varValue [/ip firewall layer7-protocol get $varID value-name=regexp];
		}
	} else={
		:if ($varID = "") do={
			/ip firewall layer7-protocol add name="$varName" regexp="$varValue"
		} else={
			/ip firewall layer7-protocol set $varID regexp="$varValue"
		}
	}

return $varValue
}

Then in order to call this “function” and write the value into it, just call:
$persistVar Uptime $getUptime; ← where Uptime will be written as a variable in Layer7 protocol.

So in this case even during outage such value will be kept there.
It’s an equivalent of writing/reading to file.

Armando.

Router can not in any way predict that there soon will be a power loss. You should either use a monitoring software, for example, The Dude or write a script.

I would recommend that you run scheduler (for example, every second) and write down a clock in a file. Then have another scheduler that runs on startup and writes into log contects of this file and current time. Then you will see what was the last time when router could write into a file and when it is powered back on.

Armando, your script runs but doesn’t even give the regex a name

The script that i have shown you is only a function to write and ready from layer7 protocol used as storage place.
Then you need to call that function by passing the variable and value that you want to write; while to read it you just pass the function and variable name that is in layer 7 protocol.

use $persistVar to write into that area protocol 7, where value will go in regex value.
use $persistVar to read its value and put into your variable in your script.

I use this approach on several of my scripts and it works fine.

ARMANDO, it is very difficult for me to make this script could you help me. Thank you.

This script will write into firewall → layer7 protocol a value of val_uptime with the uptime from your router.
You can start from here and change it to your needs.

:global persistVar do={
	:local varName $1;
	:local varValue $2;
	:local varID [/ip firewall layer7-protocol find name="$varName"];

	:if ([:typeof $varValue] = "nothing") do={
		:if ($varID != "") do={
			:set $varValue [/ip firewall layer7-protocol get $varID value-name=regexp];
		}
	} else={
		:if ($varID = "") do={
			/ip firewall layer7-protocol add name="$varName" regexp="$varValue"
		} else={
			/ip firewall layer7-protocol set $varID regexp="$varValue"
		}
	}

return $varValue
}

:do {
	$persistVar val_uptime [/system resource get uptime];
} on-error={ :log error "Script error "};

friend ARMANDO, the script records the RB’s activity time, but what I need is that in one regexp he tells me the activity time and in another regexp the new activity time so that we know at what time the electricity was interrupted and at what time They connected the electricity again, I don’t know if you understand me. Thank you.

As MK support told you, router won’t know when power outage.
So you can apply 2 scripts each on separate scheduler.

Script1 you can put it on a scheduler every X time, which will record your router uptime with date and time of the record.

:global persistVar do={
	:local varName $1;
	:local varValue $2;
	:local varID [/ip firewall layer7-protocol find name="$varName"];

	:if ([:typeof $varValue] = "nothing") do={
		:if ($varID != "") do={
			:set $varValue [/ip firewall layer7-protocol get $varID value-name=regexp];
		}
	} else={
		:if ($varID = "") do={
			/ip firewall layer7-protocol add name="$varName" regexp="$varValue"
		} else={
			/ip firewall layer7-protocol set $varID regexp="$varValue"
		}
	}

return $varValue
}

:do {
	:local day ([:pick [/system clock get date] 4 6]);
	:local mon ([:pick [/system clock get date] 0 3]);
	:local year ([:pick [/system clock get date] 7 11]);
	:local date "$day-$mon-$year";
	:local time (:put [/system clock get time]);
	:local data1 ("Uptime is " . [/system resource get uptime] . " --- " . $date . " --- " . $time);
	$persistVar val_uptime $data1;
} on-error={ :log error "Script1 error"};

Then you create another scheduler triggered on start-up of the router and you add this script2.

:global persistVar do={
	:local varName $1;
	:local varValue $2;
	:local varID [/ip firewall layer7-protocol find name="$varName"];

	:if ([:typeof $varValue] = "nothing") do={
		:if ($varID != "") do={
			:set $varValue [/ip firewall layer7-protocol get $varID value-name=regexp];
		}
	} else={
		:if ($varID = "") do={
			/ip firewall layer7-protocol add name="$varName" regexp="$varValue"
		} else={
			/ip firewall layer7-protocol set $varID regexp="$varValue"
		}
	}

return $varValue
}

:do {
	:local day ([:pick [/system clock get date] 4 6]);
	:local mon ([:pick [/system clock get date] 0 3]);
	:local year ([:pick [/system clock get date] 7 11]);
	:local date "$day-$mon-$year";
	:local time (:put [/system clock get time]);
	:local data1 ("Router restarted on " . $date . " --- " . $time);
	$persistVar val_restarted $data1;
} on-error={ :log error "Script2 error"};

So the second script will record when your router was restarted.
Now you have several examples to work on your own if you need more.

ARMANDO, thanks for the scripts, but the first one doesn’t work since when restarted the RB takes the same time as the second script

Well because the logic was simply to record the data into a permanent variable, nothing more.
You can try this new approach by storing the current uptime + date and time to a permanent variable.
The script will run as a loop and will update the variable on Layer7 protocol every 1 second.
Whenever the router will shutdown (or whenever you will restart your router), the script won’t run automatically anymore, therefore last record in the variable will indicate the moment before your router ended working.
So have this script added in the system script and run it manually the first time.

:global persistVar do={
	:local varName $1;
	:local varValue $2;
	:local varID [/ip firewall layer7-protocol find name="$varName"];

	:if ([:typeof $varValue] = "nothing") do={
		:if ($varID != "") do={
			:set $varValue [/ip firewall layer7-protocol get $varID value-name=regexp];
		}
	} else={
		:if ($varID = "") do={
			/ip firewall layer7-protocol add name="$varName" regexp="$varValue"
		} else={
			/ip firewall layer7-protocol set $varID regexp="$varValue"
		}
	}

return $varValue
}

:global stopScript false;

:do {
	:local day ([:pick [/system clock get date] 4 6]);
	:local mon ([:pick [/system clock get date] 0 3]);
	:local year ([:pick [/system clock get date] 7 11]);
	:local date "$day-$mon-$year";
	:local time (:put [/system clock get time]);
	:local data1 ("Uptime is " . [/system resource get uptime] . " --- " . $date . " --- " . $time);
	$persistVar val_uptime $data1;

	:delay 1;
} while=(!$stopScript)

Once the script is running, since it will go into a loop, you will see its run on the script’s job tab.
If your router will stop running, after startup the script won’t re-start automatically; this will guarantee that you have the time to read the variable value to see when the power outage happened.
So don’t restart this script automatically at router start-up, otherwise the previous value will be overwritten and you won’t see the time of power failure.

If you need to stop the script for any reason, you can set a global variable called stopScript and assign the value true from the terminal.

:set $stopScript true;

By typing so in the terminal you can stop the script at any time.
Just one note: by writing all values into this permanent variable, it’s easy to find and read the content without the need to open any file and watch inside.
However each time the script will update the value on the Layer7 section, a new log entry is created with this text: layer 7 protocol changed by username.
You can think about how frequently you want the script to run in this loop: by changing the value of delay, you can set it to any interval of seconds.
So if you want to run this every 1 minute, just change that line with this one.

Change the delay to your needs: 60 will be 1 minute

:delay 60;

This is it, now you have something close to your needs.

[quote=theodore6W post_id=793060 time=1589364330 user_id=163967]
[quote]Well because the logic was simply to record the data into a permanent variable, nothing more.

You can try this new approach by storing the current uptime + date and time to a permanent variable.

The script will run as a loop and will update the variable on Layer7 protocol every 1 second.[/quote]


Well, it helped a lot in my situation. [/quote]

I’m glad that this little script helped you out as well.

Armando.

that was the script dear brother. Thank you.



just out of curiosity, is there a way that instead of layer protocol 7 it’s copied to a file

If you want to write the info to a file instead of layer7 protocol, you can use this version.
However you should read this info about writing to disk, which depends on the router and disk type that you are using: https://wiki.mikrotik.com/wiki/Manual:System/File
Read about warning and notes.

If your router does have a flash disk you can use this version that writes the info every 1 minute.

:global stopRouterRun false;

:do {
	:local file "flash/uptime.txt";
	:local day ([:pick [/system clock get date] 4 6]);
	:local mon ([:pick [/system clock get date] 0 3]);
	:local year ([:pick [/system clock get date] 7 11]);
	:local date "$day-$mon-$year";
	:local time (:put [/system clock get time]);
	:local data1 ("Uptime is " . [/system resource get uptime] . " --- Stored on " . $date . " at " . $time);
	/file print file="$file"
	/file set $file contents=$data1;

	:delay 60;
} while=(!$stopRouterRun)

Otherwise if your router uses NAND type of memory storage, you can use this.

:global stopRouterRun false;

:do {
	:local file "uptime.txt";
	:local day ([:pick [/system clock get date] 4 6]);
	:local mon ([:pick [/system clock get date] 0 3]);
	:local year ([:pick [/system clock get date] 7 11]);
	:local date "$day-$mon-$year";
	:local time (:put [/system clock get time]);
	:local data1 ("Uptime is " . [/system resource get uptime] . " --- Stored on " . $date . " at " . $time);
	/file print file="$file"
	/file set $file contents=$data1;

	:delay 60;
} while=(!$stopRouterRun)

This will write data into file and overwrites its content with the latest info every minute. Same principle as before, when you will experience a power outage the script will stop writing into file and you will see the last timestamp in there. However as indicated in the notes, if your router does not use flash type memory, you might have up to 40 seconds delay before data is written from memory to disk, so you might loose some event within the minute.
So you can decide to change delay 60 to something less so that your reading is more accurate.

Armando

Dear ARMANDO, the text is created in the file, but it is not overwritten every minute, which will happen there. Thank you.

Dear Frank, are you sure ?
Please check better, because the text inside the file is overwritten every minute.
Let it run for few minutes and check at the end when you will reboot your router.
I have tested it with my router and it did update the text each minute.

Armando

I just tested it and it does not overwrite the data, it creates the file yes, but it does not overwrite the data every minute.

So I guess we can conclude that our routers are behaving differently.
Now it’s up to you what solution you will adopt.
I gave you all the help possible, now it’s on you.

Take care,
Armando.