Dear Peter and Chris,
In the end we never really implemented this scripts, but if I’m remembering correctly it should be working. If you would like to know which specifik routerBoard I was programming this for, please ask me.
The scripts are a buch of different ones, one main scripts is executing the other ones;
mainscript freedata-mikrotik.c reads data from interfaces and writes them to files
#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: http://forum.mikrotik.com/t/interface-data-quota/79514/1
#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"
};
};
};
warning-mikrotik.c checks traffic usage
#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: http://forum.mikrotik.com/t/interface-data-quota/79514/1
#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
};
};
};
};
reset-files-mikrotik.c resets all counter files every first of the month
#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: http://forum.mikrotik.com/t/interface-data-quota/79514/1
#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"
};
stoplte.c stops the interface lte
#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"
readfiles.c helpscript to run manually so you can read all files at once
: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 %"
Hope it helps, it was a lot of fun program this, so thanks again Chris. If you have any questions please let me know
Maikel