| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- #-*- 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
- # : PIN vor Modem Setup und Netzregistrierung und Runtime Werten
- 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
- # 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 Uebergabe zur Freischaltung der SIM
- self.sendPIN(simpin)
- # Steuerung des Modems nach der PIN
- self.devSetup()
- #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('ATE0') # Echo Off auf der Schnittstelle
- self.sendAT('AT+COPS=0') # Automatisch den Operator aussuchen
- self.sendAT('AT+CLTS=1')
- 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(self.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')
|