Daily quota based on remaining monthly quota

Report issues relating to bandwith monitoring, bandwidth quotas or QoS in this forum.

Moderator: Moderators

emmexx
Posts: 11
Joined: Thu Sep 29, 2016 6:01 am

Daily quota based on remaining monthly quota

Postby emmexx » Thu Sep 29, 2016 7:38 am

In a B&B that I own I offer internet access.

Internet connection is with a 4g modem and a data package of 5 GB/28 days only. Every 28 day the counter resets.

SInce we have many guests in those 28 days what happens is that the 1st ones use all the quota. :(

I'd like to distribute the quota along all the 28 days but trying to use all the data available.
Example:
  • 1st day guest uses 100MB out of 5GB/28
  • room empty
  • 3rd day guest uses 50MB out of (5GB-100MB)/26
  • 4th day guest uses 250MB out of (5GB-100MB-250MB)/25
  • ...
  • 28th day guest can use all the remaining quota. Quota resets at the end of the 28th day

Is it possible to achieve that using some script and cron? If it is, can you give me some pointers to code or documentation?
It shouldn't be that difficult, it is enough to be able to access the quota value, to save the 28 day-period quota somewhere, to reset it at the 28th day and to change the daily quota each day.

Thank you
maxx

ispyisail
Moderator
Posts: 4705
Joined: Mon Apr 06, 2009 3:15 am
Location: New Zealand

Re: Daily quota based on remaining monthly quota

Postby ispyisail » Thu Oct 13, 2016 3:48 am

Do you have a gargoyle router?

emmexx
Posts: 11
Joined: Thu Sep 29, 2016 6:01 am

Re: Daily quota based on remaining monthly quota

Postby emmexx » Thu Oct 13, 2016 3:44 pm

ispyisail wrote:Do you have a gargoyle router?

What do you mean? A supported router or a router bought from Gargoyle?

Anyway I solved the problem (and I'm testing it) by creating a cron script that sums the values of bw_get total5-download-day-365 and total5-upload-day-365 and updates firewall.quota_1.combined_limit.

If somebody is interested I can clean the code and post it.

bye
maxx

ispyisail
Moderator
Posts: 4705
Joined: Mon Apr 06, 2009 3:15 am
Location: New Zealand

Re: Daily quota based on remaining monthly quota

Postby ispyisail » Thu Oct 13, 2016 4:16 pm

What do you mean? A supported router or a router bought from Gargoyle?


Some people ask questions before using a Gargoyle router.

I was just trying to get a feel for where you were at.

You next post answered all the questions :)

ispyisail
Moderator
Posts: 4705
Joined: Mon Apr 06, 2009 3:15 am
Location: New Zealand

Re: Daily quota based on remaining monthly quota

Postby ispyisail » Thu Oct 13, 2016 4:17 pm

If somebody is interested I can clean the code and post it.


That would be nice

Thank you

ispyisail
Moderator
Posts: 4705
Joined: Mon Apr 06, 2009 3:15 am
Location: New Zealand

Re: Daily quota based on remaining monthly quota

Postby ispyisail » Thu Oct 13, 2016 4:22 pm

What do you mean? A supported router or a router bought from Gargoyle?


There are so many post that usually I just scan the posts for keys points. If I have read your first post more carefully I probably could have found the answer :)

Thanks for using Gargoyle

emmexx
Posts: 11
Joined: Thu Sep 29, 2016 6:01 am

Re: Daily quota based on remaining monthly quota

Postby emmexx » Mon Oct 17, 2016 5:12 am

At the start of the script there are 3 variables that must be changed to fit your ISP package.

Code: Select all

RENEWAL_DATE is the date when your ISP resets, or will reset, the quota
RENEWAL_DAYS is the number of days of the ISP package (quota resets every xxx days)
QUOTA is the available bandwidth for the period

In my case the last renewal date was yesterday 2016-10-16 and the quota is reset every 28 days, the quota is 5 GB. So:

Code: Select all

RENEWAL_DATE='2016-09-18'       #last date ISP reset the quota
RENEWAL_DAYS=28                #renewal every xxx days
QUOTA=$(( 5 * 1073741824 ))    #bytes

I'm not a script master so everything could be written better but it works as expected.

The script is not integrated in gargoyle, so if you upgrade or change something, you'll have to set again everything.

The script changes every day the quota available for the day, based on the available bandwidth for the entire period minus the bandwidth already used in the period.
That means that the daily quota available will probably grow every day up to the reset day.
But the aim of the script is to keep a minimum quota available every day for the entire period.

Pre-conditions:
  • You should add a quota using Gargoyle GUI before using the script. The script only updates the quota value.
  • The script sums the combined upload and download bandwidth of the previous xx days. The script works only for the entire network bandwidth.

How to use it
  • Use Gargoyle GUI to add a Firewall / Quotas / quota. See the script.
  • Copy the script to the router using ssh, change the 3 variables aforementioned, change the execution permission of the script.
  • Check if the script works by running it without parameters. It should output the values of the available bandwidth and period, the remaining bandwidth and the days before quota reset, the current quota value.
  • Run crontab -e and add a line to run the script everyday, some minute after the quota reset. I use

    Code: Select all

    5 0 0 0 0 /root/quota_period.sh -c >/dev/null 2>&1
Since the script uses the upload and download values to calculate the remaining quota, it works only if the reset time is midnight. If the reset hour is in another moment of the day, the script should be modified.

Use the script at your own risk. ;)

bye
maxx

p.s.attachments are not allowed. The script is here:
quota_period.sh

Code: Select all

#!/bin/sh

# This program is copyright © 2016 Massimo Conter
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.   
#
# https://www.gnu.org/licenses/gpl-2.0.html

#customise the following 3 variables
RENEWAL_DATE='2016-09-18'       #last date ISP reset the quota
RENEWAL_DAYS=28                #renewal every xxx days
QUOTA=$(( 5 * 1073741824 ))    #bytes

# if the script is run without parameters it outputs QUOTA and RENEWAL_DAYS, remaining quota for the period,
# remaining days before reset, current quota
# if the script is run with any parameter (e.g. quota_period.sh -c) it resets and updates gargoyle quota
#
# how to use
# In gargoyle GUI / Firewall / Quotas add a new quota. Set the parameters to:
# Applies to: Entire Local Network
# Max Total Up+Down: 100 MB
# Quota Resets: Every Day
# Reset Hour: 00:00
# Quota is Active: Always
# When Exceeded: choose if you want to shutdown Internet access or throttle bandwith (to a very low and unusable value)
# Click on Add New Quota and on Save Changes
#
# Run the script every day, e.g.:
# ssh to the router and run crontab -e
# add a line such as
# 5 0 0 0 0 /root/quota_period.sh -c >/dev/null 2>&1
# the script runs every day at 00:05
# add execute permission to the file

# nothing to change beyond this line!

MPHR=60    # Minutes per hour.
HPD=24     # Hours per day.

diff () {
        printf '%s' $(( $(date -u +%s) -
                        $(date -u -d "$RENEWAL_DATE" +%s)))
#        printf '%s' $(( $(date -u -d "2016-11-12" +%s) -                           
#                        $(date -u -d "$RENEWAL_DATE" +%s)))                           
}

get_bandwith () {
  LINE="$(/usr/bin/bw_get -i $1 -h 2> /dev/null | /bin/grep -v '^$' | /usr/bin/head -n -1 | /usr/bin/tail -$2)"

  used=0
  while read -r bw other
    do
      if [ "$bw" -eq "$bw" ] 2>/dev/null
      then
        used=$(( used+bw ))
      fi
    done <<EOF
    $LINE
EOF
   
  echo $used  #do not remove this line, it is the return value of the function
}

past_days=$(( $(diff) /$MPHR /$MPHR /$HPD % $RENEWAL_DAYS )) # days since last quota reset
remaining_days=$(( 28-past_days)) # days to next quota reset

download=$(get_bandwith "total5-download-day-365" "$past_days")
upload=$(get_bandwith "total5-upload-day-365" "$past_days")

bw_used=$((download+upload))

if [ $bw_used -ge $QUOTA ]                                           
then                                                                                                                                 
  quotaToday=0                                                   
else                                                                     
  quotaToday=$(((QUOTA-bw_used)/remaining_days))                       
fi

if [ "$#" -eq "0" ]
then
  echo
  echo "Plan: $QUOTA Bytes / $RENEWAL_DAYS days"
  echo "Remaining: $((QUOTA-bw_used)) Bytes / $remaining_days day(s)"
  echo "Quota for today: $(uci get firewall.quota_1.combined_limit)"
  exit
fi               
 
uci set firewall.quota_1.combined_limit="$quotaToday"
uci commit

sh /usr/lib/gargoyle/restart_firewall.sh
if [ -d "/usr/data/quotas/" ] ; then rm -rf /usr/data/quotas/* ; fi ;
/usr/bin/backup_quotas

exit

Last edited by emmexx on Sat Feb 11, 2017 12:58 pm, edited 1 time in total.

ispyisail
Moderator
Posts: 4705
Joined: Mon Apr 06, 2009 3:15 am
Location: New Zealand

Re: Daily quota based on remaining monthly quota

Postby ispyisail » Mon Oct 17, 2016 1:48 pm

Thanks

ArcticCat
Posts: 12
Joined: Wed Nov 23, 2016 6:45 pm

Re: Daily quota based on remaining monthly quota

Postby ArcticCat » Thu Nov 24, 2016 12:48 am

I've been looking for something similar for a long time thanks

thank you so much :D

Do you think it could be modified so

1) The quota is per user/IP ?
2) I have unlimited night quota can it be done to be active on specific time only ?

emmexx
Posts: 11
Joined: Thu Sep 29, 2016 6:01 am

Re: Daily quota based on remaining monthly quota

Postby emmexx » Sat Feb 11, 2017 12:31 pm

ArcticCat wrote:Do you think it could be modified so

1) The quota is per user/IP ?
2) I have unlimited night quota can it be done to be active on specific time only ?

Sorry for the late answer, I didn't receive the reply notification.

You can get different types of data from bw_get.
I used this command to get the various types of info that bw_get can give you:

Code: Select all

cat /tmp/bw_backup/do_bw_backup.sh | grep bw_get | sed 's/.*bw_get/bw_get/' | sed 's/\-f .*/-t/g'


Code: Select all

bwget -i "bdist4-download-day-31" -h
is a good candidate.
and

Code: Select all

bwget -i "bdist4-upload-day-31" -h


For the unlimited night quota you could write another script that disables the quota and let cron run it at the right hour.
E.g. at midnight cron runs a script that disables quota and at 6 you run my script.
You should save the used bandwidth value when disabling the quota and subtract that value when you enable the quota again, otherwise the nightly bandwith used would add up to the limited quota.

bye
maxx
Last edited by emmexx on Sat Feb 11, 2017 1:03 pm, edited 1 time in total.


Return to “Monitoring / Quota / QoS Issues”

Who is online

Users browsing this forum: No registered users and 1 guest