#-*- coding: utf-8 -*- # Diese Klasse ist fr normales Python mit pySerial # Sie stellt ein Interface fr SIM800 Befehlsstze dar # 2022-03-02 - devnull - initial # 2022-03-06 - devnull - Schritt 1 : Anpassung fr ESP ohne Auslesefunktionalitten # 2022-03-29 - devnull - Schritt 2 : Branch fr den TTGO T-Call # : Entfernung von ESP Code # 2022-04-02 - devnull - : Operator und RSSI implementiert # : CleanOutput mit Byte decoding versehen # : Debug Funktion eingebaut # 2022-04-12 - devnull : Wartezeiten beim Absetzen der AT-Kommandos # 2022-04-13 - devnull : SIN Inserted Abfrage # 2022-04-17 - devnull : Umstellung auf Loggerklasse für Debug und Verbose # 2022-04-28 - devnull : AT Kommandos ergänzt, RSSI und OperatorAusgabe gefixt import sys, os import utime from machine import UART from machine import Timer class SIM: logger = None ser = None pintx = None pinrx = None simpin = None issimpinentered = False issiminserted = False baud = None sio = None devOper = None devRSSI = None devInfo = None devTemp = None devSN = None devProd = None devRev = None SIMtim = Timer(2) # wenn keine PIN bergeben, dann brechen wir ab def __init__(self, baud = 115200, pintx = None, pinrx = None, simpin = None, logger = None): self.logger = logger # wir brauchen hier noch etwas um zu prfen und abzubrechen, wenn PIN und TTY nicht gesetzt sind if (pintx is None or pinrx is None): sys.stderr.write('PINTX/PINRX fehlt') sys.exit(1) else: self.setBaud(baud) self.setPIN(pintx,pinrx) # todo: hier muss eine Prfung rein, ob das Modem berhaupt erriechbar ist. self.sio = UART(1, baudrate=self.getBaud(), rx=self.getPINRX(), tx=self.getPINTX()) # ESP self.devSetup() # sammle Modem Informationen # wir fhren hier erstmal einen first Runtimecheck aus, damit anschlieend der PIN erfolgreich geschickt werden kann self.devRuntime() #self.SIMtim.init(period=10000, callback=self.devRuntime) # PIN bergabe self.sendPIN(simpin) #bermittelt ein AT Command, aber bitte nur eine Zeile als Rckgabewert def sendAT(self,AT): self.sio.write(AT + '\n') utime.sleep_ms(1000) if self.sio.any(): ATout=self.sio.read(self.sio.any()).decode("utf-8") self.logger.debug("AT Result: \n" + str(ATout)) else: ATout='ERROR' return self.cleanOutput(ATout) # Anpassung fr Micrpython: str.remove() gibt es da nicht, wurde durch replace ersetzt def cleanOutput(self,output): # erstmal suchen wir nach einem OK in der Ausgabe if not 'Error' in output: # geh fort mit den OKs, Zeilenumbruechen und Zeilenvorschueben output = output.replace('OK','').replace('\n','').replace('\r','') # wir brauchen hier noch einen Output self.logger.debug("cleanOutput Ausgabe: \n" + output) else: return 'ERROR' if len(output) > 0: return output else: return ' ' # Modem TX/RX PIN setter/getter def setPIN(self,pintx,pinrx): self.pintx = pintx self.pinrx = pinrx def getPINTX(self): return self.pintx def getPINRX(self): return self.pinrx # SIM PIN entered Setter Getter def setIssimpinentered(self,entered=False): self.issimpinentered=entered def getIssimpinentered(self): return self.issimpinentered # Baud setter/getter def setBaud(self,baud): self.baud = baud def getBaud(self): return self.baud # SIM Inserted States def setIssiminserted(self,si): if si == 1: self.issiminserted = True else: self.issiminserted = False def getIssiminserted(self): return self.issiminserted def setTemperature(self,temp): self.devTemp = temp def getTemperature(self): return self.devTemp def setOperator(self,operator): self.devOper = operator def getOperator(self): return self.devOper def setRSSI(self,rssi): self.devRSSI = rssi def getRSSI(self): return self.devRSSI # Konfigurationsoptionen fr das Modem def devSetup(self): self.logger.verbose("Modem Setup") self.sendAT('AT+COPS=0') # Automatisch den Operator aussuchen self.sendAT('ATE0') # Echo Off auf der Schnittstelle self.sendAT('AT+CRSL=100') self.sendAT('AT+CSCS="GSM"') self.sendAT('AT+CMGF=1') # Temperaturchecks def getDevTemp(self): self.setTemperature(self.sendAT('AT+CMTE?').partition(",")[2]) self.logger.debug(self.getTemperature()) # Informationen vom Modem lesen def getDevInfo(self): self.devInfo = self.sendAT('ATI') def getDevSIMinserted(self): si=self.sendAT('AT+CSMINS?').partition(",")[2] self.logger.debug("SIM inserted: newState=" + str(si) + " savedState=" + str(self.getIssiminserted())) self.setIssiminserted(int(si)) # PIN State # AT Commando der PIN Abfrage def getDevSIMPINstate(self): if 'READY' in self.sendAT('AT+CPIN?'): self.setIssimpinentered(True) return True else: self.setIssimpinentered(False) return False # Laufzeitinformationen vom Modem abfragen def devRuntime(self,timer=None): self.getDevInfo() self.getDevProd() self.getDevRev() self.getDevSN() self.getDevTemp() self.logger.verbose("Modem Temperature degC: " + str(self.getTemperature())) self.getDevSIMinserted() self.logger.verbose("SIM Inserted: " + str(self.getIssiminserted())) self.getDevSIMPINstate() self.logger.verbose("SIM PIN state: " + str(self.getIssimpinentered())) self.getDevOperator() self.getDevRSSI() def getDevProd(self): self.devProd = self.sendAT('AT+GMM') def getDevSN(self): self.devSN = self.sendAT('AT+GSN') def getDevRev(self): self.devRev = self.sendAT('AT+GMR') # todo: Netzqualittsanzeige (RSSI) def getDevRSSI(self): #debugausgabe zum herausfinden der Ausgabe self.setRSSI(>>> sim.sendAT("AT+CSQ").partition(",")[0].partition(": ")[2]) self.logger.debug("RSSI: " + self.getRSSI()) # todo: Netzprovider Anzeige def getDevOperator(self): #debugausgabe self.setOperator(self.sendAT("AT+COPS?").partition(",\"")[2]) self.logger.debug("Operator: " + self.getOperator()) # setzt den PIN auf dem Modem def sendPIN(self,pin=None): if not self.getIssimpinentered() and pin is not None and not self.getDevSIMPINstate(): # PIN fehlt, hier noch eintragen self.sendAT('AT+CPIN=' + str(pin)) self.setIssimpinentered(True) if not self.getIssimpinentered() and self.simpin is not None and not self.getDevSIMPINstate(): # PIN fehlt, hier noch eintragen self.sendAT('AT+CPIN=' + str(pin)) self.setIssimpinentered(True) # # sim.sendSMS("017643609376", "neue Testnachricht") def sendSMS(self,number,text): self.sendAT('AT+CMGS="'+ str(number) + '"\n' + str(text) + '\x1A')