【环境准备】
1、操作系统:
1
|
Windows 7 x64 SP1 |
2、Python 版本:
1
|
python-3.6.3-amd64 |
3、第三方组件:
(1)、
1
|
pip3 install pyserial
|
(2)、下载smspdu:
1
|
python3 setup.py build install
|
【列出所有串口】
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#encoding: utf-8 #author: walker #date: 2017-10-06 #summary: Python 用 pyserial 列出所有串口 import serial.tools.list_ports
# 打印所有串口名 def ListPorts():
serailPortList = list (serial.tools.list_ports.comports())
print ( 'serail port number: %d' % len (serailPortList))
if len (serailPortList) < 1 :
print ( "Not found serail port!" )
return for serailPort in serailPortList:
se = serial.Serial( list (serailPort)[ 0 ], 9600 , timeout = 9 )
print ( 'serail port name:%s' % se.portstr)
se.close()
if __name__ = = '__main__' :
ListPorts()
|
【发送纯英文(ASCII)短信】
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
|
#encoding: utf-8 #author: walker #date: 2017-10-06 #summary: Python 调用 GSM A6,发送英文短信 import time
import serial.tools.list_ports
class MessagerEn( object ):
# 构造函数,打开端口
def __init__( self ):
self .sePort = serial.Serial(port = 'COM3' , baudrate = 19200 , bytesize = 8 , stopbits = 1 , timeout = 3 )
time.sleep( 3 )
# 析构函数,关闭端口
def __del__( self ):
self .sePort.close()
# 重新打开端口
def reopen( self ):
print ( 'reopen ...' )
self .sePort.close()
self .sePort = serial.Serial(port = 'COM3' , baudrate = 19200 , bytesize = 8 , stopbits = 1 , timeout = 3 )
time.sleep( 3 )
# 执行指令
# 返回从串口读取的返回值
def execCmd( self , cmd, end = '\r' ):
cmd = cmd + end
bCmd = cmd.encode( 'ascii' )
print ( 'write:%s' % bCmd)
self .sePort.write(bCmd)
response = self .sePort.readall()
print ( 'read :%s' % response)
print ()
return response
# 发送英文短信
# 正确返回 True;错误返回 False
def __sendMessageEn( self , phoneNumber, message):
if not self .execCmd( 'AT+CMGF=1' ).endswith(b '\r\nOK\r\n' ): #设置TEXT MODE
return False
if not self .execCmd( 'AT+CSCS="GSM"' ).endswith(b '\r\nOK\r\n' ):
return False
if not self .execCmd( 'AT+CMGS="%s"' % phoneNumber).endswith(b '\r\n> ' ):
return False
if not self .execCmd(message + '\x1A' , end = ' ').endswith(b' \r\nOK\r\n'): # 十六进制的1A为结束符
return False
return True
# 调用私有方法 __sendMessageEn
# 在失败时重新打开串口
def sendMessage( self , phoneNumber, message):
for _ in range ( 0 , 3 ):
if self .__sendMessageEn(phoneNumber, message):
break
self .reopen()
if __name__ = = '__main__' :
messagerEn = MessagerEn()
messagerEn.sendMessage( '18688754379' , 'xxx' )
messagerEn.sendMessage( '18688754379' , 'zzz' )
|
【发送中文(Unicode)短信】
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
|
#encoding: utf-8 #author: walker #date: 2017-10-06 #summary: Python 调用 GSM A6,发送中文(Unicode)短信 import time
import serial.tools.list_ports
class Messager( object ):
# 构造函数,打开端口
def __init__( self ):
self .sePort = serial.Serial(port = 'COM3' , baudrate = 19200 , bytesize = 8 , stopbits = 1 , timeout = 3 )
time.sleep( 3 )
# 析构函数,关闭端口
def __del__( self ):
self .sePort.close()
# 重新打开端口
def reopen( self ):
print ( 'reopen ...' )
self .sePort.close()
self .sePort = serial.Serial(port = 'COM3' , baudrate = 19200 , bytesize = 8 , stopbits = 1 , timeout = 3 )
time.sleep( 3 )
# 执行指令
# 返回从串口读取的返回值
def execCmd( self , cmd, end = '\r' ):
cmd = cmd + end
bCmd = cmd.encode( 'ascii' )
print ( 'write:%s' % bCmd)
self .sePort.write(bCmd)
response = self .sePort.readall()
print ( 'read :%s' % response)
print ()
return response
# 发送英文短信
# 正确返回 True;错误返回 False
def __sendMessage( self , phoneNumber, message):
if not self .execCmd( 'AT+CMGF=0' ).endswith(b '\r\nOK\r\n' ): #设置PDU格式
return False
if not self .execCmd( 'AT+CSCS="GSM"' ).endswith(b '\r\nOK\r\n' ):
return False
pdu_content = self .encodeMessage(phoneNumber, message)
cmd = 'AT+CMGS=%d' % (( len (pdu_content) - 2 ) / 2 )
if not self .execCmd(cmd).endswith(b '\r\n> ' ):
return False
# 十六进制的1A为结束符
if not self .execCmd(pdu_content + '\x1A' , end = ' ').endswith(b' \r\nOK\r\n'):
return False
return True
# 调用私有方法 __sendMessage
# 在失败时重新打开串口
def sendMessage( self , phoneNumber, message):
for _ in range ( 0 , 3 ):
if self .__sendMessage(phoneNumber, message):
break
self .reopen()
# 将中文信息编码为PDU格式(ucs2)
def encodeMessage( self , phoneNumber, message):
tpdu = []
if phoneNumber and message:
tpdu.append( '001100' )
formatAddress = self .encodePhoneNumber(phoneNumber)
tpdu.append(formatAddress)
tpdu.append( '0008AA' )
tpdu.append( '%02X' % ( len (message) * 2 ))
content = ' '.join([' % 02X ' % c for c in message.encode(' utf_16_be')])
tpdu.append(content)
print (''.join(tpdu))
return ''.join(tpdu)
# 将手机号编码为pdu所需格式
def encodePhoneNumber( self , phoneNumber):
#号码为11位数字
if not re.match(r '\d{11}' , phoneNumber):
print ( 'Error phoneNumber: %s' % phoneNumber)
addr = '0D' #号码长度13
addr + = '91' #Type-of-Address,目标地址格式(TON/NPI)
#加86、F补成偶数个(14位),分7组翻转
phoneNumber = '86' + phoneNumber + 'F'
for i in range ( 0 , 7 ):
addr + = phoneNumber[ 2 * i + 1 ] + phoneNumber[ 2 * i]
return addr
if __name__ = = '__main__' :
messager = Messager()
messager.sendMessage( '18688754379' , '你好' )
messager.sendMessage( '18688754379' , '大家好' )
|
相关阅读:
*** walker ***
附件:http://down.51cto.com/data/2367032
本文转自walker snapshot博客51CTO博客,原文链接http://blog.51cto.com/walkerqt/1970472如需转载请自行联系原作者
RQSLT