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  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  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