Статья написана автором Галиев Руслан

Отправка SMS при отключении электричества

На работе частенько стали отключать электричество в ночное время, чтобы приехать с утра пораньше и включить сервера, нужно было придумать оповещение. На работе завалялся GSM модем Teltonika TMK-10x, поэтому решил что самый удобный способ оповещения это SMS сообщение.

1. Первое что нужно написать приложение которое будет отсылать AT команды на COM порт, к которому подключен модем. Приложение должно принимать два параметра первый номер телефона, второй сообщение.

Вот исходный код, или можете скачать скомпилированное приложение  SendSMS.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using System;
using System.IO.Ports;
using System.Text;
using System.Threading;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string phoneNo = args[2];
string message = args[3];
int speed = int.Parse(args[1]);
string port_name = args[0];
SerialPort port = OpenPort(port_name, speed, 8, 1000, 3000);

try
{
ExecCommand(port, "AT", 300, "No phone connected");
ExecCommand(port, "AT+CMGF=1", 300, "Failed to set message format.");
string command = "AT+CMGS=\"" + phoneNo + "\"";
ExecCommand(port, command, 300, "Failed to accept phoneNo");
command = message + char.ConvertFromUtf32(26) + "\r";
ExecCommand(port, command, 3000, "Failed to send message");

}
catch (Exception ex)
{
throw ex;
}

ClosePort(port);
}

//Open Port
public static SerialPort OpenPort(string portName, int baudRate, int dataBits, int readTimeout, int writeTimeout)
{
ReceiveNow = new AutoResetEvent(false);
SerialPort port = new SerialPort();

try
{
port.PortName = portName; //COM1
port.BaudRate = baudRate; //9600
port.DataBits = dataBits; //8
port.StopBits = StopBits.One; //1
port.Parity = Parity.None; //None
port.ReadTimeout = readTimeout; //300
port.WriteTimeout = writeTimeout; //300
port.Encoding = Encoding.GetEncoding("iso-8859-1");
port.DataReceived += PortDataReceived;
port.Open();
port.DtrEnable = true;
port.RtsEnable = true;
}
catch (Exception ex)
{
throw ex;
}
return port;
}

//Close Port
public static void ClosePort(SerialPort port)
{
try
{
port.Close();
port.DataReceived -= PortDataReceived;
}
catch (Exception ex)
{
throw ex;
}
}

public static string ExecCommand(SerialPort port, string command, int responseTimeout, string errorMessage)
{
try
{
port.DiscardOutBuffer();
port.DiscardInBuffer();
ReceiveNow.Reset();
port.Write(command + "\r");

string input = ReadResponse(port, responseTimeout);
if ((input.Length == 0) || ((!input.EndsWith("\r\n> ")) && (!input.EndsWith("\r\nOK\r\n"))))
throw new ApplicationException("No success message was received.");
return input;
}
catch (Exception ex)
{
throw ex;
}
}

public static AutoResetEvent ReceiveNow;

//Receive data from port
public static void PortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
if (e.EventType == SerialData.Chars)
{
ReceiveNow.Set();
}
}
catch (Exception ex)
{
throw ex;
}
}

public static string ReadResponse(SerialPort port, int timeout)
{
int tryNo = 0;

string buffer = string.Empty;
do
{
tryNo++;

if (ReceiveNow.WaitOne(timeout, false))
{
string t = port.ReadExisting();
buffer += t;
}

}
while (!buffer.EndsWith("\r\nOK\r\n") && !buffer.EndsWith("\r\n> ") && !buffer.EndsWith("\r\nERROR\r\n") && tryNo < 10);
return buffer;
}
}
}

2. Вторым этапом надо написать скрипт, который будет выполняться при отключении электричества. Выявлять событие отключения электричества решил при помощи простого пинга на сетевой принтер.

1
2
3
4
5
:begin
ping -n 1 192.168.3.69 || Goto else
exit
:else
C:\SMS\SendSMS.exe COM1 9600 89********* "sveta_net"

Сохраняем код в файле с расширением bat.

3. Создаем назначенное задание, я сделал выполнение под отдельным пользователем, чтобы не было заметно. Периодичность 5 минут.

Комментарии

You must be logged in to post a comment.

Tags Связь с комментариями статьи:
RSS комментарии