This is an old revision of the document!
View WWAN data volume statistics for a month
Goal
This SDK script queries the WWAN data volume from Download. It collects the value for one month and resets the value for the next month. This provides information on how much free data volume the SIM card still has for that month. The customer is informed after the data has been used up. When 50 percent of the data has been used, an email is sent every day. When 75 percent of the data has been used, an email is sent every 12 hours. When 90 percent of the data has been used, you receive an email every 6 hours. If 100 percent of the data volume has already been used within the month, you receive an email every 20 minutes and an additional text message informing you that only 64 kBits/s are now available in the mobile network. The subject line contains additional information such as the serial number and router name, so you can better identify which router is affected.
Prerequisites
NetModule Wireless Router with wireless connection
NetModule wireless router with a WWAN module
-
Not available for legacy products NB1600, NB2700, NB3700, NB3710
The wiki was tested with router software version 5.0.0.101.
1. Setting up an email client on the router
The configuration parameters for the mail server must be entered under the “E-mail” menu item in the “Configuration” tab. This function is then used by the SDK script.
Under point 1, an email address must be stored from the mail server.
Under point 2, the SMTP server is stored.
Under point 3, the server port is stored. Ports 25, 587, and 465 are normally available.
Under points 4 and 5, the user name and password of the email client are stored.
Once the client has been stored in the router, its functionality can be tested.
You can send an email under the “Testing” tab. If everything has been entered correctly, it will then be sent.
2. Setting up an SMS client on the router
The function must be activated under the “SMS” menu item in the “Administration” tab.
This function is then used by the SDK script.
Admin status is activated under point 1.
The SMS dispatch reports are activated under point 2.
The confirmation parameters are read from the SIM card and stored. If this has been carried out successfully, the status is “ready” and the SIM card is “registered”.
Once the SMS client has been saved in the router, its functionality can be tested.
You can send an SMS under the “Testing” tab. If everything has been entered correctly, it will then be sent.
3. Set up the SDK script on the router
In the first step, the SDK function is activated and further options are specified.
The function is activated under point 1.
Under point 2, we free up memory for the execution of the script. For this SDK script, 100 MB is sufficient; only a few variables are stored temporarily for the execution of the program.
Under point 3, we activate monitoring to check whether the script is still being processed correctly. We use the router's core function in the program. Monitoring makes sense here.
In the second step, we store the SDK script in Job Management.
First, we store the SDK script under Job Management. Using the plus button under point 3, we add a script.
After pressing the plus button, a new window opens with settings.
First, assign a name to the SDK process. In the second step, you can insert the SDK script using the “upload” function. You can open the script by clicking on the “show code” button in the WIKI and then download the “check_data_volume.are” file. Once you have saved the file on your computer, you can search for it in step 3 using Browse and select it. The last step, “Apply“, saves everything to the router.
The “check_data_volume.are” script can be downloaded via the “show code” link.
show code
- check_data_volume.are
/* DESC: This script resets the statistics value of the WWAN1 module once a month.
* If the data volume exceeds 50 percent, 75 percent, 90 percent, or
* 100 percent during the month, an email is automatically sent
* with the relevant information.
* When 100 percent of the data volume has been used up,
* a text message is sent for security reasons.
* Copyright (C) 2025 NetModule AG, Switzerland
*/
release_point = 0;
release_point_alert_email = 1;
release_point_alert2_email = 1;
alert2_value = 0;
release_point_info_email = 1;
info_value = 0;
release_point_info2_email = 1;
info2_value = 0;
######################################################################
########### Please only make changes to the script here ###########
######################################################################
interval = 1200; # The waiting time for the next run. The value is given in seconds. < 20 minutes >
datavolume = 30000000000; # Enter the data volume in bytes here. That's one gigabyte: 1 000 000 000 < 30 GBytes >
to = "<mail-address>"; # Email address for the alert and info Email
sms_number = "<SMS-number>"; # SMS Number for alert SMS 100 percent
# *** 100 percent alert all 20 minutes ***
alert2_value_time = 18; # The interval time multiplied by the alert2_value_time value < 1200 sec * 18 = 6 hours > 90 percent
info_value_time = 36; # The interval time multiplied by the info_value_time value < 1200 sec * 36 = 12 hours > 75 percent
info2_value_time = 72; # The interval time multiplied by the info_value_time value < 1200 sec * 72 = 24 hours > 50 percent
######################################################################################################
DEBUG=false; # Enable debugging with true or disable with false
######################################################################################################
printf("The SDK script is started\n");
while (true) {
year = strftime("%Y",localtime(time()));
year = (int) year;
if(DEBUG)printf("Current year: %s\n",year);
month = strftime("%m",localtime(time()));
month = (int) month;
if(DEBUG)printf("Current month: %s\n",month);
if (month == 2) {
## leap year check
if ((year % 400 == 0) || (year % 100 != 0 && year % 4 == 0)){
if(DEBUG)printf("Number of days in this month: 29\n");
number_of_days = 29;
} else {
if(DEBUG)printf("Number of days in this month: 28\n");
number_of_days = 28;
}
} else if (month == 4 || month == 6 || month == 9 || month == 11){
if(DEBUG)printf("Number of days in this month: 30\n");
number_of_days = 30;
} else {
if(DEBUG)printf("Number of days in this month: 31\n");
number_of_days = 31;
}
current_days = strftime("%d",localtime(time()));
current_days = (int) current_days;
if(DEBUG)printf("Current days: %s\n",current_days);
if (current_days == number_of_days){
if(DEBUG)printf("Current days and number of days in this month are the same\n");
if (release_point == 0) {
ret = nb_reset_statistics ("WANLINK1");
if(DEBUG)printf("The statistics are reset\n");
release_point = 1;
} else {
if(DEBUG)printf("The release point is not Null\n");
if(DEBUG)printf("The statistics are not reset\n");
}
} else {
if(DEBUG)printf("Current days and number of days in this month are not the same\n");
if(DEBUG)printf("The statistics are not reset\n");
release_point = 0;
}
status = nb_status("wan");
date_since = struct_get(status, "WANLINK1_DATA_SINCE");
date_download = struct_get(status, "WANLINK1_DATA_DOWNLOADED");
if(DEBUG)printf("Time of data collection: %s\n",date_since);
if(DEBUG)printf("%s bytes have already been downloaded via the mobile connection\n",date_download);
temp = date_download;
suffix=mkarray("Byte", "KByte", "MByte", "GByte", "TByte");
(int) i = 0;
count = date_download;
while (count >= 1024 && i < 4) {
count = (float) count;
count /= 1024;
i++;
}
system = nb_status("system");
serial_number = struct_get(system , "SERIAL_NUMBER");
if(DEBUG)printf("The Serial Number form the Router: %s\n",serial_number);
config = nb_status("config");
network_hostname = struct_get(config , "network.hostname");
if(DEBUG)printf("The Network Hostname form the Router: %s\n",network_hostname);
if(DEBUG)printf("%.2f %s\n", count, suffix[i]);
if(DEBUG)printf("The raw data: %s\n",temp);
percentage_value = temp / (datavolume / 100);
if(DEBUG)printf("%s percent of the data volume on the SIM card has been used up\n",percentage_value);
if (percentage_value > 100){
if(DEBUG)printf("The volume allowance on the SIM card has been completely used up\n");
if(DEBUG)printf("The mobile connection will be throttled to a data speed of 64 kBits/s\n");
if (release_point_alert_email == 1){
msg = sprintf("The volume allowance on the SIM card has been completely used up. The mobile connection will be throttled to a data speed of 64 kBits/s");
subj = sprintf("Data volume at 100 percent Serial-Number:%s Network-Hostname:%s",serial_number ,network_hostname);
ret = nb_email_send(to, subj , msg);
sleep(1);
if (ret == 0){
if(DEBUG)printf("Successfully sent E-Mail to %s\n", to);
release_point_alert_email = 0;
} else {
if(DEBUG)printf("Unable to send E-Mail\n");
nb_syslog("Unable to send E-Mail\n");
release_point_alert_email = 1;
}
id = nb_sms_send(sms_number , subj);
sleep(1);
if (id){
if(DEBUG)printf("SMS to %s (ID %s) has been spooled\n",sms_number, id );
release_point_alert_email = 0;
} else {
if(DEBUG)printf("Unable to send SMS to %s\n",sms_number);
nb_syslog("Unable to send SMS\n");
release_point_alert_email = 1;
}
}
} else if (percentage_value >= 90 && percentage_value < 100){
if(DEBUG)printf("90 percent of the SIM card's data allowance has been used.\nCurrent usage is %s percent\n",percentage_value);
alert2_value = alert2_value + 1;
if(DEBUG)printf("%s\n",alert2_value);
if (release_point_alert2_email == 1){
msg = sprintf("90 percent of the SIM card's data allowance has been used. Current usage is %s percent",percentage_value);
subj = sprintf("Data volume at 90 percent Serial-Number:%s Network-Hostname:%s",serial_number ,network_hostname);
ret = nb_email_send(to, subj , msg);
sleep(1);
if (ret == 0){
if(DEBUG)printf("Successfully sent E-Mail to %s\n", to);
release_point_alert2_email = 0;
alert2_value = 0;
} else {
if(DEBUG)printf("Unable to send E-Mail\n");
nb_syslog("Unable to send E-Mail\n");
release_point_alert2_email = 1;
}
}
} else if (percentage_value >= 75){
if(DEBUG)printf("Two-thirds of the SIM card's data allowance has been used.\nCurrent usage is %s percent\n",percentage_value);
info_value = info_value + 1;
if(DEBUG)printf("%s\n",info_value);
if (release_point_info_email == 1){
msg = sprintf("Two-thirds of the SIM card's data allowance has been used. Current usage is %s percent",percentage_value);
subj = sprintf("Data volume at 75 percent Serial-Number:%s Network-Hostname:%s",serial_number ,network_hostname);
ret = nb_email_send(to, subj , msg);
sleep(1);
if (ret == 0){
if(DEBUG)printf("Successfully sent E-Mail to %s\n", to);
release_point_info_email = 0;
info_value = 0;
} else {
if(DEBUG)printf("Unable to send E-Mail\n");
nb_syslog("Unable to send E-Mail\n");
release_point_info_email = 1;
}
}
} else if (percentage_value >= 50){
if(DEBUG)printf("Half of the SIM card's data allowance has been used.\nCurrent usage is %s percent\n",percentage_value);
info2_value = info2_value + 1;
if(DEBUG)printf("%s\n",info2_value);
if (release_point_info2_email == 1){
msg = sprintf("Half of the SIM card's data allowance has been used. Current usage is %s percent",percentage_value);
subj = sprintf("Data volume at 50 percent Serial-Number:%s Network-Hostname:%s",serial_number ,network_hostname);
ret = nb_email_send(to, subj , msg);
sleep(1);
if (ret == 0){
if(DEBUG)printf("Successfully sent E-Mail to %s\n", to);
release_point_info2_email = 0;
info2_value = 0;
} else {
if(DEBUG)printf("Unable to send E-Mail\n");
nb_syslog("Unable to send E-Mail\n");
release_point_info2_email = 1;
}
}
} else if (percentage_value >= 25){
if(DEBUG)printf("A quarter of the SIM card's data allowance has been used.\nCurrent usage is %s percent\n",percentage_value);
} else {
if(DEBUG)printf("Currently using %s percent\n",percentage_value);
}
sleep(interval); # 20 minutes
printf("\nNext run\n");
release_point_alert_email = 1;
if (alert2_value >= alert2_value_time){
release_point_alert2_email = 1;
}
if (info_value >= info_value_time){
release_point_info_email = 1;
}
if (info2_value >= info2_value_time){
release_point_info2_email = 1;
}
}
exit(0);
Next, set up the trigger that will start the script.
Here, too, pressing the plus button opens a new window with insertion options.
Here, too, pressing the plus button opens a new window with insertion options.
Again, start by assigning a name to the SDK process. Use the “event-based” option as the trigger type for this script. Select the “sdk-startup” event from the list. Why do we use these settings for the script? The script was created as an endless script. The commands are controlled and executed in the script. Errors are output and the program is then terminated. The event starts the script when the daemon of the SDK program is started by the router. This is also advantageous if the watchdog restarts the SDK daemon on the router. In this case, the script is also reactivated. The “Apply” button saves the changes back to the router.
4. Important settings in the SDK script
show code
- check_data_volume.are
/* DESC: This script resets the statistics value of the WWAN1 module once a month.
* If the data volume exceeds 50 percent, 75 percent, 90 percent, or
* 100 percent during the month, an email is automatically sent
* with the relevant information.
* When 100 percent of the data volume has been used up,
* a text message is sent for security reasons.
* Copyright (C) 2025 NetModule AG, Switzerland
*/
release_point = 0;
release_point_alert_email = 1;
release_point_alert2_email = 1;
alert2_value = 0;
release_point_info_email = 1;
info_value = 0;
release_point_info2_email = 1;
info2_value = 0;
######################################################################
########### Please only make changes to the script here ###########
######################################################################
interval = 1200; # The waiting time for the next run. The value is given in seconds. < 20 minutes >
datavolume = 30000000000; # Enter the data volume in bytes here. That's one gigabyte: 1 000 000 000 < 30 GBytes >
to = "<mail-address>"; # Email address for the alert and info Email
sms_number = "<SMS-number>"; # SMS Number for alert SMS 100 percent
# *** 100 percent alert all 20 minutes ***
alert2_value_time = 18; # The interval time multiplied by the alert2_value_time value < 1200 sec * 18 = 6 hours > 90 percent
info_value_time = 36; # The interval time multiplied by the info_value_time value < 1200 sec * 36 = 12 hours > 75 percent
info2_value_time = 72; # The interval time multiplied by the info_value_time value < 1200 sec * 72 = 24 hours > 50 percent
######################################################################################################
DEBUG=false; # Enable debugging with true or disable with false
######################################################################################################
printf("The SDK script is started\n");
while (true) {
year = strftime("%Y",localtime(time()));
year = (int) year;
if(DEBUG)printf("Current year: %s\n",year);
month = strftime("%m",localtime(time()));
month = (int) month;
if(DEBUG)printf("Current month: %s\n",month);
if (month == 2) {
## leap year check
if ((year % 400 == 0) || (year % 100 != 0 && year % 4 == 0)){
if(DEBUG)printf("Number of days in this month: 29\n");
number_of_days = 29;
} else {
if(DEBUG)printf("Number of days in this month: 28\n");
number_of_days = 28;
}
} else if (month == 4 || month == 6 || month == 9 || month == 11){
if(DEBUG)printf("Number of days in this month: 30\n");
number_of_days = 30;
} else {
if(DEBUG)printf("Number of days in this month: 31\n");
number_of_days = 31;
}
current_days = strftime("%d",localtime(time()));
current_days = (int) current_days;
if(DEBUG)printf("Current days: %s\n",current_days);
if (current_days == number_of_days){
if(DEBUG)printf("Current days and number of days in this month are the same\n");
if (release_point == 0) {
ret = nb_reset_statistics ("WANLINK1");
if(DEBUG)printf("The statistics are reset\n");
release_point = 1;
} else {
if(DEBUG)printf("The release point is not Null\n");
if(DEBUG)printf("The statistics are not reset\n");
}
} else {
if(DEBUG)printf("Current days and number of days in this month are not the same\n");
if(DEBUG)printf("The statistics are not reset\n");
release_point = 0;
}
status = nb_status("wan");
date_since = struct_get(status, "WANLINK1_DATA_SINCE");
date_download = struct_get(status, "WANLINK1_DATA_DOWNLOADED");
if(DEBUG)printf("Time of data collection: %s\n",date_since);
if(DEBUG)printf("%s bytes have already been downloaded via the mobile connection\n",date_download);
temp = date_download;
suffix=mkarray("Byte", "KByte", "MByte", "GByte", "TByte");
(int) i = 0;
count = date_download;
while (count >= 1024 && i < 4) {
count = (float) count;
count /= 1024;
i++;
}
system = nb_status("system");
serial_number = struct_get(system , "SERIAL_NUMBER");
if(DEBUG)printf("The Serial Number form the Router: %s\n",serial_number);
config = nb_status("config");
network_hostname = struct_get(config , "network.hostname");
if(DEBUG)printf("The Network Hostname form the Router: %s\n",network_hostname);
if(DEBUG)printf("%.2f %s\n", count, suffix[i]);
if(DEBUG)printf("The raw data: %s\n",temp);
percentage_value = temp / (datavolume / 100);
if(DEBUG)printf("%s percent of the data volume on the SIM card has been used up\n",percentage_value);
if (percentage_value > 100){
if(DEBUG)printf("The volume allowance on the SIM card has been completely used up\n");
if(DEBUG)printf("The mobile connection will be throttled to a data speed of 64 kBits/s\n");
if (release_point_alert_email == 1){
msg = sprintf("The volume allowance on the SIM card has been completely used up. The mobile connection will be throttled to a data speed of 64 kBits/s");
subj = sprintf("Data volume at 100 percent Serial-Number:%s Network-Hostname:%s",serial_number ,network_hostname);
ret = nb_email_send(to, subj , msg);
sleep(1);
if (ret == 0){
if(DEBUG)printf("Successfully sent E-Mail to %s\n", to);
release_point_alert_email = 0;
} else {
if(DEBUG)printf("Unable to send E-Mail\n");
nb_syslog("Unable to send E-Mail\n");
release_point_alert_email = 1;
}
id = nb_sms_send(sms_number , subj);
sleep(1);
if (id){
if(DEBUG)printf("SMS to %s (ID %s) has been spooled\n",sms_number, id );
release_point_alert_email = 0;
} else {
if(DEBUG)printf("Unable to send SMS to %s\n",sms_number);
nb_syslog("Unable to send SMS\n");
release_point_alert_email = 1;
}
}
} else if (percentage_value >= 90 && percentage_value < 100){
if(DEBUG)printf("90 percent of the SIM card's data allowance has been used.\nCurrent usage is %s percent\n",percentage_value);
alert2_value = alert2_value + 1;
if(DEBUG)printf("%s\n",alert2_value);
if (release_point_alert2_email == 1){
msg = sprintf("90 percent of the SIM card's data allowance has been used. Current usage is %s percent",percentage_value);
subj = sprintf("Data volume at 90 percent Serial-Number:%s Network-Hostname:%s",serial_number ,network_hostname);
ret = nb_email_send(to, subj , msg);
sleep(1);
if (ret == 0){
if(DEBUG)printf("Successfully sent E-Mail to %s\n", to);
release_point_alert2_email = 0;
alert2_value = 0;
} else {
if(DEBUG)printf("Unable to send E-Mail\n");
nb_syslog("Unable to send E-Mail\n");
release_point_alert2_email = 1;
}
}
} else if (percentage_value >= 75){
if(DEBUG)printf("Two-thirds of the SIM card's data allowance has been used.\nCurrent usage is %s percent\n",percentage_value);
info_value = info_value + 1;
if(DEBUG)printf("%s\n",info_value);
if (release_point_info_email == 1){
msg = sprintf("Two-thirds of the SIM card's data allowance has been used. Current usage is %s percent",percentage_value);
subj = sprintf("Data volume at 75 percent Serial-Number:%s Network-Hostname:%s",serial_number ,network_hostname);
ret = nb_email_send(to, subj , msg);
sleep(1);
if (ret == 0){
if(DEBUG)printf("Successfully sent E-Mail to %s\n", to);
release_point_info_email = 0;
info_value = 0;
} else {
if(DEBUG)printf("Unable to send E-Mail\n");
nb_syslog("Unable to send E-Mail\n");
release_point_info_email = 1;
}
}
} else if (percentage_value >= 50){
if(DEBUG)printf("Half of the SIM card's data allowance has been used.\nCurrent usage is %s percent\n",percentage_value);
info2_value = info2_value + 1;
if(DEBUG)printf("%s\n",info2_value);
if (release_point_info2_email == 1){
msg = sprintf("Half of the SIM card's data allowance has been used. Current usage is %s percent",percentage_value);
subj = sprintf("Data volume at 50 percent Serial-Number:%s Network-Hostname:%s",serial_number ,network_hostname);
ret = nb_email_send(to, subj , msg);
sleep(1);
if (ret == 0){
if(DEBUG)printf("Successfully sent E-Mail to %s\n", to);
release_point_info2_email = 0;
info2_value = 0;
} else {
if(DEBUG)printf("Unable to send E-Mail\n");
nb_syslog("Unable to send E-Mail\n");
release_point_info2_email = 1;
}
}
} else if (percentage_value >= 25){
if(DEBUG)printf("A quarter of the SIM card's data allowance has been used.\nCurrent usage is %s percent\n",percentage_value);
} else {
if(DEBUG)printf("Currently using %s percent\n",percentage_value);
}
sleep(interval); # 20 minutes
printf("\nNext run\n");
release_point_alert_email = 1;
if (alert2_value >= alert2_value_time){
release_point_alert2_email = 1;
}
if (info_value >= info_value_time){
release_point_info_email = 1;
}
if (info2_value >= info2_value_time){
release_point_info2_email = 1;
}
}
exit(0);