【環境準備】html
一、操做系統:python
Windows 7 x64 SP1
二、Python 版本:
linux
python-3.6.3-amd64
三、第三方組件:git
(1)、github
pip3 install pyserial
(2)、下載smspdu:bash
python3 setup.py build install
【列出全部串口】app
#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)短信】ide
#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) #加8六、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', '你們好')
相關閱讀:ui
*** walker ***