SIM.py 7.6 KB

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