dynamic user profile change using script

I want to create script which would change user profile after user reach byte limit, eg. when user reach 20GB of download, change his profile to 128kbps/128kbps. I think it is the easiest way to do it on user login. Could someone help me?

Try this script on user login, tested on v5.22

It checks user total download bytes, and if it exceeds 20GB, it checks the profile limits and changes current queue and profile accordingly.
:local newLimit 128k/128k;
:local maxBytes 21474836480;

:local userStr [:tostr $user];

:local ip [/ip hotspot active get [find user=“$userStr”] address];
:local bytes [/ip hotspot user get [find name=“$userStr”] bytes-out];
:local profile [/ip hotspot user get [find name=“$userStr”] profile];
:local rateLimit [/ip hotspot user profile get [find name=“$userStr”] rate-limit];

:if ($bytes > $maxBytes) do={
:if ($rateLimit != $newLimit) do={
/log info “[DOWNLOAD LIMIT] - $userStr has exceeded $maxBytes bytes downloaded, limiting profile to $newLimit”;
/queue simple set [find target-addresses=“$ip/32”] max-limit=$newLimit limit-at=$newLimit;
/ip hotspot user profile set [find name=“$profile”] rate-limit=$newLimit;
}
}

Thanks Skot!

Playing with scripts seen on the forum I’ve already made one that seems working, here it is:
#Download limit 20GB
:local downquotaGB “20”
:local slowprofile “free(128/128)” (this is profile already defined and existing on RB)

Do not modify anything below this line

:local counter
:local currentprofile
:local datadown
:foreach counter in=[/ip hotspot user find ] do={
:set datadown ([/ip hotspot user get $counter bytes-out]/1074000000)
:set currentprofile [/ip hotspot user get $counter profile]
:if (($datadown>=$downquotaGB) and ($currentprofile!=$slowprofile)) do={
/ip hotspot user set $counter profile=$slowprofile
:log warning “USER $[/ip hotspot user get $counter name] CROSSED LIMIT, PROFILE CHANGED TO $slowprofile
}
}

I’ll check yours too.
Do you know how to trigger the action in the script by user logon? And how to keep colors in the code when posting, as you did?

Thanks again!

Using Winbox/Webfig, go to: IP > Hotspot > User Profiles Tab > Open the desired profile > Scripts Tab > put script in the On Login box


When you add a post, highlight the code and select Router OS from the Select a Syntax drop down
s.png

hi skot. sorry for my bad english. I have the same problem with Zarko. I’ve followed the code that you write over and nothing happens. queue settings are needed for this case? how its queue settings? thanks :slight_smile:

The code is designed specifically for a hotspot. Are you putting the code into the hotspot User Profile On Login box?

omg, i put it in the script mikrotik.. sorry. okay thanks Scots. I will try it first

hi skot, I have put it in the box on the login but still no change :frowning:



I try to test with 1 user dummy that I had prepared to download a file at a specific site using internet download manager app, but the transfer rate that I can remain in the application in accordance with the settings.


whether you think the right parameters to specify the script runs fine? how to test the script right? I need this script for my final project in college. sorry if it’s too much to ask :slight_smile:

this is my screenshoot
1.png
2.png
~edited~

Well, here is more mature code, which does the following:
-Checks the downloaded quota of hotspot user, and if it is over the limit - change user profile to slower one
-Resets counters on the first day of the moth
-Recover the original profile of hotspot user after counter reset
-Send mail with info, every day
-Log the actions
May be helpful for someone. It is working perfectly on 5.23.
#Download limit 20GB
:local downquotaGB “20”
:local slowprofile “free(128/128)”
:local fastprofile “free(768/128)”

Do not modify anything below this line

:local counter
:local currentprofile
:local datadown
:local printout “User download before counters reset:\r\n”
:local name
:local day
#Check if it is first day of the month, and if yes, reset counters
:if ([:pick [/system clock get date] 4 6]=“01” ) do={
/ip hotspot user reset-counters
:set printout “$printout Monthly reset DONE\r\n”
:log warning “SCRIPT -ProfileChecker- DONE (counters resetted)
} else={
:log warning “SCRIPT -ProfileChecker- DONE
}
#Checks the quota and profiles of all enabled users
:foreach counter in=[/ip hotspot user find ] do={
:set datadown ([/ip hotspot user get $counter bytes-out]/1074000000)
:set currentprofile [/ip hotspot user get $counter profile]
:set name ([/ip hotspot user get $counter name])
:if (![/ip hotspot user get $counter disabled]) do={set printout “$printout $name → $datadown GB \r\n”}
:if (($datadown>=$downquotaGB) and ($currentprofile!=$slowprofile)) do={
/ip hotspot user set $counter profile=$slowprofile
:log warning “USER $[/ip hotspot user get $counter name] CROSSED LIMIT, PROFILE CHANGED TO $slowprofile
:set printout “$printout USER $name CROSSED LIMIT, PROFILE CHANGED TO $slowprofile\r\n”
}
:if (($datadown<$downquotaGB) and ($currentprofile=$slowprofile)) do={
/ip hotspot user set $counter profile=$fastprofile
:log warning “USER $[/ip hotspot user get $counter name] BELOW LIMIT, PROFILE CHANGED BACK TO $fastprofile
:set printout “$printout USER $name BELOW LIMIT, PROFILE CHANGED BACK TO $fastprofile\r\n”
}
}
#Send mail with info about the results from the script
/tool e-mail send server=173.194.70.108 port=25 user=xyz@gmail.com password=xxxxxxx
from=xyz@gmail.com tls=yes to=xyz@gmail.com subject=ProfileChecker-DONE! body=$printout

The script specifically checks for the limit zarko requested, 20GB:
:local maxBytes 21474836480;Your screenshot only shows a total of 1100.3 kiB, so the limit has not been reached. For testing, change the number above to a limit you will reach, and then log out/in to re-test.

hi zarko. thank you for your participation, but the script that I need only to limit hotspot. but I’ve tried and I needed to take part, still does not happen :frowning:

I limit the quota in the number 3 mb
:local maxBytes 3145728;and I repeatedly tested still nothing happened :frowning:


This is my setting
4.png




testing before passing 3 mb
3.png
testing after passing 3 mb
5.png
please help me where the settings are wrong: (
I have reset the counter at ip / hotspot reset all counters but still nothing happens: (

Just to clarify, what do you want to do?

  1. Change the profile’s Rate Limit for the user (under User Profiles tab) -or-
  2. Change which profile is assigned to the user (under the Users tab)

The script was designed to do the first option.


I do see one problem from the screenshots. The first line was changed to this:
:local slowProfile 80k/80k;From the original script, the only things you should have to change would be the values in the first two lines, not the variable names. So it would look something like this:
:local newLimit 80k/80k;
:local maxBytes 3145728;When a user logs in, if they have reached the maxBytes value, their assigned profile (under User Profiles) will change, and their Simple Queue will change. (They will not be assigned a different profile)


The way I would go about testing this is to enclose the whole script in brackets so that :local variables don’t error out. Then, change ther userStr variable to an existing User name. Now, you can copy/paste the script into a terminal window for testing. You can then use the :put command to view variable values to make sure they are doing what you want. For example, :put $bytes will show you the value of the $bytes variable. Etc.
{
:local newLimit 80k/80k;
:local maxBytes 3145728;

#:local userStr [:tostr $user];
:local userStr “tes1”;

:local ip [/ip hotspot active get [find user=“$userStr”] address];
:local bytes [/ip hotspot user get [find name=“$userStr”] bytes-out];
:put $bytes;
:local profile [/ip hotspot user get [find name=“$userStr”] profile];
:local rateLimit [/ip hotspot user profile get [find name=“$userStr”] rate-limit];

:if ($bytes > $maxBytes) do={
:if ($rateLimit != $newLimit) do={
/log info “[DOWNLOAD LIMIT] - $userStr has exceeded $maxBytes bytes downloaded, limiting profile to $newLimit”;
/queue simple set [find target-addresses=“$ip/32”] max-limit=$newLimit limit-at=$newLimit;
/ip hotspot user profile set [find name=“$profile”] rate-limit=$newLimit;
}
}
}HTH

with all due respect to you Scots, but I have follow your way back,

to make a copy / paste your script in the login box unlimited user profile, and then I reset all the counters on the simple queue and user hotspot hotspot (tes1), still nothing happens when I test downloading data fil * hippo.com site with downloadable apps default browser (goo * e ch * me).

indeed of the script that you appear not show the slightest sign of error, but after I tried to do testing, still no change, either on the download speed is obtained or at the speed indicated in the simple queue or on a log the info though.

once again I apologize for my impudence in asking. My only final year students who are studying more on mikrotik script :slight_smile:

I attach below my settings
[fadli@MikroTik] > ip hotspot profile print
Flags: * - default
0 * name=“default” hotspot-address=0.0.0.0 dns-name=“” html-directory=hotspot
rate-limit=“” http-proxy=0.0.0.0:0 smtp-server=0.0.0.0 login-by=http-chap
split-user-domain=no use-radius=no

1 name=“hsprof1” hotspot-address=192.168.1.1 dns-name=“” html-directory=hotspot
rate-limit=“” http-proxy=0.0.0.0:0 smtp-server=0.0.0.0 login-by=http-chap
split-user-domain=no use-radius=yes radius-accounting=yes
radius-interim-update=received nas-port-type=wireless-802.11
radius-default-domain=“” radius-location-id=“” radius-location-name=“”
radius-mac-format=XX:XX:XX:XX:XX:XX/ip hotspot user profile> print
Flags: * - default
0 * name=“default” address-pool=pool1 idle-timeout=none keepalive-timeout=2m
status-autorefresh=1m shared-users=1 transparent-proxy=no

1 name=“unlimited” idle-timeout=none keepalive-timeout=2m status-autorefresh=1m
shared-users=5 on-login={\r\n:local newLimit 80k/80k;\r\n:local maxBytes
3145728;\r\n \r\n#:local userStr [:tostr $user];\r\n:local userStr
“tes1”;\r\n \r\n \r\n:local ip [/ip hotspot active get [find
user=“$userStr”] address];\r\n:local bytes [/ip hotspot user get [find
name=“$userStr”] bytes-out];\r\n:put $bytes;\r\n:local profile [/ip
hotspot user get [find name=“$userStr”] profile];\r\n:local rateLimit [/ip
hotspot user profile get [find name=“$userStr”] rate-limit];\r\n \r\n:if
($bytes > $maxBytes) do={\r\n :if ($rateLimit != $newLimit) do={\r\n
/log info “[DOWNLOAD LIMIT] - $userStr has exceeded $maxBytes bytes
downloaded, limiting profile to $newLimit”;\r\n /queue simple set
[find target-addresses=“$ip/32”] max-limit=$newLimit limit-
at=$newLimit;\r\n /ip hotspot user profile set [find name=“$profile”]
rate-limit=$newLimit;\r\n }\r\n}\r\nqueue simple print
Flags: X - disabled, I - invalid, D - dynamic
0 D name=“hs-” target-addresses=“” interface=wlan parent=none
packet-marks=“” direction=both priority=8
queue=hotspot-default/hotspot-default limit-at=0/0 max-limit=0/0
burst-limit=0/0 burst-threshold=0/0 burst-time=0s/0s
total-queue=default-small07:10:04 wireless,info 20:16:D8:46:F9:35@wlan: connected
07:10:14 hotspot,info,debug tes1 (192.168.1.12): trying to log in by http-chap
07:10:14 hotspot,account,info,debug tes1 (192.168.1.12): logged in
07:13:34 system,info,account user fadli logged in from 192.168.1.12 via winbox
07:14:52 system,info hotspot user profile slowProfile removed by fadli
07:14:58 system,info hotspot user tes2 changed by fadli
07:16:41 system,info,account user fadli logged in from 192.168.1.12 via telnet
07:25:52 system,info,account user fadli logged out from 192.168.1.12 via winbox
07:26:03 system,info hotspot user profile unlimited changed by fadli
07:58:17 system,info,account user fadli logged in from 192.168.1.12 via telnet
08:02:54 system,info,account user fadli logged out from 192.168.1.12 via winbox
08:02:54 system,info,account user fadli logged out from 192.168.1.12 via telnet
08:02:54 system,info,account user fadli logged out from 192.168.1.12 via telnet
08:02:58 hotspot,info,debug tes1 (192.168.1.12): logged out: user request
08:03:05 hotspot,info,debug tes1 (192.168.1.12): trying to log in by http-chap
08:03:07 hotspot,info,debug tes1 (192.168.1.12): login failed: invalid username or pa
ssword
08:03:14 hotspot,info,debug tes1 (192.168.1.12): trying to log in by http-chap
08:03:16 hotspot,info,debug tes1 (192.168.1.12): login failed: invalid username or pa
ssword
08:03:28 hotspot,info,debug tes1 (192.168.1.12): trying to log in by http-chap
08:03:28 hotspot,account,info,debug tes1 (192.168.1.12): logged in
08:03:47 system,info,account user fadli logged in from 192.168.1.12 via winbox
08:04:03 system,info hotspot user tes2 changed by fadli
08:04:10 system,info hotspot user tes3 changed by fadli
08:04:12 system,info hotspot user tes3 changed by fadli
08:04:14 system,info hotspot user tes2 changed by fadli
08:05:53 wireless,info 6C:71:D9:23:7F:77@wlan: connected
08:05:53 dhcp,info server1 deassigned 192.168.1.20 from 6C:71:D9:23:7F:77
08:05:56 dhcp,info server1 assigned 192.168.1.20 to 6C:71:D9:23:7F:77
08:14:55 wireless,info 74:DE:2B:7A:FF:03@wlan: connected
08:16:31 hotspot,info,debug tes2 (192.168.1.19): trying to log in by http-chap
08:16:31 hotspot,account,info,debug tes2 (192.168.1.19): logged in
08:19:49 system,info,account user fadli logged in from 192.168.1.12 via telnet[fadli@MikroTik] /ip pool>> print append detail
0 name=“pool1” ranges=192.168.1.11-192.168.1.50ip dns print interval=1
servers: 8.8.8.8
dynamic-servers:
allow-remote-requests: yes
max-udp-packet-size: 4096
cache-size: 2048KiB
cache-max-ttl: 1w
cache-used: 66KiB
7.png
8.png
9.png
please correct me if I’m wrong.
I was really depressed with this.thank you

What version of RouterOS are you using?

Which option do you want to do?

  1. Change the profile’s Rate Limit for the user? (under User Profiles tab) - (this is the way it currently works)
  2. Change which profile is assigned to the user? (under the Users tab)

What do you have under the User Profiles tab?

I’m using RouterOS v5.24
I’m selecting the first option, change the profile rate limit.
in the user profile tab, I have a profile (unlimited) with unlimited rate limit. I have filled on login box with your script. current user (tes1) has passed maxBytes(3145728), the user (tes1) does not limit to newLimit (80k/80k)

any solution Skot?

sir how to change $maxBytes to limits bytes Total
your script working on maxBytes
Thanks in advance

your script is working Good like it
for 30GB
:local maxBytes 32212254720;
:local newProfile “payment”;

:local userStr [:tostr $user];

:local bytes [/ip hotspot user get [find name=“$userStr”] bytes-out];
:local profile [/ip hotspot user get [find name=“$userStr”] profile];

:if ($bytes > $maxBytes) do={
:if ($profile != $newProfile) do={
/log info “[DOWNLOAD LIMIT] - $userStr has exceeded $maxBytes bytes downloaded, changing profile”;
/ip hotspot user set [find name=“$userStr”] profile=“$newProfile”
}
}