【环境准备】
1、操作系统:
Windows 7 x64 SP1
2、Python 版本:
python-3.6.3-amd64
3、第三方组件:
(1)、
pip3 install pyserial
(2)、下载smspdu:
python3 setup.py build install
【列出所有串口】
#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)短信】
#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)短信】
#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 ***
转载于:https://blog.51cto.com/walkerqt/1970472