【环境准备】
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 ***