Check Hotspot user Comment Against Current Date

I am using the phpAPI to allow Hotels etc to use a web portal to create users for their hotspot and as part of that the user is assigned a comment based on either their check out date or seven days from when created if unspecified. I then run the script below daily to clear out old users. It checks for empty or non-integer comments and ignores them which allows me to have an option for setting users to ‘not expire’ if they have long term clients. Hopefully useful for others:

:foreach counter in=[/ip hotspot user find] do= {
if ([ /ip hotspot user get $counter comment ] != "") do={
:local date1 [ /ip hotspot user get $counter comment ];
:local date2 [ /system clock get date ];
:local months ("jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec");
:local date1month [ :pick $date1 0 3 ];
:local date1day [ :pick $date1 4 6 ];
:local date1year [ :pick $date1 7 11 ];
:local mm ([ :find $months $date1month -1 ] + 1);
:if ($mm < 10) do={
   :set date1month ("0" . $mm);
} else={
   :set date1month $mm;
}
:local date1value ($date1year . $date1month . $date1day);
:local date2month [ :pick $date2 0 3 ];
:local date2day [ :pick $date2 4 6 ];
:local date2year [ :pick $date2 7 11 ];
:local mm ([ :find $months $date2month -1 ] + 1);
:if ($mm < 10) do={
    :set date2month ("0" . $mm);
} else={
    :set date2month $mm;
}
:local date2value ($date2year . $date2month . $date2day);
:local date1valuenum [:tonum $date1value];
if ([:typeof $date1valuenum] = "num") do={
if ($date1value <= $date2value) do={
	/ip hotspot user remove $counter }
	}
}
}

Since you’re adding users via API, why not just ALSO add a scheduler script for the user at that point? The script would be triggered at expiration time, and could then remove the user and itself. If it’s necessary to then extend the stay, just modify the time for the scheduler script with the API.

I hadn’t actually even thought of doing it that way boen_robot. I guess my concern would be the CPU and Memory load in having hundreds of different scripts in the scheduler when it could be achieved with just the one. Either solution would work though.

The best one could compress each scheduler script would be

/sy sch r ""
/ip h u r ""

So this means at least 25 bytes per user, plus however many more their username is (so that it’s put inside the quotes there). An average name of 5 characters makes 30 bytes per user or 3KiB for 100 users. I guess the scheduler item itself would also take up some memory… Let’s say ~256 bytes per item, to err on the “heavy” side, so that makes a total of ~28KiB for 100 users.

Sounds reasonable even for weaker RouterBOARD devices to me.

I guess the CPU may be a more valid concern. I’d think that RouterOS is smart enough to not even bother checking scheduled tasks that are hours ahead in the future… I mean, if I was implementing a scheduler system, I’d order all tasks by their due time, and just check if the first one is up, without checking the rest (since they’re obviously not yet due either). But I haven’t made tests with hundreds of scheduled tasks on a weak RouterBOARD to see if this causes a CPU spike or not.

Yeah, I am sure it’d work fine. no reason why not. either way would be good. I thought it’d be useful for people to be able to see this code anyway as the concept could be altered to be put against a variety of things, A lot of the code I got from other posts anyway but putting it all together and putting in failsafes was the trick I, and hopefully others, needed