Python 调用 GSM A6
【环境准备】
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_portsports()) 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' , '大家好' ) |
相关阅读:
1、PDU编码(非常经典)
2、在线PDU格式编码/解码
3、使用python实现短信PDU编码
*** walker ***
附件:
本文转自walker snapshot博客51CTO博客,原文链接
RQSLT
Python 调用 GSM A6
【环境准备】
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_portsports()) 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' , '大家好' ) |
相关阅读:
1、PDU编码(非常经典)
2、在线PDU格式编码/解码
3、使用python实现短信PDU编码
*** walker ***
附件:
本文转自walker snapshot博客51CTO博客,原文链接
RQSLT
发布评论