SMS Server Tools 3
 Menu
Basic information:
Additional information:
Support:
Get SMS Server Tools 3:
Additional Options

 Sponsored links

 Search
Custom Search

 Visitor locations
 
 SMS Server Tools 3 Community
Welcome, Guest. The forum is currently read-only, but will open soon. Thu Nov 21, 2024 13:16
SMSTools3 Community » Sample scripts / setups Bottom

Sample config and script for regular_run and balance of prepaid SIM using USSD

Login and Post Reply

Page:  1  2  Next

Author Post
Administrator
Registered:
May 2009
Location: Jyväskylä, Finland
This sample works with the version 3.1.7 or later, and is targeted to systems where prepaid SIM is used.

When a defined number of messages are sent, balance is asked using USSD. The response is saved to the file and it's also logged. It is also possible to ask the balance "on demand", by creating a "flag file": touch /var/spool/sms/stats/get.GSM1.balance.

When the balance goes too low, an alert SMS is sent. Also, the expiration time is checked and alert is sent if necessary.

If the balance was not asked for a long time, the script will ask it by itself. The setting max_age defaults to 24 hours. This is for systems where messages are sent very rarely, and therefore the balance and expiration are not checked and the SIM may expire accidentally.

Notice that even when this sample is using stats directory, it is not required that the statistics functionality (libmm) is available.

The config:

devices = GSM1
logfile = /var/log/smsd.log
loglevel = notice
smart_logging = yes

stats = /var/spool/sms/stats

[default]
regular_run_interval = 10
regular_run_logfile = /var/log/smsd_regular_run.log

[GSM1]
device = /dev/ttyUSB0
incoming = yes
pin = ignore

regular_run = /var/spool/sms/regular_run/GSM1.sh
regular_run_post_run = /var/spool/sms/regular_run/GSM1.sh
regular_run_cmdfile = /var/spool/sms/regular_run/GSM1.cmdfile
regular_run_statfile = /var/spool/sms/regular_run/GSM1.statfile
 
'smsdconf' Syntax Highlight powered by GeSHi


The script /var/spool/sms/regular_run/GSM1.sh:

#!/bin/bash

###########################################################################
# Global settings:

get_balance_after=5 # 1 = get the balance after at least one message is sent.

max_age=24 # an integer for hours, 0 = disable periodic checking.

alert_balance=5 # an integer for "euros".

alert_expiration=14 # an integer for days.

alert_to="358401234567" # "" = no SMS is sent.

###########################################################################
# Device depended settings:

# Comment out the next command if a DEVICENAME setting should be taken from
# the name of this file (which can be a symbolic link). For example:
# /var/spool/sms/regular_run/GSM1.sh
#DEVICENAME="GSM1"

[ -z "$DEVICENAME" ] && tmp=${0##*/} && DEVICENAME=${tmp%%.*}
balance_file="/var/spool/sms/stats/${DEVICENAME}.balance"
counter_file="/var/spool/sms/stats/${DEVICENAME}.counter"
get_balance_flagfile="/var/spool/sms/stats/get.${DEVICENAME}.balance"
regular_run_cmdfile="/var/spool/sms/regular_run/${DEVICENAME}.cmdfile"
regular_run_statfile="$2"
outgoing="/var/spool/sms/outgoing"

###########################################################################
# START OF OPERATOR SPECIFIC SETTINGS

# If more than one modem is used and they have different operator specific
# settings, move this section to the files for each modem and include the
# file here using the following command:
# . /var/spool/sms/regular_run/${DEVICENAME}.operator_settings.sh

# Fix this if a different command is required in your network:
ussd_command="AT+CUSD=1,\"*100#\""

# This is an example result for the query:
# 2010-05-09 14:16:11,5, GSM1: CMD: AT+CUSD=1,"*100#": OK +CUSD: 2, ...
# ... "Liittymäsi saldo on 22.36 EUR. Puheaikasi vanhenee 27.04.2011.",15

# Defines how balance can be found from the result:
balance_prefix="saldo on "

# Defines how the "euros" part ends:
balance_suffix="."

# Defines how the expiration date can be found.
# With an empty setting the expiration is not checked.
balance_expiration="vanhenee "

# Helper function for converting date from the answer to the format yyyy-mm-dd
# Modify this if necessary.
extract_expiration()
{
  # datestamp to format yyyy-mm-dd
  echo "${1:6:4}-${1:3:2}-${1:0:2}"
}

: <<COMMENTBLOCK

Example 2:
..."Balance subscription is EUR 22.36. Your allotted time expires 04/27/2011."

balance_prefix="EUR "
balance_suffix="."
balance_expiration="expires "
Command in extract_expiration(): echo "${1:6:4}-${1:0:2}-${1:3:2}"

Example 3:
..."The balance is 34.84 B. & valid until 26/07/10 "

balance_prefix="is "
balance_suffix="."
balance_expiration="until "
Command in extract_expiration(): echo "20${1:6:2}-${1:3:2}-${1:0:2}"

Example 4:
...Ihr Restguthaben ist CHF 18,87

balance_prefix="CHF "
balance_suffix=","
balance_expiration=""

COMMENTBLOCK


# END OF OPERATOR SPECIFIC SETTINGS
###########################################################################

substr()
{
  local string=$1
  local prefix=$2
  local suffix=$3

  local ppref=${string%${prefix}*}

  # Changed 2010-11-02:
  if [[ "$ppref" == *${prefix}* ]]
  then
    string=${string//\"/}

    local position=$(echo | awk '{
      print index("'
"${string}"'", "'"${prefix}"'")
    }'
)

    if [ $position -gt 0 ]; then
      ppref=${string:0:$(($position - 1))}
    fi
  fi
  # -------------------

  local ssuff=${string#*${suffix}}
  local nopref=${string#${ppref}${prefix}}
  echo ${nopref%${suffix}${ssuff}}
}

#--------------------------------------------------------------------------
date2stamp()
{
  case `uname` in
    Darwin)
      date -juf "%Y-%m-%d %H:%M:%S" "$1" +%s
      ;;
    *)
      date --utc --date "$1" +%s
      ;;
  esac
}

#--------------------------------------------------------------------------
dateDiff()
{
  local sec=0

  case $1 in
    -s) sec=1; shift;;
    -m) sec=60; shift;;
    -h) sec=3600; shift;;
    -d) sec=86400; shift;;
    *) sec=86400;;
  esac

  local dte1=$(date2stamp "$1")
  local dte2=$(date2stamp "$2")
  local diffSec=$((dte2-dte1))

  echo $((diffSec/sec))
}

###########################################################################

test -e "$counter_file" || exit 1

messages=$(formail -zx ${DEVICENAME}: < "$counter_file")

if [ "$1" = "PRE_RUN" ]; then

  get_balance=0

  # Get the balance if it was wanted:
  [ -w "$get_balance_flagfile" ] && get_balance=1 && \
     unlink "$get_balance_flagfile"

  if [ -r "$balance_file" ]; then
    # Get the balance if a defined number of messages are sent.
    messagesb=$(formail -zx Messages: < "$balance_file")
    [ $(($messages - $messagesb)) -ge $get_balance_after ] && get_balance=1
  else
    # Get the balance because the previous value is not known.
    get_balance=1
  fi

  # Check the age of the last query if necessary:
  if [ $get_balance = 0 ] && [ $max_age -gt 0 ]; then
    last_query=$(formail -zx Last_query: < "$balance_file")
    age=$(dateDiff -h "$last_query" "$(date +"%Y-%m-%d %T")")
    [ $age -ge $max_age ] && get_balance=1
  fi

  [ $get_balance -gt 0 ] && echo "$ussd_command" > "$regular_run_cmdfile"

else

  # 2011-06-29: Check that USSD command is found:
  result=""
  if [ -r "$regular_run_statfile" ]; then
    tmp=${ussd_command//\"/\\\"}
    tmp=${tmp//\*/\\*}
    result=$(cat "$regular_run_statfile" | grep "$tmp")
  fi

  if [ -n "$result" ]; then

    balance_low=-1 # Initial value means unknown.
    balance=-1
    balance_alerted=""
    expiration_low=-1
    expiration=-1
    expiration_alerted=""
    sms_alert=""
    current_alert=""

    # 2010-11-02: Change Ctrl-B to $
    result=$(echo "${result//$'\x02'/$}")

    # Check that required words exists:
    if [[ "$result" == *${balance_prefix}* ]] && \
       [[ "$result" == *${balance_suffix}* ]]
    then
      # Get the balance and check it:
      balance=$(substr "$result" "$balance_prefix" "$balance_suffix")
      balance_low=0

      if [ $(expr "$balance" + 1 2> /dev/null) ]; then
        [ $balance -le $alert_balance ] && balance_low=1
      else
        echo "Error while parsing an integer: $balance"
      fi
    else
      echo "Error while parsing the answer (balance): $result"
    fi

    # Get the expiration date if defined, and check it:
    if [ -n "$balance_expiration" ]; then
      if [[ "$result" == *${balance_expiration}* ]]; then
        expiration_low=0
        expiration=$(substr "$result" "$balance_expiration" "")
        expiration=$(extract_expiration "$expiration")
        expiration=$(dateDiff -d "$(date +"%Y-%m-%d")" "$expiration")
        [ $expiration -le $alert_expiration ] && expiration_low=1
      else
        echo "Error while parsing the answer (expiration): $result"
      fi
    fi

    if [ -e "$balance_file" ]; then
      # Get previous values:
      current_alert=$(formail -zx Current_alert: < "$balance_file")
      balance_alerted=$(formail -zx Balance_alerted: < "$balance_file")
      expiration_alerted=$(formail -zx Expiration_alerted: < "$balance_file")
    fi

    balance_gone_low=0 # added 2010-11-03
    # If not yet alerted and the balance has gone low, alert now:
    if [ -z "$balance_alerted" ] && [ $balance_low = 1 ]; then
      balance_gone_low=1
      balance_alerted=$(date +"%Y-%m-%d %T")
      tmp="The balance has gone low ($balance)."
      echo "$tmp" # This message goes to the smsd.log
      [ -z "$sms_alert" ] && sms_alert="Alert:"
      sms_alert="${sms_alert} ${tmp}"

      # If the expiration is already alerted, but the issue is still active,
      # include it in the message:
      if [ -n "$expiration_alerted" ] && [ $expiration_low = 1 ]; then
        sms_alert="${sms_alert} The expiration is also near ($expiration days)."
      fi
    fi

    # Remove an outdated alert:
    [ -n "$balance_alerted" ] && [ $balance_low = 0 ] && balance_alerted=""

    # If not yet alerted and the expiration is near, alert now:
    if [ -z "$expiration_alerted" ] && [ $expiration_low = 1 ]; then
      expiration_alerted=$(date +"%Y-%m-%d %T")
      tmp="The expiration is near ($expiration days)."
      echo "$tmp" # This message goes to the smsd.log
      [ -z "$sms_alert" ] && sms_alert="Alert:"
      sms_alert="${sms_alert} ${tmp}"

      # If the balance is already alerted, but the issue is still active,
      # include it in the message:
      if [ -n "$balance_alerted" ] && [ $balance_low = 1 ]; then
        if [ $balance_gone_low -eq 0 ]; then
          sms_alert="${sms_alert} The balance is also low ($balance)."
        fi
      fi
    fi

    # Remove an outdated alert:
    [ -n "$expiration_alerted" ] && [ $expiration_low = 0 ] && \
       expiration_alerted=""

    [ -z "$balance_alerted" ] && [ -z "$expiration_alerted" ] && \
       current_alert=""

    if [ -n "$sms_alert" ] && [ -n "$alert_to" ]; then
      # Send the SMS:
      FILE=$(mktemp /tmp/alert_XXXXXX)
      echo "To: $alert_to" >> $FILE
      echo "" >> $FILE
      echo "$DEVICENAME $sms_alert" >> $FILE
      FILE2=$(mktemp "${outgoing}/send_XXXXXX")
      mv $FILE "$FILE2"
    fi

    # Save the details:
    DATE=$(date +"%Y-%m-%d %T")
    echo "Last_query: $DATE" > "$balance_file"
    [ -n "$sms_alert" ] && current_alert="${DATE}, $sms_alert"
    [ -n "$current_alert" ] && \
       echo "Current_alert: $current_alert" >> "$balance_file"
    echo "Messages: $messages" >> "$balance_file"
    echo "Balance: $balance" >> "$balance_file"
    [ -n "$balance_expiration" ] && \
       echo "Expiration: $expiration" >> "$balance_file"
    [ -n "$balance_alerted" ] && \
       echo "Balance_alerted: $balance_alerted" >> "$balance_file"
    [ -n "$expiration_alerted" ] && \
       echo "Expiration_alerted: $expiration_alerted" >> "$balance_file"
    echo "" >> "$balance_file"
    echo "$result" >> "$balance_file"
  fi
fi

exit 0
 
 
'bash' Syntax Highlight powered by GeSHi



« Last edit by keke on Wed Jun 29, 2011 10:18, 163 months ago. »
Member
Registered:
Jun 2010
Location: Finland
For this script to work on Mac OS X, the date command needs a different format:



Administrator
Registered:
May 2009
Location: Jyväskylä, Finland
Topic owner
Thank's for the information. I have updated the script to include that.

Member
Registered:
Sep 2010
Location: Germany
Hello
Does not work this script with Version 3.1.11?

I start smstools the script is asking the balance.

get_balance_after=1

I send a sms GSM1.counter says



But GSM1.balance will not be updated!



I think it will be automatic updated when i send a sms? Is this correct?


« Last edit by cyres on Sun Sep 12, 2010 20:11, 172 months ago. »
Administrator
Registered:
May 2009
Location: Jyväskylä, Finland
Topic owner
There was a bug in the script :( :


 if [ -r "$balance_file" ]; then
   # Get the balance if a defined number of messages are sent.
   messagesb=$(formail -zx Messages: < "$balance_file")
   [ $(($messages - $messagesb)) -ge $get_balance_after ] && get_balance=1
 else


Apply the fixes marked with red color, or copy the script from the first post, I have updated it.

Member
Registered:
Sep 2010
Location: Germany
It works!

Thanks :mrgreen:

Member
Registered:
Jun 2010
Location: Singapore
work great,
please help on how to capture $ symbol (code 0002), and how to handle date format dd mmm yyyy (26 Jan 2011) ?

example ussd answer:

Last_query: 2010-11-02 08:54:20
Current_alert: 2010-11-02 08:53:54, Alert: The expiration is near (-14915 days).
Messages: 8
Balance: -1
Expiration: -14915
Expiration_alerted: 2010-11-02 08:53:54

2010-11-02 08:54:20,5, modem1: CMD: AT+CUSD=1,"*139#",0: +CUSD: 0,"Main: 5.35 Expiry: 26 Jan 2011. Special Bonus: 0.00 Expiry: - *Special Bonus balance is capped at '100'. FIC Expiry: -" OK

Thank you!

Member
Registered:
Jun 2010
Location: Singapore


Should be:
2010-11-02 08:54:20,5, modem1: CMD: AT+CUSD=1,"*139#",0: +CUSD: 0,"Main: $5.35 Expiry: 26 Jan 2011. Special Bonus: $0.00 Expiry: - *Special Bonus balance is capped at $'100'. FIC Expiry: -" OK

Administrator
Registered:
May 2009
Location: Jyväskylä, Finland
Topic owner
johnaa wrote
please help on how to capture $ symbol (code 0002), and how to handle date format dd mmm yyyy (26 Jan 2011) ?

Because in the ussd response there is keyword "Expiry:" existing more than once, I had to change the substr() function. The code in the first post is now updated.

In your case use the following definitions in the script:

balance_prefix="Main: $"
balance_suffix="."
balance_expiration="Expiry: "


You also need to change the way how date is extracted. Use the following code:

# Helper function for converting date from the answer to the format yyyy-mm-dd
# Modify this if necessary.
extract_expiration()
{
  # datestamp to format yyyy-mm-dd
  #echo "${1:6:4}-${1:3:2}-${1:0:2}"

  # Example: 26 Jan 2011.
  local dt=$(echo "$1" | awk '{print $1; print $2; print $3;}')
  dt=${dt//./}
  local stamp=$(date --utc --date "$dt" +%s)
  date --utc --date "1970-01-01 $stamp sec" "+%Y-%m-%d"
}
 
'bash' Syntax Highlight powered by GeSHi


Member
Registered:
Jun 2010
Location: Singapore
Hi. Keke

Thank you very much, for expiry, it work well for date format dd mmm yyyyy now.
but for symbol $, sorry for don't make the thing clear, the problem is:
symbol $ is not displayed correctly in logfile, it display code 0002 instead of $, so I can't use "Main: $" to capture it. please advise.

Quote
Last_query: 2010-11-03 00:04:11
Current_alert: 2010-11-03 00:00:28, Alert: The expiration is near (84 days).
Messages: 3
Balance: -1
Expiration: 84
Expiration_alerted: 2010-11-03 00:00:28

2010-11-03 00:04:11,5, modem1: CMD: AT+CUSD=1,"*139#": +CUSD: 0,"Main: .5.25 Expiry: 26 Jan 2011. Special Bonus: .0.00 Expiry: - *Special Bonus balance is capped at .'100'. FIC Expiry: -" OK

I cut & paste here, but it is not displayed correctly in this site also, it displays "." instead of "0002". I will send you screen shot to you if you need it.

And Balance is always -1, not updated, is it correct ? -- "Balance: -1"

Thank you again

Administrator
Registered:
May 2009
Location: Jyväskylä, Finland
Topic owner
johnaa wrote
but for symbol $, sorry for don't make the thing clear, the problem is:
symbol $ is not displayed correctly in logfile, it display code 0002 instead of $, so I can't use "Main: $" to capture it. please advise.

Oops....

Show the output from hexdump -C < /var/spool/sms/stats/modem1.balance here.

Member
Registered:
Jun 2010
Location: Singapore


Administrator
Registered:
May 2009
Location: Jyväskylä, Finland
Topic owner
Thank's.

For some reason there is Ctrl-B character received. The updated script will now handle it too.

Member
Registered:
Jun 2010
Location: Singapore


Thank, the $ symbol is displayed correctly now, but the low balance alert SMS is not sent out ( alert_balance=5).

Administrator
Registered:
May 2009
Location: Jyväskylä, Finland
Topic owner
After updating the script, did you set all of those settings, especially balance_prefix:

balance_prefix="Main: $"
balance_suffix="."
balance_expiration="Expiry: "

Member
Registered:
Jun 2010
Location: Singapore
Works great with above setting, I got expiry alert SMS and low balance alert SMS as well, Thanks.



Administrator
Registered:
May 2009
Location: Jyväskylä, Finland
Topic owner
There is still one more change in the script: a message "Alert: The balance has gone low (4). The expiration is near (84 days). The balance is also low (4)." looks funny ;). Now the script does not say "balance is also low" if it just told that "balance has gone low".

Member
Registered:
Jul 2011
Location: Warsaw, Poland
#!/bin/bash
MYTIME=$(date +%H%M)
ISTIME=$(expr $MYTIME \> 0659)$(expr $MYTIME \< 2301)

if [ "$ISTIME" = "11" ]; then
{

#
# rest of the script
#

}
fi
 
'bash' Syntax Highlight powered by GeSHi



If you dont want receive balance/expiration alert in the night.
In this example script run only from 7:00 to 23:00 (after 0659, before 2301)

Administrator
Registered:
May 2009
Location: Jyväskylä, Finland
Topic owner
Ines wrote
If you dont want receive balance/expiration alert in the night.

See also this topic: Scheduler for sending messages. Scripts in post #3 can be used if a header Urgency: low is added to the message file.

Member
Registered:
Nov 2011
Location: Russian Federation
Hello keke :)

I didn't understand how does this script work :( And I don't want to use something that I don't understand. Is there a simple way just to check balance before(or after) sending every message? I wrote a simple python script to be used as eventhandler_ussd, it works fine with regular_run_interval, but that is not what I need. How can I run USSD query every time when sms message is sent? I tried using eventhandler with


but I'm recieving errors like this:


and eventhandler_ussd is not launched.

Please, help me :?

Member
Registered:
Oct 2012
Location: Russian Federation
You can decode it:



Member
Registered:
Nov 2012
Location: Bosnia and Herzegovina
I have one problem! I get this error code in smsd.log file PLS help!



Member
Registered:
Sep 2013
Location: Muenster, NRW, Germany
Hello folks,

I'd like to post a script for use as Nagios plugin:
This Script is looking for the substrings Aktuelles and Guthaben that is used by German Telekom:
2014-05-14 15:08:48,5, GSM1: CMD: AT+CUSD=1,"*100#": OK +CUSD: 2,"Aktuelles Guthaben: 2.18 EUR.",15

You can change these strings easily. If you are looking for errors, you can turn on debugging with DEBUG=1.



Comments are appreciated....

Bye,
Tom


« Last edit by LightScape66 on Thu May 15, 2014 15:25, 128 months ago. »
Member
Registered:
Sep 2017
Location: Munich, Germany
I got this script to run on a FreeBSD system (FreeNAS, really) and have some amendments to the script to suggest. Please kindly consider this:

* the message "error parsing an integer" seems incorrect. The echo statement is executed when the current balance is above the warning threshold, which is good. I replaced the message with "Balance $balance is above warning threshold $alert_balance"

* FreeBSD requies the same format for the date() builtin function as Darwin (tehy are both based on BSD), so I extended the date2stamp() routine by another case statement.

* the inline explanation for balance_suffix is misleading as it may understood as indicating the radix (the sign between major and minor money quantities, e.g. between Euros and Euro-cents). I suggest this explanation:
# Defines how the balance amount part ends (NOT the radix)

* some documentation for making the script work might also be valuable to others:
+ file <DEVICE>.counter must exist and contain "<DEVICE>: <n>"
+ file <DEVICE>.balance causes trouble if it does not contain a line "<DEVICE>: <n>"

Member
Registered:
Sep 2017
Location: Munich, Germany
Is there a way of running more than one script per device regularly?

In my setup I need a different USSD command argument for balance (*100#) and lease time (*102#). The way I understand the script it gets run a first time for outputting the command to regular_run_cmdfile and a second time when it picks up the answer from regular_run_statfile. In other words I cannot simply add another USSD command to the existing file and expect it to work.

Login and Post Reply

Page:  1  2  Next

SMSTools3 Community » Sample scripts / setups Top

 
Time in this board is UTC.  

Privacy Policy   SMS Server Tools 3 Copyright © Keijo Kasvi.