Hardware SMS Gateway for Cacti

  • Published In: Tutorial
  • Created Date: 2018-12-06
  • Hits: 5582

Cacti is an open-source web application. The system allows building graphs using RRDtool. Cacti gathers statistical data for specific periods of time and allows representing them in a graphic view. Most often, standard templates are used to represent statistics on a processor load, memory allocation, number running processes, using incoming/outgoing traffic. Basically, Cacti is only a shell to visualize accumulated monitoring data, namely drawing graphs. In this article, we will regard a way of extending Cacti features for sending SMS notifications on monitoring events (SMS gateway for Cacti). To send SMS, it is possible to use the next devices of NetPing company:

This allows minimizing the expenses for third-party services of SMS distribution because in this case, the cost of each SMS will be equal to one specified in the plan of your mobile network operator with no additional commissions.

Requirements to the Equipment

  • NetPing device listed above with the installed SIM card – 1 pc;
  • PC/server with OS Ubuntu and already installed monitoring system Cacti – 1 pc;
  • Local network – 1 pc.

In our example, we use Cacti 0.8.8f, installed at Ubuntu Server 16.04.3 LTS. To get information on configuring the monitoring system Cacti, it is possible to address the official documentation.

Configuring NetPing Devices

To send SMS notifications, there is a need to implement only a part of a basic configuration. In our case, there is a need to configure network parameters for network access of modem NetPing SMSUniPing server solution v4/SMSNetPing 8/PWR-220 v4/SMS and install a working SIM card with a positive balance into a slot of a built-in GSM modem. It is possible to read about a basic and additional configuration of devices in the next documentation:

Implementing Sending E-mail Notifications from the Cacti Monitoring System

There is a need to install additional plugins to get a feature of sending notifications from a Cacti monitoring system. We will need two plugins:

  • Settings – it is a module with settings for plugins, plugins will not work without it.
  • Thold - it is a plugin for notifications when critical parameter values of a device are reached.

To install the plugin, there is a need to download archive with the plugin from the Cacti official website and unzip to the directory /usr/share/cacti/site/plugins/. After unzipping plugins, go to a web interface of the monitoring system Cacti. In the menu on the left, choose the menu item «Plugin Management» (1) and install. In the main area of the web page, sequentially click the buttons «Install Plugin» and «Enable Plugin» in the column «Action» (2). The button «Enable plugin» is available after the plugin is installed.

Cacti installing plugins

After installing plugins, go to the section «Settings» (1) using the menu on the left of the page. In this section, new tabs «Thresholds» and «Mail/DNS» should appear: 

Cacti configuring SMTP

On the tab Mail/DNS (2), there is a need to fill in the next fields:

Test Email – indicate any e-mail address for testing sending e-mail notifications;
Mail Services – specify «PHP mail() function»;
From E-mail Address – indicate the address of an e-mail notification sender. In our example, it is cacti@netping.ru;
From Name – specify the name of the e-mail notification sender. In our example, it is Cacti;
Word Wrap – the number of characters in the line of the email, can be left on default.
Sendmail – a value here is filled in on default. In our example, we use local Sendmail server for sending. More detailed information about deployment and configuration of Sendmail can be found here
SMTP Options – is filled in when using the third party SMTP server;
DNS Options – indicate IP addresses of the primary and secondary DNS servers. DNS Timeout can be left on default.

After filling in all fields, click the button «Save» (3) in the bottom of the page. Then, test configurations by clicking the link «Send a Test Email» (4). If all settings are correct, we will receive a notification about successful sending a test e-mail in the popup window:

Cacti notification about successful test sending of the letter

Now, go to the tab «Thresholds». All settings on the page can be left on default. For further configuration of sending SMS, we need to check a checkbox «Send Alerts as Text»:

Cacti configuring Thresholds

Save the settings by clicking the button «Save».

The next step is creating a contact list for sending notifications. Go to the section «Notification Lists» (1) using the menu on the left of the page. On the page that opens, click  the link «Add» (2) top right:

Cacti creating a contact list

And fill in the fields in the form that opens:

Cacti filling in the form of a contact list

Name – is a name of a contact list. In our example, «List_1»;
Description – is a description of a contact list;
Email Addresses – is a list of e-mail addresses. Here, we also indicate the phone number for sending SMS notifications.

Click the button «Create» for creating a contact list.

Now, configure notifications for thresholds for a temperature sensor. Go to the section «Threshold Templates» using the menu on the left of the page. On the page that opens, click the link «Add» (2) top right:

Cacti switching to the section Threshold Templates

Fill in the fields of the form that opens, the same as shown on the screenshot, and click the button «Create»:

Cacti creating a template

Fill in the fields on the next page:

Cacti filling in the properties of the template

Template Name – is the name of a template. In our example, it is «Thold_Temperature»;
High Warning Threshold – is a top threshold for notification. In our example, a notification will be sent when the temperature exceeds 30°C;
Low Warning Threshold – is a bottom threshold for notification. A notification will be sent when the temperature falls below 10°C;
High Threshold – is a top threshold for the alarm. The alarm will trigger when the temperature exceeds 40°C;
Low Threshold – is a bottom threshold for the alarm. The alarm will trigger when the temperature drops below 5°C;
Warning Notification List – is a contact list for receiving notifications. Choose a previously created «List_1» from the list;
Alert Notification List – is a contact list for receiving the alarm notification. Choose a previously created «List_1» from the list;
Alert Emails – is an alarm notification text. Cyryllic is not supported by the Cacti system;
Warning Emails – is a notification text. Cyryllic is not supported by the Cacti system.

The rest of fields can be left on default. Confirm the change by clicking the button «Save».

The next step is applying the Threshold template to temperature graphs. Go to the section «Graph Management» (1) using the menu on the left of the page. On the page that opens, we choose a temperature graph of the device UniPing server solution v4/SMS that has been built before. Mark a necessary graph by checking the checkbox (2). From the list on the bottom of the page, choose the point «Create Threshold from Template» (3) and click the button «Go» (4):

Cacti selecting a temperature graph

In the form that opens, choose a previously specified template Threshold – «Thold_Temperature» from the list and click the button «Continue»:

Cacti applying Threshold template for a temperature graph

Ready! After setting all parameters indicated above, the email of a system administrator specified in the contact list will receive notifications about temperature getting close to threshold values and a deviation of temperature from the normal values.

Implementing Sending SMS Notifications from the Cacti Monitoring System

Now, let's teach Cacti to send SMS notifications using a NetPing SMS device. Edit the code of the file /usr/local/share/cacti/plugins/thold/thold_functions.php. Search for the line «function thold_mail($to, $from, $subject, $message, $filename, $headers = '') {». We need to add working with SMS into this code. Let's replace the entire code of the function «function thold_mail» with the next one:


function thold_mail($to, $from, $subject, $message, $filename, $headers = '') {


                global $config;


                if (strpos($to, '@') === false){

                               $sms = true;

                               $mail = false;


                               $sms = false;

                               $mail = true;


/* Indicate IP address, login and password for accessing this NetPing device*/    

                $ip_server = '';

                $login = 'visor';

                $pass = 'ping';


                $phone = trim(strip_tags($to));

                $msg_sms = trim(strip_tags($subject));


                if ($sms == true){


                               $ch = curl_init("http://". $ip_server ."/sendsms.cgi?utf8");

                               curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

                               curl_setopt($ch, CURLOPT_HEADER, false);

                               curl_setopt($ch, CURLOPT_TIMEOUT, 60);

                               curl_setopt($ch, CURLOPT_AUTOREFERER, false);

                               curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

                               curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

                               curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

                               curl_setopt($ch, CURLOPT_POST, true);

                               curl_setopt($ch, CURLOPT_POSTFIELDS, "[". $phone ."] ". $msg_sms );

                               curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

                               curl_setopt($ch, CURLOPT_USERPWD, $login . ":" . $pass);




                               return '';




                if ($mail == true){


                               thold_debug('Preparing to send email');

                               include_once($config['base_path'] . '/plugins/settings/include/mailer.php');

                               include_once($config['base_path'] . '/plugins/thold/setup.php');

                               $subject = trim($subject);

                               $message = str_replace('<SUBJECT>', $subject, $message);

                               $how = read_config_option('settings_how');

                               if ($how < 0 && $how > 2)

                                               $how = 0;

                               if ($how == 0) {

                                               $Mailer = new Mailer(array(

                                                               'Type' => 'PHP'));

                               } else if ($how == 1) {

                                               $sendmail = read_config_option('settings_sendmail_path');

                                               $Mailer = new Mailer(array(

                                                               'Type' => 'DirectInject',

                                                               'DirectInject_Path' => $sendmail));

                               } else if ($how == 2) {

                                               $smtp_host = read_config_option('settings_smtp_host');

                                               $smtp_port = read_config_option('settings_smtp_port');

                                               $smtp_username = read_config_option('settings_smtp_username');

                                               $smtp_password = read_config_option('settings_smtp_password');

                                               $Mailer = new Mailer(array(

                                                               'Type' => 'SMTP',

                                                               'SMTP_Host' => $smtp_host,

                                                               'SMTP_Port' => $smtp_port,

                                                               'SMTP_Username' => $smtp_username,

                                                               'SMTP_Password' => $smtp_password));


                               if ($from == '') {

                                               $from = read_config_option('thold_from_email');

                                               $fromname = read_config_option('thold_from_name');

                                               if ($from == '') {

                                                               if (isset($_SERVER['HOSTNAME'])) {

                                                                               $from = 'Cacti@' . $_SERVER['HOSTNAME'];

                                                               } else {

                                                                               $from = 'Cacti@localhost';



                                               if ($fromname == '')

                                                               $fromname = 'Cacti'; $from = $Mailer->email_format($fromname, $from);

                                               if ($Mailer->header_set('From', $from) === false) {

                                                               print 'ERROR: ' . $Mailer->error() . "\n";

                                                               return $Mailer->error();


                               } else {

                                               $from = $Mailer->email_format('Cacti', $from);

                                               if ($Mailer->header_set('From', $from) === false) {

                                                               print 'ERROR: ' . $Mailer->error() . "\n";

                                                               return $Mailer->error();



                               if ($to == '')

                                               return 'Mailer Error: No <b>TO</b> address set!!<br>If using the <i>Test Mail</i> link, please set the <b>Alert e-mail</b> setting.';

                               $to = explode(',', $to);

                               foreach($to as $t) {

                                               if (trim($t) != '' && !$Mailer->header_set('To', $t)) {

                                                               print 'ERROR: ' . $Mailer->error() . "\n";

                                                               return $Mailer->error();



                               $wordwrap = read_config_option('settings_wordwrap');

                               if ($wordwrap == '')

                                               $wordwrap = 76;

                               if ($wordwrap > 9999)

                                               $wordwrap = 9999;

                               if ($wordwrap < 0)

                                               $wordwrap = 76;

                               $Mailer->Config['Mail']['WordWrap'] = $wordwrap;

                               if (! $Mailer->header_set('Subject', $subject)) {

                                               print 'ERROR: ' . $Mailer->error() . "\n";

                                               return $Mailer->error();


                               if (is_array($filename) && !empty($filename) && strstr($message, '<GRAPH>') !==0) {

                                               foreach($filename as $val) {

                                                               $graph_data_array = array('output_flag'=> RRDTOOL_OUTPUT_STDOUT);

                                                               if (function_exists('imagecreatefrompng') && function_exists('imagejpeg')) {

                                                                               $data = @png2jpeg(rrdtool_function_graph($val['local_graph_id'], $val['rra_id'], $graph_data_array));

                                                                               $ext = 'jpg';

                                                               } else {

                                                                               $data = @rrdtool_function_graph($val['local_graph_id'], $val['rra_id'], $graph_data_array);

                                                                               $ext = 'png';


                                                               if ($data != '') {

                                                                               $cid = $Mailer->content_id();

                                                                               if ($Mailer->attach($data, $val['filename'].".$ext", "image/$ext", 'inline', $cid) == false) {

                                                                                              print 'ERROR: ' . $Mailer->error() . "\n";

                                                                                              return $Mailer->error();


                                                                               $message = str_replace('<GRAPH>', "<br><br><img src='cid:$cid'>", $message);

                                                               } else {

                                                                               $message = str_replace('<GRAPH>', "<br><img src='" . $val['file'] . "'><br>Could not open!<br>" . $val['file'], $message);




                               $text = array('text' => '', 'html' => '');

                               if ($filename == '') {

                                               $message = str_replace('<br>', "\n", $message);

                                               $message = str_replace('<BR>', "\n", $message);

                                               $message = str_replace('</BR>', "\n", $message);

                                               $text['text'] = strip_tags($message);

                               } else {

                                               $text['html'] = $message . '<br>';

                                               $text['text'] = strip_tags(str_replace('<br>', "\n", $message));


                               $v = thold_version();

                               $Mailer->header_set('X-Mailer', 'Cacti-Thold-v' . $v['version']);

                               $Mailer->header_set('User-Agent', 'Cacti-Thold-v' . $v['version']);

                               if (read_config_option('thold_email_prio') == 'on') {

                                               $Mailer->header_set('X-Priority', '1');


                               thold_debug("Sending email to '" . trim(implode(',',$to),',') . "'");

                               if ($Mailer->send($text) == false) {

                                               print 'ERROR: ' . $Mailer->error() . "\n";

                                               return $Mailer->error();


                               return '';




A ready file can be downloaded from here. Do not forget to specify your data for connecting to the NetPing SMS gateway. A feature automatically distinguishes e-mail from a phone number and sends an SMS or an email notification accordingly.

As a result, a system administrator will receive SMS notifications about getting close to threshold values and/or exceeding threshold values from the Cacti monitoring system.

Template for SMS notifications from Cacti

comments powered by Disqus