3
0

SIM.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #-*- coding: utf-8 -*-
  2. # Diese Klasse ist fr normales Python mit pySerial
  3. # Sie stellt ein Interface fr SIM800 Befehlsstze dar
  4. # 2022-03-02 - devnull - initial
  5. # 2022-03-06 - devnull - Schritt 1 : Anpassung fr ESP ohne Auslesefunktionalitten
  6. # 2022-03-29 - devnull - Schritt 2 : Branch fr den TTGO T-Call
  7. # : Entfernung von ESP Code
  8. # 2022-04-02 - devnull - : Operator und RSSI implementiert
  9. # : CleanOutput mit Byte decoding versehen
  10. # : Debug Funktion eingebaut
  11. # 2022-04-12 - devnull : Wartezeiten beim Absetzen der AT-Kommandos
  12. # 2022-04-13 - devnull : SIN Inserted Abfrage
  13. # 2022-04-17 - devnull : Umstellung auf Loggerklasse für Debug und Verbose
  14. # 2022-04-28 - devnull : AT Kommandos ergänzt, RSSI und OperatorAusgabe gefixt
  15. import sys, os
  16. import utime
  17. from machine import UART
  18. from machine import Timer
  19. class SIM:
  20. logger = None
  21. ser = None
  22. pintx = None
  23. pinrx = None
  24. simpin = None
  25. issimpinentered = False
  26. issiminserted = False
  27. baud = None
  28. sio = None
  29. devOper = None
  30. devRSSI = None
  31. devInfo = None
  32. devTemp = None
  33. devSN = None
  34. devProd = None
  35. devRev = None
  36. SIMtim = Timer(2)
  37. # wenn keine PIN bergeben, dann brechen wir ab
  38. def __init__(self, baud = 115200, pintx = None, pinrx = None, simpin = None, logger = None):
  39. self.logger = logger
  40. # wir brauchen hier noch etwas um zu prfen und abzubrechen, wenn PIN und TTY nicht gesetzt sind
  41. if (pintx is None or pinrx is None):
  42. sys.stderr.write('PINTX/PINRX fehlt')
  43. sys.exit(1)
  44. else:
  45. self.setBaud(baud)
  46. self.setPIN(pintx,pinrx)
  47. # todo: hier muss eine Prfung rein, ob das Modem berhaupt erriechbar ist.
  48. self.sio = UART(1, baudrate=self.getBaud(), rx=self.getPINRX(), tx=self.getPINTX()) # ESP
  49. self.devSetup()
  50. # sammle Modem Informationen
  51. # wir fhren hier erstmal einen first Runtimecheck aus, damit anschlieend der PIN erfolgreich geschickt werden kann
  52. self.devRuntime()
  53. #self.SIMtim.init(period=10000, callback=self.devRuntime)
  54. # PIN bergabe
  55. self.sendPIN(simpin)
  56. #bermittelt ein AT Command, aber bitte nur eine Zeile als Rckgabewert
  57. def sendAT(self,AT):
  58. self.sio.write(AT + '\n')
  59. utime.sleep_ms(1000)
  60. if self.sio.any():
  61. ATout=self.sio.read(self.sio.any()).decode("utf-8")
  62. self.logger.debug("AT Result: \n" + str(ATout))
  63. else:
  64. ATout='ERROR'
  65. return self.cleanOutput(ATout)
  66. # Anpassung fr Micrpython: str.remove() gibt es da nicht, wurde durch replace ersetzt
  67. def cleanOutput(self,output):
  68. # erstmal suchen wir nach einem OK in der Ausgabe
  69. if not 'Error' in output:
  70. # geh fort mit den OKs, Zeilenumbruechen und Zeilenvorschueben
  71. output = output.replace('OK','').replace('\n','').replace('\r','')
  72. # wir brauchen hier noch einen Output
  73. self.logger.debug("cleanOutput Ausgabe: \n" + output)
  74. else:
  75. return 'ERROR'
  76. if len(output) > 0:
  77. return output
  78. else:
  79. return ' '
  80. # Modem TX/RX PIN setter/getter
  81. def setPIN(self,pintx,pinrx):
  82. self.pintx = pintx
  83. self.pinrx = pinrx
  84. def getPINTX(self):
  85. return self.pintx
  86. def getPINRX(self):
  87. return self.pinrx
  88. # SIM PIN entered Setter Getter
  89. def setIssimpinentered(self,entered=False):
  90. self.issimpinentered=entered
  91. def getIssimpinentered(self):
  92. return self.issimpinentered
  93. # Baud setter/getter
  94. def setBaud(self,baud):
  95. self.baud = baud
  96. def getBaud(self):
  97. return self.baud
  98. # SIM Inserted States
  99. def setIssiminserted(self,si):
  100. if si == 1:
  101. self.issiminserted = True
  102. else:
  103. self.issiminserted = False
  104. def getIssiminserted(self):
  105. return self.issiminserted
  106. def setTemperature(self,temp):
  107. self.devTemp = temp
  108. def getTemperature(self):
  109. return self.devTemp
  110. def setOperator(self,operator):
  111. self.devOper = operator
  112. def getOperator(self):
  113. return self.devOper
  114. def setRSSI(self,rssi):
  115. self.devRSSI = rssi
  116. def getRSSI(self):
  117. return self.devRSSI
  118. # Konfigurationsoptionen fr das Modem
  119. def devSetup(self):
  120. self.logger.verbose("Modem Setup")
  121. self.sendAT('AT+COPS=0') # Automatisch den Operator aussuchen
  122. self.sendAT('ATE0') # Echo Off auf der Schnittstelle
  123. self.sendAT('AT+CRSL=100')
  124. self.sendAT('AT+CSCS="GSM"')
  125. self.sendAT('AT+CMGF=1')
  126. # Temperaturchecks
  127. def getDevTemp(self):
  128. self.setTemperature(self.sendAT('AT+CMTE?').partition(",")[2])
  129. self.logger.debug(self.getTemperature())
  130. # Informationen vom Modem lesen
  131. def getDevInfo(self):
  132. self.devInfo = self.sendAT('ATI')
  133. def getDevSIMinserted(self):
  134. si=self.sendAT('AT+CSMINS?').partition(",")[2]
  135. self.logger.debug("SIM inserted: newState=" + str(si) + " savedState=" + str(self.getIssiminserted()))
  136. self.setIssiminserted(int(si))
  137. # PIN State
  138. # AT Commando der PIN Abfrage
  139. def getDevSIMPINstate(self):
  140. if 'READY' in self.sendAT('AT+CPIN?'):
  141. self.setIssimpinentered(True)
  142. return True
  143. else:
  144. self.setIssimpinentered(False)
  145. return False
  146. # Laufzeitinformationen vom Modem abfragen
  147. def devRuntime(self,timer=None):
  148. self.getDevInfo()
  149. self.getDevProd()
  150. self.getDevRev()
  151. self.getDevSN()
  152. self.getDevTemp()
  153. self.logger.verbose("Modem Temperature degC: " + str(self.getTemperature()))
  154. self.getDevSIMinserted()
  155. self.logger.verbose("SIM Inserted: " + str(self.getIssiminserted()))
  156. self.getDevSIMPINstate()
  157. self.logger.verbose("SIM PIN state: " + str(self.getIssimpinentered()))
  158. self.getDevOperator()
  159. self.getDevRSSI()
  160. def getDevProd(self):
  161. self.devProd = self.sendAT('AT+GMM')
  162. def getDevSN(self):
  163. self.devSN = self.sendAT('AT+GSN')
  164. def getDevRev(self):
  165. self.devRev = self.sendAT('AT+GMR')
  166. # todo: Netzqualittsanzeige (RSSI)
  167. def getDevRSSI(self):
  168. #debugausgabe zum herausfinden der Ausgabe
  169. self.setRSSI(>>> sim.sendAT("AT+CSQ").partition(",")[0].partition(": ")[2])
  170. self.logger.debug("RSSI: " + self.getRSSI())
  171. # todo: Netzprovider Anzeige
  172. def getDevOperator(self):
  173. #debugausgabe
  174. self.setOperator(self.sendAT("AT+COPS?").partition(",\"")[2])
  175. self.logger.debug("Operator: " + self.getOperator())
  176. # setzt den PIN auf dem Modem
  177. def sendPIN(self,pin=None):
  178. if not self.getIssimpinentered() and pin is not None and not self.getDevSIMPINstate():
  179. # PIN fehlt, hier noch eintragen
  180. self.sendAT('AT+CPIN=' + str(pin))
  181. self.setIssimpinentered(True)
  182. if not self.getIssimpinentered() and self.simpin is not None and not self.getDevSIMPINstate():
  183. # PIN fehlt, hier noch eintragen
  184. self.sendAT('AT+CPIN=' + str(pin))
  185. self.setIssimpinentered(True)
  186. #
  187. # sim.sendSMS("017643609376", "neue Testnachricht")
  188. def sendSMS(self,number,text):
  189. self.sendAT('AT+CMGS="'+ str(number) + '"\n' + str(text) + '\x1A')