:local counter [/interface get lte1 rx-bytes] :set $counter ($counter + [/interface get lte1 tx-bytes]) :local traffic :if ([:len [/file find where name=counter.txt]] < 1 ) do={ /file print file=counter.txt where name=counter.txt; /delay delay-time=2; /file set counter.txt contents="0"; }; :local before value=[/file get counter.txt contents] :if ($counter > $before) do={ /file set counter.txt contents=$counter } else= { :set $traffic ($counter+$before) /file set counter.txt contents=$traffic };The second script is run every 15 minutes which checks the traffic usage and issues a warning email at 80% and triggers the stoplte script at 100%:
:local traffic ([/file get traffic.txt contents] / 1000 / 1000 / 1000) #set the LTE quota in GB :local limit 30 :local percent ($traffic*100 / $limit) :if ([:len [/file find where name=warning.txt]] < 1 ) do={ /file print file=warning.txt where name=warning.txt; /delay delay-time=2; /file set warning.txt contents=$percent; :if ($percent < 50) do={ #any action you like - maybe you want to issue daily reports, warnings at 50% or whatsoever } } else={ :if ($percent < 79) do={ /file set warning.txt contents=$percent; :log info "Traffic at $percent%" } else={ :if (($percent >=80) && ($traffic <$limit)) do={ :if ([/file get warning.txt contents] <> "99") do={ /tool e-mail send to=<youremailaddress> subject="Traffic warning: $percent% reached at $[/system clock get date], $[/system clock get time]" body="The actual traffic amount is $traffic GB \r\nThis is $percent% of the monthly limit\r\n\" /file set warning.txt contents="99" :log warning "Warning message sent at $percent%"}; } else={ :if ($percent >= 100) do={ /system script run stoplte } } } }The stoplte script disables the interface and all related NAT-rules as well as the default route to lte1.
Can you already share your script. I would highly appreciate it!<as this is firstly commercially sold I removed the information, I will add it later>
Dear Maikel,
Can you already share your script. I would highly appreciate it!<as this is firstly commercially sold I removed the information, I will add it later>
Thanks & best regards,
Peter
Dear Peter and Chris,Hi maikel,
I would also be very interested in your new and improved script if you're willing!
Thanks,
Chris
#This first script is scheduled to run every 5 minutes. It collects the traffic of lte1 (sums up tx and rx bytes)
#and writes different data to multiple files. Kudos to Christopher Diedrich: https://forum.mikrotik.com/viewtopic.php?t=87565#
#Creator: Maikel Egberink Robacomm.nl
#The following crontab rule is essential for the correct execution of this script:
#
#Please crontab as follow: */5 * * * * which lets cron starts this script every 5 min, e.g. 21:40,21:45,21:50,21:55
#
#Get newest tx- and rx-data from interface and put in var $newdata
:local interf "ether2"
:global newdata
:global tx [/interface get $interf tx-byte]
:put "tx: $tx"
:global rx [/interface get $interf rx-byte]
:put "rx: $rx"
:set $newdata ( $rx + $tx )
:put "Newdata value: $newdata"
#
#Check if freedata is applicable
:local curtime [/system clock get time]
:put "Current time value: $curtime"
#Example: freedata is from 0:00:00 until 6:00:00 (when changing times please change if-then's too
:local startfreedata 0:00:00
:local beforestartfreedata 23:59:59
:local stopfreedata 6:00:00
:local freedata
#Between freedata-times count freedata
:if ( $curtime >= $startfreedata && $curtime <= $stopfreedata ) do={
:set $freedata true
:put "Freedata applicable"
};
#Later than (latest) freedata-times count no freedata. Cannot look before 0:00:00, so always later than 0:00:00
:if ( $curtime > $stopfreedata && $curtime < $beforestartfreedata ) do={
:set $freedata false
:put "Freedata NOT applicable"
};
:put "Freedata is set to: $freedata"
#
#Check if files are already created;
:local fileref "refcount.txt"
:local filename "counter.txt"
:local filefree "freecount.txt"
#Check if file refcount.txt not exists, then do (1=exist, 0=not exist)
:if ([:len [/file find where name=$fileref]] < 1 ) do={
#Create new file
/file print file=$fileref where name=$fileref;
#Wait 2 sec
/delay delay-time=2;
#Put value 0 in file contents
/file set $fileref contents=0;
:put "New file $fileref is created with content 0"
};
#Check if file counter.txt not exists, then do (1=exist, 0=not exist)
:if ([:len [/file find where name=$filename]] < 1 ) do={
#Create new file
/file print file=$filename where name=$filename;
#Wait 2 sec
/delay delay-time=2;
#Put value 0 in file contents
/file set $filename contents=0;
:put "New file $filename is created with content 0"
}
#Check if file freecount.txt not exists, then do (1=exist, 0=not exist)
:if ([:len [/file find where name=$filefree]] < 1 ) do={
#Create new file
/file print file=$filefree where name=$filefree;
#Wait 2 sec
/delay delay-time=2;
#Put value 0 in file contents
/file set $filefree contents=0;
:put "New file $filefree is created with content 0"
};
#
:local ref
#Reference file stores the $newdata value on 1st of the month at 0:00 after script 'resetfiles-mikrotik-x.x' ran
#If there is no value (0) in refcount.txt then put contents to file from var newdata
#If there is a value in refcount.txt then read it and put it in var ref
:set $ref [/file get $fileref contents]
:put "Reference value from $fileref: $ref"
:if ( $ref = 0 ) do={
#Write var $newdata to file
/file set $fileref contents=$newdata
#Wait 2 sec
/delay delay-time=2;
:put "Reference data $newdata put in $fileref"
:log info "Freedatascripts: Reference data $newdata put in $fileref"
};
#
#When freedata is applicable then count bytes during freedata (not total interface bytes) and write it to freecount.txt.
:local before
:local correct
:local free
#
#Freedata is applicable; write bytes to freecount.txt
#Check if freedata; >0:00 and < 6:00 do
:if ( $freedata = true ) do={
#:put "if freecount true do"
#Read freecount.txt (last freedata)
:set $free [/file get $filefree contents]
:put "Previous Free value from $filefree: $free"
#When newdata is lower than before (e.g. when interface reset) do
:if ( $newdata < $free ) do={
#:put "freedata true if newdata < before do"
#Correct reference file when counters did reset (to prevent reset value, this way we remember 'old' bytes)
/file set $fileref contents=$newdata
#correct value written to freecount.txt (we suppose that 5 min before also was freedata)
:set $correct ( $free + $newdata )
#Write corrected value to freecount.txt
/file set $filefree contents=$correct
:put "Writen $correct to $filefree"
} else={
#:put "freedata true else newdata < before do"
:if ( $newdata >= $free ) do={
#:put "freedata true if newdata >= before do"
#Read reference data and set freedata
:set $ref [/file get $fileref contents]
#The var $newdata is now only the actual bytes used from 01-mm-yyyy 0:00:00
:set $newdata ( $newdata - $ref )
:put "Variable newdata is now set to new value: $newdata"
#Newest data from interface - content of counter.txt + contents of freecount.txt
:set $free ( $newdata - $free )
#Write updated data to freecount.txt
/file set $filefree contents=$free
:put "Written $free to $filefree"
};
};
};
#
#Freedata is not applicable; write bytes to counter.txt
#Check if not freedata; > 6:00 and <23:59 do
:if ( $freedata = false ) do={
#:put "if freedata false"
#Read contents from file counter.txt (no freetime) and puts it in var $before
:set $before [/file get $filename contents]
:put "Previous Before value from $filename: $before"
#When newdata is lower than before (e.g. when interface reset) do
:if ( $newdata < $before ) do={
#:put "freedata false if newdata < before do"
#Correct reference file
/file set $fileref contents=$newdata
#correct value written to counter.txt (to prevent reset value, this way we remember 'old' bytes)
:set $correct ( $before + $newdata )
#Write corrected value to counter.txt
/file set $filename contents=$correct
:put "Written $correct to $filename"
} else={
:if ( $newdata >= $before ) do={
#:put "freedata false if newdata >= before do"
#Read reference data and set counterdata
:set $ref [/file get $fileref contents]
#The var $newdata is now only the actual bytes used from 01-mm-yyyy 0:00:00
:set $newdata ( $newdata - $ref )
:put "Variable newdata is now set to new value: $newdata"
#Write newdata value to counter.txt
:set $correct ( $newdata - $free )
/file set $filename contents=$correct
:put "Written $newdata to $filename"
};
};
};
#This second script is scheduled to run every 15 minutes. It checks the traffic usage and issues a warning email at 80%
#and triggers the stoplte script at 100%. Kudos to Christopher Diedrich: https://forum.mikrotik.com/viewtopic.php?t=87565#
#Creator: Maikel Egberink Robacomm.nl
#The following crontab rule is essential for the correct execution of this script:
#
#Please crontab as follow: */15 * * * * which lets cron starts this script every 15 min, e.g. 21:30,21:45,22:00,22:15
#
#Wait for script one; freedata-mikrotik0.2 for 5 seconds
:local interf "ether2"
:put "Wait for 5 seconds to finish first script"
/delay delay-time=5
:local filecount "counter.txt"
:local filewarn "warning.txt"
:local traffic ([/file get $filecount contents] / 1024 / 1024 / 1024)
:put "Registered amount of data is now: $traffic GB"
#Set the interface quota in GB;
:local limit 100
:put "Quota is set to: $limit GB"
#Calculate percents
:local percent ($traffic*100 / $limit)
:put "$percent % is now reached until set quota of $limit GB"
#
#Check if file is already created. Check if file warning.txt not exists, then do (1=exist, 0=not exist)
:if ([:len [/file find where name=$filewarn]] < 1 ) do={
/file print file=$filewarn where name=$filewarn
/delay delay-time=2
/file set $filewarn contents=$percent
};
#Write precentage to file
/file set $filewarn contents=$percent
#
#Select action according to percentage reached until quota
:if ($percent < 50) do={
#any action you like - maybe you want to issue daily reports, warnings at 50% or whatsoever
:log info "Traffic on $interf at $percent %"
:log info "Freedatascripts: Traffic on $interf at $percent%"
/tool e-mail send to=maikel@robacomm.nl subject="Traffic warning: $percent% reached at $[/system clock get date], $[/system clock get time]" body="The actual traffic amount is $traffic GB \r\nThis is $percent% of the monthly limit of $limit GB\r\nThis email is automatically generated by Freedatascript on mikrotik router at CarpeDiem, please do not reply\r\n\"
} else={
:if ($percent < 79) do={
#Write percentage to file
:set $percent [/file get $filewarn contents]
:put "Traffic on $interf at $percent % (less than 79%)"
#:log info "Freedatascripts: Traffic on $interf at $percent%"
} else={
:if (($percent >=80) && ($traffic < $limit)) do={
#Send email one time when percentage is over 80% and traffic is not reached quota yet
:if ([/file get $filewarn contents] <> 99) do={
#/tool e-mail send to=<youremailaddress> subject="Traffic warning: $percent% reached at $[/system clock get date], $[/system clock get time]" body="The actual traffic amount is $traffic GB \r\nThis is $percent% of the monthly limit\r\n\"
/file set $filewarn contents=99
:put "Traffic on $interf at $percent % (80% and over) -99 in file and email sent-"
:log warning "Freedatascripts: Warning message sent for $interf at $percent%"
}
} else={
:if ($percent >= 100) do={
/file set $filewarn contents=$percent
:put "Traffic at $percent % (100% or over) -stop interface-"
/system script run stoplte
};
};
};
};
#This script ran daily at midnight which checks if it's the first of the month and then enables lte1 (and all rules/routes)
#and resets the counters and warnings. Kudos to Christopher Diedrich: https://forum.mikrotik.com/viewtopic.php?t=87565#
#Creator: Maikel Egberink Robacomm.nl
#The following crontab rule is essential for the correct execution of this script:
#
#Please crontab as follow: 0 0 * 1 * which lets cron starts this script every 1st of every month
#
:local interf "ether2"
:local curdate [/system clock get date]
:put "Current date value: $curdate"
:local fileref "refcount.txt"
:local filename "counter.txt"
:local filefree "freecount.txt"
:local filewarn "warning.txt"
:local day [ :pick $curdate 4 6 ];
:put $day
:if ( $day = 1 ) do={
:put "Today is 1th of the month, resetting all counters..."
#RAM
:put "Resetting counters on RAM..."
:put "Resetting counter for regular data $filename ..."
/file set $filename contents=0
:put "Resetting counter for free data $filefree ..."
/file set $filefree contents=0
:put "Resetting counter for warnings $filewarn ..."
/file set $filewarn contents=0
:put "Resetting counter for reference data $fileref ..."
/file set $fileref contents=0
#enable interface, which might be disabled after reaching 100% data-usage
:put "Enabling interface LTE..."
#/interface ethernet set $interf disabled=no
:put "The interface is enabled"
:log info "Freedatascripts: All counters are reset to 0, interface $interf is enabled"
};
:if ( $day = 13 ) do={
:log info "Freedatascripts: test 00:00:01 13th day"
};
#This script stops interface when the quota is reached (100%)
#Change the interfacename here;
:local interf "ether2"
#Uncomment the following rules for running scripts in production;
#/interface ethernet set $interf disabled=yes
#:put "The interface is disabled"
#:log warning "Interface $interf is DISABLED due to reached datalimit"
:local filename counter.txt
:local fileref refcount.txt
:local filefree freecount.txt
:local filewarn warning.txt
#:put "-- Reference point made when the freedatascripts started running (1st of the month) --"
:put "-- Referentie/Ijkpunt gemaakt wanneer de freedatascripts zijn gestart (1ste vd maand) --"
:set $ref [/file get $fileref contents]
#:put "Reference value from $fileref: $ref in bytes"
:put "Referentie waarde vanuit $fileref: $ref in bytes"
#:put "-- Registered amount of data during NON-free data times --"
:put "-- Geregistreerde hoeveelheid data tijdens NIET-vrije data tijden --"
:set $before [/file get $filename contents]
#:put "Counted bytes value from $filename: $before"
:put "Getelde bytes waarde vanuit $filename: $before"
:local beforemb ( $before / 1024 / 1024 )
#:put "Counted Megabytes value from $filename: $beforemb"
:put "Getelde Megabytes waarde vanuit $filename: $beforemb"
:local beforegb ( $before / 1024 / 1024 / 1024 )
:put "Getelde Gigabytes waarde vanuit $filename: $beforegb"
#:put "-- Registered amount of data during FREE data times --"
:put "-- Geregistreerde hoeveelheid data tijdens VRIJE data tijden --"
:set $free [/file get $filefree contents]
#:put "Counted bytes value from $filefree: $free"
:put "Getelde bytes waarde vanuit $filefree: $free"
:local freemb ( $free / 1024 / 1024 )
#:put "Counted Megabytes value from $filename: $freemb"
:put "Getelde Megabytes waarde vanuit $filename: $freemb"
:local freegb ( $free / 1024 / 1024 / 1024 )
#:put "Counted Gigabytes value from $filename: $freegb"
:put "Getelde Gigabytes waarde vanuit $filename: $freegb"
#:put "-- Amount of GB when interface has to be switched off --"
:put "-- Waarde in GB wanneer de interface uitgeschakeld moet worden --"
#:put "The limit is set to: $limit GB"
:put "De limiet is ingesteld op: $limit GB"
:set $percent [/file get $filewarn contents]
#:put "Counted traffic data is now at $percent %"
:put "Getelde traffic data is nu op $percent %"
Very welcomeHi Maikel,
thanks so much for sharing!
I will try to implement it in the wAP LTE kit counting LTE traffic.
Best regards,
Peter
For LTE:
# /$$ /$$$$$$$$/$$$$$$$$ /$$ /$$ /$$ /$$
# | $$ |__ $$__/ $$_____/| $$ |__/ |__/ | $$
# | $$ | $$ | $$ | $$ /$$ /$$$$$$/$$$$ /$$ /$$$$$$ /$$$$$$ /$$$$$$
# | $$ | $$ | $$$$$ | $$ | $$| $$_ $$_ $$| $$|_ $$_/ /$$__ $$ /$$__ $$
# | $$ | $$ | $$__/ | $$ | $$| $$ \ $$ \ $$| $$ | $$ | $$$$$$$$| $$ \__/
# | $$ | $$ | $$ | $$ | $$| $$ | $$ | $$| $$ | $$ /$$| $$_____/| $$
# | $$$$$$$$| $$ | $$$$$$$$| $$$$$$$$| $$| $$ | $$ | $$| $$ | $$$$/| $$$$$$$| $$
# |________/|__/ |________/|________/|__/|__/ |__/ |__/|__/ \___/ \_______/|__/
#
# Using: Set all var in User config section. Add scripts to schedule with onstart and interval 30 sek
:do {
#######################################################################################################
# User config
#Set limit in MB
:local limit 12288
#Set day to reset limit
:local dayresetlimit 1
#Set interface
:local interf "lte1"
#Set auto bring up interface
:local autointon true
#######################################################################################################
:local filename "counter.txt"
:local filewarn "warning.txt"
:local fileref "refcount.txt"
:local reblock "reblock.txt"
:local status
:if ([:len [/file find where name=$filewarn]] < 1 ) do={
/file print file=$filewarn where name=$filewarn
/delay delay-time=2
/file set $filewarn contents=$percent
};
:if ([:len [/file find where name=$filename]] < 1 ) do={
/file print file=$filename where name=$filename
/delay delay-time=2;
/file set $filename contents=0
}
:if ([:len [/file find where name=$reblock]] < 1 ) do={
/file print file=$reblock where name=$reblock
/delay delay-time=2;
/file set $reblock contents=1
}
:if ([:len [/file find where name=$fileref]] < 1 ) do={
/file print file=$fileref where name=$fileref
/delay delay-time=2;
/file set $fileref contents=0
}
:local reblocker ([/file get $reblock contents])
:local curdate [/system clock get date]
:local day [ :pick $curdate 4 6 ]
:if ( $day = $dayresetlimit and $reblocker = 0) do={
/file set $filename contents=0
/file set $filewarn contents=0
/file set $fileref contents=0
/interface lte set $interf disabled=no
/file set $reblock contents=1
:log info "Limit reset, int $interf bring up"
/delay delay-time=5;
:log info "Clear int counters - reboot"
#TODO find another method for interf clear counters
/system reboot
}
:if ( $day != $dayresetlimit ) do={
/file set $reblock contents=0
}
:local before
:local correct
:local ref
:local newdata
:local tx [/interface get $interf tx-byte]
:local rx [/interface get $interf rx-byte]
:set $newdata (( $rx + $tx ) / 1024 / 1024 )
:set $before [/file get $filename contents]
:if ( $newdata < $before ) do={
:set $ref [/file get $fileref contents]
:set $correct ( $before + $newdata - $ref )
/file set $fileref contents=$newdata
/file set $filename contents=$correct
}
:if ( $newdata >= $before ) do={
/file set $filename contents=$newdata
}
:local traffic ([/file get $filename contents])
:log warning "Limit: $limit MB"
:local percent ($traffic*100 / $limit)
:log warning "Use: $percent%"
/file set $filewarn contents=$percent
:if ($percent >= 100) do={
/file set $filewarn contents=$percent
/interface lte set $interf disabled=yes
}
:if ($percent < 100 and $autointon = true) do={
:set $status [/interface get $interf value-name=disabled]
:if ($status = true) do={
/interface lte set $interf disabled=no
}
}
} on-error={ :log error "Error LTELimiter "};
for PPP-Client
# /$$ /$$$$$$$$/$$$$$$$$ /$$ /$$ /$$ /$$
# | $$ |__ $$__/ $$_____/| $$ |__/ |__/ | $$
# | $$ | $$ | $$ | $$ /$$ /$$$$$$/$$$$ /$$ /$$$$$$ /$$$$$$ /$$$$$$
# | $$ | $$ | $$$$$ | $$ | $$| $$_ $$_ $$| $$|_ $$_/ /$$__ $$ /$$__ $$
# | $$ | $$ | $$__/ | $$ | $$| $$ \ $$ \ $$| $$ | $$ | $$$$$$$$| $$ \__/
# | $$ | $$ | $$ | $$ | $$| $$ | $$ | $$| $$ | $$ /$$| $$_____/| $$
# | $$$$$$$$| $$ | $$$$$$$$| $$$$$$$$| $$| $$ | $$ | $$| $$ | $$$$/| $$$$$$$| $$
# |________/|__/ |________/|________/|__/|__/ |__/ |__/|__/ \___/ \_______/|__/
#
# Using: Set all var in User config section. Add scripts to schedule with onstart and interval 30 sek
:do {
#######################################################################################################
# User config
#Set limit in MB
:local limit 12288
#Set day to reset limit
:local dayresetlimit 1
#Set interface
:local interf "ppp-out1"
#Set auto bring up interface
:local autointon true
#######################################################################################################
:local filename "counter.txt"
:local filewarn "warning.txt"
:local fileref "refcount.txt"
:local reblock "reblock.txt"
:local status
:if ([:len [/file find where name=$filewarn]] < 1 ) do={
/file print file=$filewarn where name=$filewarn
/delay delay-time=2
/file set $filewarn contents=$percent
};
:if ([:len [/file find where name=$filename]] < 1 ) do={
/file print file=$filename where name=$filename
/delay delay-time=2;
/file set $filename contents=0
}
:if ([:len [/file find where name=$reblock]] < 1 ) do={
/file print file=$reblock where name=$reblock
/delay delay-time=2;
/file set $reblock contents=1
}
:if ([:len [/file find where name=$fileref]] < 1 ) do={
/file print file=$fileref where name=$fileref
/delay delay-time=2;
/file set $fileref contents=0
}
:local reblocker ([/file get $reblock contents])
:local curdate [/system clock get date]
:local day [ :pick $curdate 4 6 ]
:if ( $day = $dayresetlimit and $reblocker = 0) do={
/file set $filename contents=0
/file set $filewarn contents=0
/file set $fileref contents=0
/interface ppp-client set $interf disabled=no
/file set $reblock contents=1
:log info "Limit reset, int $interf bring up"
/delay delay-time=5;
:log info "Clear int counters - reboot"
#TODO find another method for interf clear counters
/system reboot
}
:if ( $day != $dayresetlimit ) do={
/file set $reblock contents=0
}
:local before
:local correct
:local ref
:local newdata
:local tx [/interface get $interf tx-byte]
:local rx [/interface get $interf rx-byte]
:set $newdata (( $rx + $tx ) / 1024 / 1024 )
:set $before [/file get $filename contents]
:if ( $newdata < $before ) do={
:set $ref [/file get $fileref contents]
:set $correct ( $before + $newdata - $ref )
/file set $fileref contents=$newdata
/file set $filename contents=$correct
}
:if ( $newdata >= $before ) do={
/file set $filename contents=$newdata
}
:local traffic ([/file get $filename contents])
:log warning "Limit: $limit MB"
:local percent ($traffic*100 / $limit)
:log warning "Use: $percent%"
/file set $filewarn contents=$percent
:if ($percent >= 100) do={
/file set $filewarn contents=$percent
/interface ppp-client set $interf disabled=yes
}
:if ($percent < 100 and $autointon = true) do={
:set $status [/interface get $interf value-name=disabled]
:if ($status = true) do={
/interface ppp-client set $interf disabled=no
}
}
} on-error={ :log error "Error ppp-clientLimiter "};
Hello
For LTE:Code: Select all# /$$ /$$$$$$$$/$$$$$$$$ /$$ /$$ /$$ /$$ # | $$ |__ $$__/ $$_____/| $$ |__/ |__/ | $$ # | $$ | $$ | $$ | $$ /$$ /$$$$$$/$$$$ /$$ /$$$$$$ /$$$$$$ /$$$$$$ # | $$ | $$ | $$$$$ | $$ | $$| $$_ $$_ $$| $$|_ $$_/ /$$__ $$ /$$__ $$ # | $$ | $$ | $$__/ | $$ | $$| $$ \ $$ \ $$| $$ | $$ | $$$$$$$$| $$ \__/ # | $$ | $$ | $$ | $$ | $$| $$ | $$ | $$| $$ | $$ /$$| $$_____/| $$ # | $$$$$$$$| $$ | $$$$$$$$| $$$$$$$$| $$| $$ | $$ | $$| $$ | $$$$/| $$$$$$$| $$ # |________/|__/ |________/|________/|__/|__/ |__/ |__/|__/ \___/ \_______/|__/ # # Using: Set all var in User config section. Add scripts to schedule with onstart and interval 30 sek :do { ####################################################################################################### # User config #Set limit in MB :local limit 12288 #Set day to reset limit :local dayresetlimit 1 #Set interface :local interf "lte1" #Set auto bring up interface :local autointon true ####################################################################################################### :local filename "counter.txt" :local filewarn "warning.txt" :local fileref "refcount.txt" :local reblock "reblock.txt" :local status :if ([:len [/file find where name=$filewarn]] < 1 ) do={ /file print file=$filewarn where name=$filewarn /delay delay-time=2 /file set $filewarn contents=$percent }; :if ([:len [/file find where name=$filename]] < 1 ) do={ /file print file=$filename where name=$filename /delay delay-time=2; /file set $filename contents=0 } :if ([:len [/file find where name=$reblock]] < 1 ) do={ /file print file=$reblock where name=$reblock /delay delay-time=2; /file set $reblock contents=1 } :if ([:len [/file find where name=$fileref]] < 1 ) do={ /file print file=$fileref where name=$fileref /delay delay-time=2; /file set $fileref contents=0 } :local reblocker ([/file get $reblock contents]) :local curdate [/system clock get date] :local day [ :pick $curdate 4 6 ] :if ( $day = $dayresetlimit and $reblocker = 0) do={ /file set $filename contents=0 /file set $filewarn contents=0 /file set $fileref contents=0 /interface lte set $interf disabled=no /file set $reblock contents=1 :log info "Limit reset, int $interf bring up" /delay delay-time=5; :log info "Clear int counters - reboot" #TODO find another method for interf clear counters /system reboot } :if ( $day != $dayresetlimit ) do={ /file set $reblock contents=0 } :local before :local correct :local ref :local newdata :local tx [/interface get $interf tx-byte] :local rx [/interface get $interf rx-byte] :set $newdata (( $rx + $tx ) / 1024 / 1024 ) :set $before [/file get $filename contents] :if ( $newdata < $before ) do={ :set $ref [/file get $fileref contents] :set $correct ( $before + $newdata - $ref ) /file set $fileref contents=$newdata /file set $filename contents=$correct } :if ( $newdata >= $before ) do={ /file set $filename contents=$newdata } :local traffic ([/file get $filename contents]) :log warning "Limit: $limit MB" :local percent ($traffic*100 / $limit) :log warning "Use: $percent%" /file set $filewarn contents=$percent :if ($percent >= 100) do={ /file set $filewarn contents=$percent /interface lte set $interf disabled=yes } :if ($percent < 100 and $autointon = true) do={ :set $status [/interface get $interf value-name=disabled] :if ($status = true) do={ /interface lte set $interf disabled=no } } } on-error={ :log error "Error LTELimiter "};
for PPP-ClientCode: Select all# /$$ /$$$$$$$$/$$$$$$$$ /$$ /$$ /$$ /$$ # | $$ |__ $$__/ $$_____/| $$ |__/ |__/ | $$ # | $$ | $$ | $$ | $$ /$$ /$$$$$$/$$$$ /$$ /$$$$$$ /$$$$$$ /$$$$$$ # | $$ | $$ | $$$$$ | $$ | $$| $$_ $$_ $$| $$|_ $$_/ /$$__ $$ /$$__ $$ # | $$ | $$ | $$__/ | $$ | $$| $$ \ $$ \ $$| $$ | $$ | $$$$$$$$| $$ \__/ # | $$ | $$ | $$ | $$ | $$| $$ | $$ | $$| $$ | $$ /$$| $$_____/| $$ # | $$$$$$$$| $$ | $$$$$$$$| $$$$$$$$| $$| $$ | $$ | $$| $$ | $$$$/| $$$$$$$| $$ # |________/|__/ |________/|________/|__/|__/ |__/ |__/|__/ \___/ \_______/|__/ # # Using: Set all var in User config section. Add scripts to schedule with onstart and interval 30 sek :do { ####################################################################################################### # User config #Set limit in MB :local limit 12288 #Set day to reset limit :local dayresetlimit 1 #Set interface :local interf "ppp-out1" #Set auto bring up interface :local autointon true ####################################################################################################### :local filename "counter.txt" :local filewarn "warning.txt" :local fileref "refcount.txt" :local reblock "reblock.txt" :local status :if ([:len [/file find where name=$filewarn]] < 1 ) do={ /file print file=$filewarn where name=$filewarn /delay delay-time=2 /file set $filewarn contents=$percent }; :if ([:len [/file find where name=$filename]] < 1 ) do={ /file print file=$filename where name=$filename /delay delay-time=2; /file set $filename contents=0 } :if ([:len [/file find where name=$reblock]] < 1 ) do={ /file print file=$reblock where name=$reblock /delay delay-time=2; /file set $reblock contents=1 } :if ([:len [/file find where name=$fileref]] < 1 ) do={ /file print file=$fileref where name=$fileref /delay delay-time=2; /file set $fileref contents=0 } :local reblocker ([/file get $reblock contents]) :local curdate [/system clock get date] :local day [ :pick $curdate 4 6 ] :if ( $day = $dayresetlimit and $reblocker = 0) do={ /file set $filename contents=0 /file set $filewarn contents=0 /file set $fileref contents=0 /interface ppp-client set $interf disabled=no /file set $reblock contents=1 :log info "Limit reset, int $interf bring up" /delay delay-time=5; :log info "Clear int counters - reboot" #TODO find another method for interf clear counters /system reboot } :if ( $day != $dayresetlimit ) do={ /file set $reblock contents=0 } :local before :local correct :local ref :local newdata :local tx [/interface get $interf tx-byte] :local rx [/interface get $interf rx-byte] :set $newdata (( $rx + $tx ) / 1024 / 1024 ) :set $before [/file get $filename contents] :if ( $newdata < $before ) do={ :set $ref [/file get $fileref contents] :set $correct ( $before + $newdata - $ref ) /file set $fileref contents=$newdata /file set $filename contents=$correct } :if ( $newdata >= $before ) do={ /file set $filename contents=$newdata } :local traffic ([/file get $filename contents]) :log warning "Limit: $limit MB" :local percent ($traffic*100 / $limit) :log warning "Use: $percent%" /file set $filewarn contents=$percent :if ($percent >= 100) do={ /file set $filewarn contents=$percent /interface ppp-client set $interf disabled=yes } :if ($percent < 100 and $autointon = true) do={ :set $status [/interface get $interf value-name=disabled] :if ($status = true) do={ /interface ppp-client set $interf disabled=no } } } on-error={ :log error "Error ppp-clientLimiter "};
: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 {
####################################################################################################
# User config
#Set limit in MB
:local limit 350000;
#Set day to reset limit
:local dayresetlimit "01";
#Set interface
:local interf "ether1-WAN1";
#Set auto bring up interface
:local autointon true;
####################################################################################################
:local day ([:pick [/system clock get date] 4 6]);
:local newdata;
:local result;
:local ref;
:local status;
:local tx [/interface get $interf tx-byte];
:local rx [/interface get $interf rx-byte];
:set $newdata (($rx + $tx) / 1024 / 1024);
:if ([:len [$persistVar wan_counter]] < 1 ) do={
$persistVar wan_counter 0;
}
:if ([:len [$persistVar wan_rebootblock]] < 1 ) do={
$persistVar wan_rebootblock 1;
}
:if ([:len [$persistVar wan_offset]] < 1 ) do={
$persistVar wan_offset 0;
}
:if ([:len [$persistVar wan_refdata]] < 1 ) do={
$persistVar wan_refdata 0;
}
:local rebootblocker ([$persistVar wan_rebootblock]);
:if ( $day = $dayresetlimit and $rebootblocker = 0) do={
$persistVar wan_counter 0;
$persistVar wan_offset $newdata;
$persistVar wan_refdata 0;
/interface ethernet set $interf disabled=no
$persistVar wan_rebootblock 1;
:log info "Limit reset, int $interf bring up";
}
:if ( $day != $dayresetlimit ) do={
$persistVar wan_rebootblock 0;
}
:local before [$persistVar wan_counter];
:local offset [$persistVar wan_offset];
:if ( $newdata < $before ) do={
$persistVar wan_offset 0;
:set $ref [$persistVar wan_refdata];
:if ( $newdata < $ref ) do={
set $ref (0)
}
:set $result ($before + $newdata - $ref);
$persistVar wan_refdata $newdata;
$persistVar wan_counter $result;
} else={
:set $result ($newdata - $offset);
$persistVar wan_counter $result;
}
:local traffic ([$persistVar wan_counter]);
:local percent ($traffic*100 / $limit);
:log warning "Limit: $limit MB Traffic: $traffic MB Used: $percent%";
:if ($percent >= 100) do={
/interface ethernet set $interf disabled=yes
}
:if ($percent < 100 and $autointon = true) do={
:set $status [/interface get $interf value-name=disabled];
:if ($status = true) do={
/interface ethernet set $interf disabled=no
}
}
} on-error={ :log error "Error WAN1_Limiter "};
Hi Armando,After trying one of the final version of this script, I made some modification to avoid couple of things from the original idea: resetting the router to reset the interface's counters and writing to file to keep variable values. When using ethernet interface in order to reset the traffic counter you have to reboot the router, as disable/enable does not reset those counters.
In this version I'm using someone's else idea to keep all variables in the firewall Layer7 protocol section; those values are retained also after router reboot (original post viewtopic.php?f=9&t=7496#).
Then I decided to add a new variable for the offset for when the new month kicks in and I don't reboot the router and therefore the ethernet counters are still with values.
I have tested it with the latest ROS 6.46 and it seem working fine, even trying to simulate router reboot, new month and so on.
If someone is interested here is the final code, starting from the one on this post; this version is used on ethernet interface, so if you want to use it for LTE then you need to change the /interface command to reflect that.
Cheers,
Armando
:local day ([:pick [/system clock get date] 4 6]);
:local day ([:pick [/system clock get time] 0 2]);
add action=passthrough chain=forward comment="Count traffic going to internet through WAN2 (LTE)" dst-address=!172.16.5.0/24 log-prefix="FW fwd passthrough WAN2" out-interface="WAN2"
add action=passthrough chain=forward comment="Count traffic coming from internet through WAN2 (LTE)" dst-address=!172.16.5.0/24 log-prefix="FW fwd passthrough WAN2" in-interface="WAN2"
add action=masquerade chain=srcnat comment="NAT to WAN2" ipsec-policy=out,none out-interface="WAN2"
# /system script run wan2DisableNatOnVolumeExcess
## Script config
:local firewallFilterOUTComment "Count traffic going to internet through WAN2 (LTE)";
:local firewallFilterINComment "Count traffic coming from internet through WAN2 (LTE)";
:local wan2NatComment "NAT to WAN2";
:local maxVolumeMB 2000
## Script program below
## Function: flip wan2 nat disable state
:local flipWan2NatDisableStatus do={
# get WAN2 nat status
:local wan2NatDisabledStatus value=[:tostr [/ip firewall nat get value-name=disabled [find comment="$wan2NatComment"]]];
:local outputLogMessage
# invert the disabled state
:local wan2NatDisabledSwitch;
:local wan2NatDisabledSwitchRequired false;
:if (($wan2NatDisabledStatus=true) && ($maxVolumeThresholdExceeded=false)) do={
:set wan2NatDisabledSwitchRequired true;
:set wan2NatDisabledSwitch "no";
:set outputLogMessage "WAN2 interface volume threshold not exceeded (<$maxVolumeMB MB), enabling NAT";
}
:if (($wan2NatDisabledStatus=false) && ($maxVolumeThresholdExceeded=true)) do={
:set wan2NatDisabledSwitchRequired true;
:set wan2NatDisabledSwitch "yes";
:set outputLogMessage "WAN2 interface volume threshold exceeded (>$maxVolumeMB MB), disabling NAT";
}
if ($wan2NatDisabledSwitchRequired=true) do={
/ip firewall nat set disabled=[$wan2NatDisabledSwitch] [find comment="$wan2NatComment"];
:log warning $outputLogMessage
}
}
# reset filter counter, on the 1st of each month at 00:00
:if (([/system clock get date]~"^[a-zA-Z][a-zA-Z][a-zA-Z]/01/[0-9][0-9][0-9][0-9]") && ([/system clock get time]~"^00:00:[0-9][0-9]")) do={
/ip firewall filter reset-counters [find comment="$firewallFilterOUTComment"];
/ip firewall filter reset-counters [find comment="$firewallFilterINComment"];
:log info "WAN2 firewall filter counter has been reset"
};
# get the counter of traffic gone through WAN2 to internet
:local maxVolumeB value=[:tonum ($maxVolumeMB*1024*1024)]
:local maxVolumeThresholdExceeded
:local firewallFilterOUTVolume value=[:tostr [/ip firewall filter get value-name=bytes [find comment="$firewallFilterOUTComment"]]];
:local firewallFilterINVolume value=[:tostr [/ip firewall filter get value-name=bytes [find comment="$firewallFilterINComment"]]];
:local filrewallFilterTotalVolume ($firewallFilterOUTVolume + $firewallFilterINVolume);
:if ($filrewallFilterTotalVolume > $maxVolumeB) do={
:set maxVolumeThresholdExceeded true
} else={
:set maxVolumeThresholdExceeded false
}
## enable/disable nat of WAN2 when traffic below/exceeds threshold
$flipWan2NatDisableStatus wan2NatComment=$wan2NatComment maxVolumeThresholdExceeded=$maxVolumeThresholdExceeded maxVolumeMB=$maxVolumeMB
Bandwidth-based load-balancing with failover. This presentation also covers Mangle.2- when the volume is exceeded, the interface is not shut down, instead it's the NAT which gets disabled. This enables the router to still have service
3- the script runs every minute (via scheduler) and reset the firewall counter at midnight, on the 1st of each month. The script logs the NAT disable/enable action, and logs the counter-resetting
The script uniquely identifies the firewall filter and the nat via their comment
Bandwidth-based load-balancing with failover. This presentation also covers Mangle.2- when the volume is exceeded, the interface is not shut down, instead it's the NAT which gets disabled. This enables the router to still have service
3- the script runs every minute (via scheduler) and reset the firewall counter at midnight, on the 1st of each month. The script logs the NAT disable/enable action, and logs the counter-resetting
The script uniquely identifies the firewall filter and the nat via their comment
This was presented at the MUM (MikroTik User Meeting) in New Orelans, USA.
Tomas Kirnak - YouTube: https://www.youtube.com/watch?v=67Dna_ffCvc&t=1s
http://mum.mikrotik.com/presentations/US12/tomas.pdf
Dear all,
I'm new to Mikrotik, this forum was of great help. Thanks to the community.
Happy to contribute by sharing below my implementation to avoid getting overpriced LTE invoices.
How this works?
1- the counting of the LTE traffic is made via a firewall filter. Main reason here is to avoid file read/write, hence SSD wear + even if firewall counter doesnt survive a reboot. This firewall filter is expected to be the first in the chain, so it really counts all matching traffic. Observe that this firewall filter purposefully excludes the traffic that only goes to the internal IP of the LTE router (or its subnet): the counter hence only includes the traffic that goes through the LTE router and to the internet
2- when the volume is exceeded, the interface is not shut down, instead it's the NAT which gets disabled. This enables the router to still have service
3- the script runs every minute (via scheduler) and reset the firewall counter at midnight, on the 1st of each month. The script logs the NAT disable/enable action, and logs the counter-resetting
The script uniquely identifies the firewall filter and the nat via their comment
Below is the content
Firewall filter (to count traffic)Code: Select alladd action=passthrough chain=forward comment="Count traffic going to internet through WAN2 (LTE)" dst-address=!172.16.5.0/24 log-prefix="FW fwd passthrough WAN2" out-interface="WAN2" add action=passthrough chain=forward comment="Count traffic coming from internet through WAN2 (LTE)" dst-address=!172.16.5.0/24 log-prefix="FW fwd passthrough WAN2" in-interface="WAN2"
NAT (this is what gets enabled/disabled on volume excess)
Code: Select alladd action=masquerade chain=srcnat comment="NAT to WAN2" ipsec-policy=out,none out-interface="WAN2"
Script wan2DisableNatOnVolumeExcess
Code: Select all# /system script run wan2DisableNatOnVolumeExcess ## Script config :local firewallFilterOUTComment "Count traffic going to internet through WAN2 (LTE)"; :local firewallFilterINComment "Count traffic coming from internet through WAN2 (LTE)"; :local wan2NatComment "NAT to WAN2"; :local maxVolumeMB 2000 ## Script program below ## Function: flip wan2 nat disable state :local flipWan2NatDisableStatus do={ # get WAN2 nat status :local wan2NatDisabledStatus value=[:tostr [/ip firewall nat get value-name=disabled [find comment="$wan2NatComment"]]]; :local outputLogMessage # invert the disabled state :local wan2NatDisabledSwitch; :local wan2NatDisabledSwitchRequired false; :if (($wan2NatDisabledStatus=true) && ($maxVolumeThresholdExceeded=false)) do={ :set wan2NatDisabledSwitchRequired true; :set wan2NatDisabledSwitch "no"; :set outputLogMessage "WAN2 interface volume threshold not exceeded (<$maxVolumeMB MB), enabling NAT"; } :if (($wan2NatDisabledStatus=false) && ($maxVolumeThresholdExceeded=true)) do={ :set wan2NatDisabledSwitchRequired true; :set wan2NatDisabledSwitch "yes"; :set outputLogMessage "WAN2 interface volume threshold exceeded (>$maxVolumeMB MB), disabling NAT"; } if ($wan2NatDisabledSwitchRequired=true) do={ /ip firewall nat set disabled=[$wan2NatDisabledSwitch] [find comment="$wan2NatComment"]; :log warning $outputLogMessage } } # reset filter counter, on the 1st of each month at 00:00 :if (([/system clock get date]~"^[a-zA-Z][a-zA-Z][a-zA-Z]/01/[0-9][0-9][0-9][0-9]") && ([/system clock get time]~"^00:00:[0-9][0-9]")) do={ /ip firewall filter reset-counters [find comment="$firewallFilterOUTComment"]; /ip firewall filter reset-counters [find comment="$firewallFilterINComment"]; :log info "WAN2 firewall filter counter has been reset" }; # get the counter of traffic gone through WAN2 to internet :local maxVolumeB value=[:tonum ($maxVolumeMB*1024*1024)] :local maxVolumeThresholdExceeded :local firewallFilterOUTVolume value=[:tostr [/ip firewall filter get value-name=bytes [find comment="$firewallFilterOUTComment"]]]; :local firewallFilterINVolume value=[:tostr [/ip firewall filter get value-name=bytes [find comment="$firewallFilterINComment"]]]; :local filrewallFilterTotalVolume ($firewallFilterOUTVolume + $firewallFilterINVolume); :if ($filrewallFilterTotalVolume > $maxVolumeB) do={ :set maxVolumeThresholdExceeded true } else={ :set maxVolumeThresholdExceeded false } ## enable/disable nat of WAN2 when traffic below/exceeds threshold $flipWan2NatDisableStatus wan2NatComment=$wan2NatComment maxVolumeThresholdExceeded=$maxVolumeThresholdExceeded maxVolumeMB=$maxVolumeMB
Hi,
Well the content of the script should be pasted into a blank script into System> Scripts
You'll need to give this script a name a suggestion would be wan2DisableNatOnVolumeExcess
Once you have saved your script under its name (for example wan2DisableNatOnVolumeExcess); then you'll need to run it:
- either manually via the command line
- or automatically via the scheduler (system > scheduler)
Either way, the script is invoked with:
/system script run wan2DisableNatOnVolumeExcess
Also, please ensure you have adjusted the firewall rules to your environment: both for the interface name AND the subnet.
Hope this helps
Cheers
Hi Eguun,
Thanks a lot for the clarification. Appreciate your assistance. Will try tonight. :)
Hi,
Well the content of the script should be pasted into a blank script into System> Scripts
You'll need to give this script a name a suggestion would be wan2DisableNatOnVolumeExcess
Once you have saved your script under its name (for example wan2DisableNatOnVolumeExcess); then you'll need to run it:
- either manually via the command line
- or automatically via the scheduler (system > scheduler)
Either way, the script is invoked with:
/system script run wan2DisableNatOnVolumeExcess
Also, please ensure you have adjusted the firewall rules to your environment: both for the interface name AND the subnet.
Hope this helps
Cheers
Okay,
at this stage, it's worth you ensuring the Nat & Firewall rules are aligned with your interface: ie that you didn't simply copy/pasted my text without changing interface names.
Once done, you can add debug lines in the code to output some info in the logs or the console so you can follow-up how the script behave.
I would recommend you to invest serious time & effort into it: I can provide some high level guidance but won't be able to dedicate hand-helding level of support.
Thanks
After trying one of the final version of this script, I made some modification to avoid couple of things from the original idea: resetting the router to reset the interface's counters and writing to file to keep variable values. When using ethernet interface in order to reset the traffic counter you have to reboot the router, as disable/enable does not reset those counters.
In this version I'm using someone's else idea to keep all variables in the firewall Layer7 protocol section; those values are retained also after router reboot (original post viewtopic.php?f=9&t=7496#).
Then I decided to add a new variable for the offset for when the new month kicks in and I don't reboot the router and therefore the ethernet counters are still with values.
I have tested it with the latest ROS 6.46 and it seem working fine, even trying to simulate router reboot, new month and so on.
If someone is interested here is the final code, starting from the one on this post; this version is used on ethernet interface, so if you want to use it for LTE then you need to change the /interface command to reflect that.
Cheers,
Armando
Code: Select all: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 { #################################################################################################### # User config #Set limit in MB :local limit 350000; #Set day to reset limit :local dayresetlimit "01"; #Set interface :local interf "ether1-WAN1"; #Set auto bring up interface :local autointon true; #################################################################################################### :local day ([:pick [/system clock get date] 4 6]); :local newdata; :local result; :local ref; :local status; :local tx [/interface get $interf tx-byte]; :local rx [/interface get $interf rx-byte]; :set $newdata (($rx + $tx) / 1024 / 1024); :if ([:len [$persistVar wan_counter]] < 1 ) do={ $persistVar wan_counter 0; } :if ([:len [$persistVar wan_rebootblock]] < 1 ) do={ $persistVar wan_rebootblock 1; } :if ([:len [$persistVar wan_offset]] < 1 ) do={ $persistVar wan_offset 0; } :if ([:len [$persistVar wan_refdata]] < 1 ) do={ $persistVar wan_refdata 0; } :local rebootblocker ([$persistVar wan_rebootblock]); :if ( $day = $dayresetlimit and $rebootblocker = 0) do={ $persistVar wan_counter 0; $persistVar wan_offset $newdata; $persistVar wan_refdata 0; /interface ethernet set $interf disabled=no $persistVar wan_rebootblock 1; :log info "Limit reset, int $interf bring up"; } :if ( $day != $dayresetlimit ) do={ $persistVar wan_rebootblock 0; } :local before [$persistVar wan_counter]; :local offset [$persistVar wan_offset]; :if ( $newdata < $before ) do={ $persistVar wan_offset 0; :set $ref [$persistVar wan_refdata]; :if ( $newdata < $ref ) do={ set $ref (0) } :set $result ($before + $newdata - $ref); $persistVar wan_refdata $newdata; $persistVar wan_counter $result; } else={ :set $result ($newdata - $offset); $persistVar wan_counter $result; } :local traffic ([$persistVar wan_counter]); :local percent ($traffic*100 / $limit); :log warning "Limit: $limit MB Traffic: $traffic MB Used: $percent%"; :if ($percent >= 100) do={ /interface ethernet set $interf disabled=yes } :if ($percent < 100 and $autointon = true) do={ :set $status [/interface get $interf value-name=disabled]; :if ($status = true) do={ /interface ethernet set $interf disabled=no } } } on-error={ :log error "Error WAN1_Limiter "};
On your counter-reset question: there is no way to alter this, it's a "feature" of mikrotik: all what isn't saved on flash drive is lost on reboot. It also includes these firewall-filter counters.If the router is rebooted, the counters will be back to zero. Any idea how to resolve this?
On this topic, I would suppose the script works already as you would like:I've tested this script and it is working as what I needed. But I would to make some amendments to it. How do I only allow winbox (port 8291) to passthrough instead for disabling the whole interface? The reason for this is I want to remotely connect to it if the remote site decided to topup the quota. Any help is much appreciated.
You have counting scripts in this post. Use it. You can create other way... like check if internet is offline - if true then run script who replace sim slots and do change APN etc.i want, if is possible, make a script that when the traffic on SIM "a" will be finish(on 50GB of limit) change a modem, and a APN. I have on SIM "a", 70Gb of traffic, and the APN is 1, otherhand i have on SIM "b", 50Gb of traffic limit and APN is 2.
Sorry for the long delay, but actually I have never received notification about this post being growing.
Would you be able/willing to explain what the 3 other L7 variables do?
I tried to understand from your script, but can't get their meaning...:
- wan-offset ?
- wan-rebootlock ?
- wan-refdata ?
Again, thank you very much for your script :-)
:global persistVar
:global notifyCount
:do {
####################################################################################################
# User config
#Set limit in MB
:local limit 390000
#Set day to reset limit
:local dayresetlimit "01"
#Set interface
:local interf "ether1-WAN"
#Set auto bring up interface
:local autointon true
#Delta startup value
:local startValue 0
####################################################################################################
:local notifyLimit 1
:local botId "your_bot_id"
:local chatId "your_chat_id"
:local site [/system identity get value-name=name]
: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 newdata
:local result
:local ref
:local status
:local tx [/interface get $interf tx-byte]
:local rx [/interface get $interf rx-byte]
:set $newdata (($rx + $tx) / 1024 / 1024)
:if ([:len [$persistVar wan1_counter]] < 1 ) do={
$persistVar wan1_counter 0
}
:if ([:len [$persistVar wan1_rebootblock]] < 1 ) do={
$persistVar wan1_rebootblock 1
}
:if ([:len [$persistVar wan1_offset]] < 1 ) do={
$persistVar wan1_offset 0
}
:if ([:len [$persistVar wan1_refdata]] < 1 ) do={
$persistVar wan1_refdata 0
}
:local rebootblocker ([$persistVar wan1_rebootblock])
:if ( $day = $dayresetlimit and $rebootblocker = 0) do={
$persistVar wan1_counter 0
$persistVar wan1_offset $newdata
$persistVar wan1_refdata 0
/interface ethernet set $interf disabled=no
$persistVar wan1_rebootblock 1
:set notifyCount 0
:log warning "Resetting limits, int $interf bring up"
}
:if ( $day != $dayresetlimit ) do={
$persistVar wan1_rebootblock 0
}
:local before [$persistVar wan1_counter]
:local offset [$persistVar wan1_offset]
:if ( $newdata < $before ) do={
$persistVar wan1_offset 0
:set $ref [$persistVar wan1_refdata]
:if ( $newdata < $ref ) do={
:set $ref (0)
}
:set $result ($before + $newdata - $ref + $startValue)
$persistVar wan1_refdata $newdata
$persistVar wan1_counter $result
} else={
:set $result ($newdata - $offset + $startValue)
$persistVar wan1_counter $result
}
:local traffic ([$persistVar wan1_counter])
:local percent ($traffic*100 / $limit)
:if ($percent >= 100) do={
:if ($notifyCount <= $notifyLimit) do={
/tool fetch url="https://api.telegram.org/bot$botId/sendMessage?chat_id=$chatId&text=MikroTik $site info:%0A[$date $time]%0AWAN1 disabled for exceeding bandwidth limit $limit MB" keep-result=no
:log warning "$interf disabled for exceeding bandwidth limit $limit MB"
:set $notifyCount ($notifyCount + 1)
:delay 3
}
/interface ethernet set $interf disabled=yes
}
:if ($percent < 100 and $autointon = true) do={
:set $status [/interface get $interf value-name=disabled]
:if ($status = true) do={
/interface ethernet set $interf disabled=no
}
}
} on-error={ :log error "Error WAN1_Limiter "}
I use this script I'm fine, but I wanted to understand how I can insert a method in the script to send me an email after the traffic has passed? I tried to insert it myself but the passed mb sends me e-mails all the time. I wish you would just send me an email. Thanks in advanceHello
For LTE:Code: Select all# /$$ /$$$$$$$$/$$$$$$$$ /$$ /$$ /$$ /$$ # | $$ |__ $$__/ $$_____/| $$ |__/ |__/ | $$ # | $$ | $$ | $$ | $$ /$$ /$$$$$$/$$$$ /$$ /$$$$$$ /$$$$$$ /$$$$$$ # | $$ | $$ | $$$$$ | $$ | $$| $$_ $$_ $$| $$|_ $$_/ /$$__ $$ /$$__ $$ # | $$ | $$ | $$__/ | $$ | $$| $$ \ $$ \ $$| $$ | $$ | $$$$$$$$| $$ \__/ # | $$ | $$ | $$ | $$ | $$| $$ | $$ | $$| $$ | $$ /$$| $$_____/| $$ # | $$$$$$$$| $$ | $$$$$$$$| $$$$$$$$| $$| $$ | $$ | $$| $$ | $$$$/| $$$$$$$| $$ # |________/|__/ |________/|________/|__/|__/ |__/ |__/|__/ \___/ \_______/|__/ # # Using: Set all var in User config section. Add scripts to schedule with onstart and interval 30 sek :do { ####################################################################################################### # User config #Set limit in MB :local limit 12288 #Set day to reset limit :local dayresetlimit 1 #Set interface :local interf "lte1" #Set auto bring up interface :local autointon true ####################################################################################################### :local filename "counter.txt" :local filewarn "warning.txt" :local fileref "refcount.txt" :local reblock "reblock.txt" :local status :if ([:len [/file find where name=$filewarn]] < 1 ) do={ /file print file=$filewarn where name=$filewarn /delay delay-time=2 /file set $filewarn contents=$percent }; :if ([:len [/file find where name=$filename]] < 1 ) do={ /file print file=$filename where name=$filename /delay delay-time=2; /file set $filename contents=0 } :if ([:len [/file find where name=$reblock]] < 1 ) do={ /file print file=$reblock where name=$reblock /delay delay-time=2; /file set $reblock contents=1 } :if ([:len [/file find where name=$fileref]] < 1 ) do={ /file print file=$fileref where name=$fileref /delay delay-time=2; /file set $fileref contents=0 } :local reblocker ([/file get $reblock contents]) :local curdate [/system clock get date] :local day [ :pick $curdate 4 6 ] :if ( $day = $dayresetlimit and $reblocker = 0) do={ /file set $filename contents=0 /file set $filewarn contents=0 /file set $fileref contents=0 /interface lte set $interf disabled=no /file set $reblock contents=1 :log info "Limit reset, int $interf bring up" /delay delay-time=5; :log info "Clear int counters - reboot" #TODO find another method for interf clear counters /system reboot } :if ( $day != $dayresetlimit ) do={ /file set $reblock contents=0 } :local before :local correct :local ref :local newdata :local tx [/interface get $interf tx-byte] :local rx [/interface get $interf rx-byte] :set $newdata (( $rx + $tx ) / 1024 / 1024 ) :set $before [/file get $filename contents] :if ( $newdata < $before ) do={ :set $ref [/file get $fileref contents] :set $correct ( $before + $newdata - $ref ) /file set $fileref contents=$newdata /file set $filename contents=$correct } :if ( $newdata >= $before ) do={ /file set $filename contents=$newdata } :local traffic ([/file get $filename contents]) :log warning "Limit: $limit MB" :local percent ($traffic*100 / $limit) :log warning "Use: $percent%" /file set $filewarn contents=$percent :if ($percent >= 100) do={ /file set $filewarn contents=$percent /interface lte set $interf disabled=yes } :if ($percent < 100 and $autointon = true) do={ :set $status [/interface get $interf value-name=disabled] :if ($status = true) do={ /interface lte set $interf disabled=no } } } on-error={ :log error "Error LTELimiter "};
for PPP-ClientCode: Select all# /$$ /$$$$$$$$/$$$$$$$$ /$$ /$$ /$$ /$$ # | $$ |__ $$__/ $$_____/| $$ |__/ |__/ | $$ # | $$ | $$ | $$ | $$ /$$ /$$$$$$/$$$$ /$$ /$$$$$$ /$$$$$$ /$$$$$$ # | $$ | $$ | $$$$$ | $$ | $$| $$_ $$_ $$| $$|_ $$_/ /$$__ $$ /$$__ $$ # | $$ | $$ | $$__/ | $$ | $$| $$ \ $$ \ $$| $$ | $$ | $$$$$$$$| $$ \__/ # | $$ | $$ | $$ | $$ | $$| $$ | $$ | $$| $$ | $$ /$$| $$_____/| $$ # | $$$$$$$$| $$ | $$$$$$$$| $$$$$$$$| $$| $$ | $$ | $$| $$ | $$$$/| $$$$$$$| $$ # |________/|__/ |________/|________/|__/|__/ |__/ |__/|__/ \___/ \_______/|__/ # # Using: Set all var in User config section. Add scripts to schedule with onstart and interval 30 sek :do { ####################################################################################################### # User config #Set limit in MB :local limit 12288 #Set day to reset limit :local dayresetlimit 1 #Set interface :local interf "ppp-out1" #Set auto bring up interface :local autointon true ####################################################################################################### :local filename "counter.txt" :local filewarn "warning.txt" :local fileref "refcount.txt" :local reblock "reblock.txt" :local status :if ([:len [/file find where name=$filewarn]] < 1 ) do={ /file print file=$filewarn where name=$filewarn /delay delay-time=2 /file set $filewarn contents=$percent }; :if ([:len [/file find where name=$filename]] < 1 ) do={ /file print file=$filename where name=$filename /delay delay-time=2; /file set $filename contents=0 } :if ([:len [/file find where name=$reblock]] < 1 ) do={ /file print file=$reblock where name=$reblock /delay delay-time=2; /file set $reblock contents=1 } :if ([:len [/file find where name=$fileref]] < 1 ) do={ /file print file=$fileref where name=$fileref /delay delay-time=2; /file set $fileref contents=0 } :local reblocker ([/file get $reblock contents]) :local curdate [/system clock get date] :local day [ :pick $curdate 4 6 ] :if ( $day = $dayresetlimit and $reblocker = 0) do={ /file set $filename contents=0 /file set $filewarn contents=0 /file set $fileref contents=0 /interface ppp-client set $interf disabled=no /file set $reblock contents=1 :log info "Limit reset, int $interf bring up" /delay delay-time=5; :log info "Clear int counters - reboot" #TODO find another method for interf clear counters /system reboot } :if ( $day != $dayresetlimit ) do={ /file set $reblock contents=0 } :local before :local correct :local ref :local newdata :local tx [/interface get $interf tx-byte] :local rx [/interface get $interf rx-byte] :set $newdata (( $rx + $tx ) / 1024 / 1024 ) :set $before [/file get $filename contents] :if ( $newdata < $before ) do={ :set $ref [/file get $fileref contents] :set $correct ( $before + $newdata - $ref ) /file set $fileref contents=$newdata /file set $filename contents=$correct } :if ( $newdata >= $before ) do={ /file set $filename contents=$newdata } :local traffic ([/file get $filename contents]) :log warning "Limit: $limit MB" :local percent ($traffic*100 / $limit) :log warning "Use: $percent%" /file set $filewarn contents=$percent :if ($percent >= 100) do={ /file set $filewarn contents=$percent /interface ppp-client set $interf disabled=yes } :if ($percent < 100 and $autointon = true) do={ :set $status [/interface get $interf value-name=disabled] :if ($status = true) do={ /interface ppp-client set $interf disabled=no } } } on-error={ :log error "Error ppp-clientLimiter "};
Ciao Armando, could you explain the usage of firewall-L7 "data storage"? It's not really clear to me from your script code, or I'm missing another script to define $persistVar?Hello all,
I'm just posting the current version of the script for ethernet's based traffic limiter which I'm currently using, where I added also some notification via Telegram Bot.
For this reason there is a global variable "notifyCount" to limit the number of Telegram notification that you'd like to receive.
Most of the script is the same, few changes to some part of the logic.
The main function to store data into firewall-L7 "data storage" is now part of a general global variable and the script is not run in a loop, but through a scheduler.
Armando
Hello
For LTE:Code: Select all# /$$ /$$$$$$$$/$$$$$$$$ /$$ /$$ /$$ /$$ # | $$ |__ $$__/ $$_____/| $$ |__/ |__/ | $$ # | $$ | $$ | $$ | $$ /$$ /$$$$$$/$$$$ /$$ /$$$$$$ /$$$$$$ /$$$$$$ # | $$ | $$ | $$$$$ | $$ | $$| $$_ $$_ $$| $$|_ $$_/ /$$__ $$ /$$__ $$ # | $$ | $$ | $$__/ | $$ | $$| $$ \ $$ \ $$| $$ | $$ | $$$$$$$$| $$ \__/ # | $$ | $$ | $$ | $$ | $$| $$ | $$ | $$| $$ | $$ /$$| $$_____/| $$ # | $$$$$$$$| $$ | $$$$$$$$| $$$$$$$$| $$| $$ | $$ | $$| $$ | $$$$/| $$$$$$$| $$ # |________/|__/ |________/|________/|__/|__/ |__/ |__/|__/ \___/ \_______/|__/ # # Using: Set all var in User config section. Add scripts to schedule with onstart and interval 30 sek :do { ####################################################################################################### # User config #Set limit in MB :local limit 12288 #Set day to reset limit :local dayresetlimit 1 #Set interface :local interf "lte1" #Set auto bring up interface :local autointon true ####################################################################################################### :local filename "counter.txt" :local filewarn "warning.txt" :local fileref "refcount.txt" :local reblock "reblock.txt" :local status :if ([:len [/file find where name=$filewarn]] < 1 ) do={ /file print file=$filewarn where name=$filewarn /delay delay-time=2 /file set $filewarn contents=$percent }; :if ([:len [/file find where name=$filename]] < 1 ) do={ /file print file=$filename where name=$filename /delay delay-time=2; /file set $filename contents=0 } :if ([:len [/file find where name=$reblock]] < 1 ) do={ /file print file=$reblock where name=$reblock /delay delay-time=2; /file set $reblock contents=1 } :if ([:len [/file find where name=$fileref]] < 1 ) do={ /file print file=$fileref where name=$fileref /delay delay-time=2; /file set $fileref contents=0 } :local reblocker ([/file get $reblock contents]) :local curdate [/system clock get date] :local day [ :pick $curdate 4 6 ] :if ( $day = $dayresetlimit and $reblocker = 0) do={ /file set $filename contents=0 /file set $filewarn contents=0 /file set $fileref contents=0 /interface lte set $interf disabled=no /file set $reblock contents=1 :log info "Limit reset, int $interf bring up" /delay delay-time=5; :log info "Clear int counters - reboot" #TODO find another method for interf clear counters /system reboot } :if ( $day != $dayresetlimit ) do={ /file set $reblock contents=0 } :local before :local correct :local ref :local newdata :local tx [/interface get $interf tx-byte] :local rx [/interface get $interf rx-byte] :set $newdata (( $rx + $tx ) / 1024 / 1024 ) :set $before [/file get $filename contents] :if ( $newdata < $before ) do={ :set $ref [/file get $fileref contents] :set $correct ( $before + $newdata - $ref ) /file set $fileref contents=$newdata /file set $filename contents=$correct } :if ( $newdata >= $before ) do={ /file set $filename contents=$newdata } :local traffic ([/file get $filename contents]) :log warning "Limit: $limit MB" :local percent ($traffic*100 / $limit) :log warning "Use: $percent%" /file set $filewarn contents=$percent :if ($percent >= 100) do={ /file set $filewarn contents=$percent /interface lte set $interf disabled=yes } :if ($percent < 100 and $autointon = true) do={ :set $status [/interface get $interf value-name=disabled] :if ($status = true) do={ /interface lte set $interf disabled=no } } } on-error={ :log error "Error LTELimiter "};
for PPP-ClientCode: Select all# /$$ /$$$$$$$$/$$$$$$$$ /$$ /$$ /$$ /$$ # | $$ |__ $$__/ $$_____/| $$ |__/ |__/ | $$ # | $$ | $$ | $$ | $$ /$$ /$$$$$$/$$$$ /$$ /$$$$$$ /$$$$$$ /$$$$$$ # | $$ | $$ | $$$$$ | $$ | $$| $$_ $$_ $$| $$|_ $$_/ /$$__ $$ /$$__ $$ # | $$ | $$ | $$__/ | $$ | $$| $$ \ $$ \ $$| $$ | $$ | $$$$$$$$| $$ \__/ # | $$ | $$ | $$ | $$ | $$| $$ | $$ | $$| $$ | $$ /$$| $$_____/| $$ # | $$$$$$$$| $$ | $$$$$$$$| $$$$$$$$| $$| $$ | $$ | $$| $$ | $$$$/| $$$$$$$| $$ # |________/|__/ |________/|________/|__/|__/ |__/ |__/|__/ \___/ \_______/|__/ # # Using: Set all var in User config section. Add scripts to schedule with onstart and interval 30 sek :do { ####################################################################################################### # User config #Set limit in MB :local limit 12288 #Set day to reset limit :local dayresetlimit 1 #Set interface :local interf "ppp-out1" #Set auto bring up interface :local autointon true ####################################################################################################### :local filename "counter.txt" :local filewarn "warning.txt" :local fileref "refcount.txt" :local reblock "reblock.txt" :local status :if ([:len [/file find where name=$filewarn]] < 1 ) do={ /file print file=$filewarn where name=$filewarn /delay delay-time=2 /file set $filewarn contents=$percent }; :if ([:len [/file find where name=$filename]] < 1 ) do={ /file print file=$filename where name=$filename /delay delay-time=2; /file set $filename contents=0 } :if ([:len [/file find where name=$reblock]] < 1 ) do={ /file print file=$reblock where name=$reblock /delay delay-time=2; /file set $reblock contents=1 } :if ([:len [/file find where name=$fileref]] < 1 ) do={ /file print file=$fileref where name=$fileref /delay delay-time=2; /file set $fileref contents=0 } :local reblocker ([/file get $reblock contents]) :local curdate [/system clock get date] :local day [ :pick $curdate 4 6 ] :if ( $day = $dayresetlimit and $reblocker = 0) do={ /file set $filename contents=0 /file set $filewarn contents=0 /file set $fileref contents=0 /interface ppp-client set $interf disabled=no /file set $reblock contents=1 :log info "Limit reset, int $interf bring up" /delay delay-time=5; :log info "Clear int counters - reboot" #TODO find another method for interf clear counters /system reboot } :if ( $day != $dayresetlimit ) do={ /file set $reblock contents=0 } :local before :local correct :local ref :local newdata :local tx [/interface get $interf tx-byte] :local rx [/interface get $interf rx-byte] :set $newdata (( $rx + $tx ) / 1024 / 1024 ) :set $before [/file get $filename contents] :if ( $newdata < $before ) do={ :set $ref [/file get $fileref contents] :set $correct ( $before + $newdata - $ref ) /file set $fileref contents=$newdata /file set $filename contents=$correct } :if ( $newdata >= $before ) do={ /file set $filename contents=$newdata } :local traffic ([/file get $filename contents]) :log warning "Limit: $limit MB" :local percent ($traffic*100 / $limit) :log warning "Use: $percent%" /file set $filewarn contents=$percent :if ($percent >= 100) do={ /file set $filewarn contents=$percent /interface ppp-client set $interf disabled=yes } :if ($percent < 100 and $autointon = true) do={ :set $status [/interface get $interf value-name=disabled] :if ($status = true) do={ /interface ppp-client set $interf disabled=no } } } on-error={ :log error "Error ppp-clientLimiter "};