|
|
@@ -1,9 +1,14 @@
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
# Diese Klasse ist für normales Python mit pySerial
|
|
|
# Sie stellt ein Interface für SIM800 Befehlssätze dar
|
|
|
|
|
|
# 2022-03-02 - devnull - initial
|
|
|
# 2022-03-06 - devnull - Schritt 1 : Anpassung für ESP ohne Auslesefunktionalitäten
|
|
|
# 2022-03-29 - devnull - Schritt 2 : Branch für den TTGO T-Call
|
|
|
+# : Entfernung von ESP Code
|
|
|
+# 2022-04-02 - devnull - : Operator und RSSI implementiert
|
|
|
+# : CleanOutput mit Byte decoding versehen
|
|
|
+# : Debug Funktion eingebaut
|
|
|
|
|
|
import sys, os
|
|
|
from machine import UART
|
|
|
@@ -11,6 +16,7 @@ from machine import Timer
|
|
|
|
|
|
class SIM:
|
|
|
|
|
|
+ debugvalue = 0
|
|
|
ser = None
|
|
|
pintx = None
|
|
|
pinrx = None
|
|
|
@@ -28,7 +34,9 @@ class SIM:
|
|
|
|
|
|
|
|
|
# wenn keine PIN übergeben, dann brechen wir ab
|
|
|
- def __init__(self, baud = 115200, pintx = None, pinrx = None, simpin = None):
|
|
|
+ def __init__(self, baud = 115200, pintx = None, pinrx = None, simpin = None, debug=0):
|
|
|
+
|
|
|
+ self.setDebug(debug)
|
|
|
|
|
|
# wir brauchen hier noch etwas um zu prüfen und abzubrechen, wenn PIN und TTY nicht gesetzt sind
|
|
|
if (pintx is None or pinrx is None):
|
|
|
@@ -38,64 +46,83 @@ class SIM:
|
|
|
self.setBaud(baud)
|
|
|
self.setPIN(pintx,pinrx)
|
|
|
|
|
|
+ # todo: kann nicht gehen, wo war denn jemals die PIN Zuweisung ? -> genau eins drüber
|
|
|
+ # todo: hier muss eine Prüfung 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 brauchen hier einen Timer, der dann in regelmaessigen Abstaenden die Modeminfos holt
|
|
|
- #self.getDevInfo()
|
|
|
- #self.getDevProd()
|
|
|
- #self.getDevRev()
|
|
|
- #self.getDevSN()
|
|
|
- #self.devTemp()
|
|
|
|
|
|
# wir führen hier erstmal einen first Runtimecheck aus, damit anschließend der PIN erfolgreich geschickt werden kann
|
|
|
self.devRuntime()
|
|
|
-
|
|
|
- # todo: Status Updatetimer prüfen
|
|
|
- self.SIMtim.init(period=1000, callback=self.devRuntime)
|
|
|
+ self.SIMtim.init(period=3000, callback=self.devRuntime)
|
|
|
|
|
|
# PIN Übergabe
|
|
|
- # todo: angepasst-testen, Umstellung auf die korrekte PIN Funktion
|
|
|
- #self.sendESPPIN(pin)
|
|
|
self.sendPIN(simpin)
|
|
|
|
|
|
|
|
|
#übermittelt ein AT Command, aber bitte nur eine Zeile als Rückgabewert
|
|
|
+ # todo: Hier scheint es ein Problem mit dem Puffer zu geben. Es sieht so aus, als ob mehrere Anfragen gleichzeitig verschickt werden und die Antwort nicht ausgewertet weden kann, da bereits ausgelesen. Das muss serialisiert werden
|
|
|
def sendAT(self,AT):
|
|
|
self.sio.write(AT + '\n')
|
|
|
#PC: self.sio.flush() # it is buffering. required to get the data out *now*
|
|
|
#PC: return self.cleanOutput(self.sio.readlines())
|
|
|
|
|
|
- #os.dupterm(None,1)
|
|
|
- return self.cleanOutput(self.sio.read(self.sio.any()))
|
|
|
+ #intermediate debug
|
|
|
+ ATout=self.sio.read(self.sio.any())
|
|
|
+ self.debug("AT Result: \n" + str(ATout))
|
|
|
+
|
|
|
+ #ATline = self.sio.readline()
|
|
|
+ #while ATline:
|
|
|
+ # ATline = ATline + self.sio.readline()
|
|
|
|
|
|
+ #print("Debug: AT Result: " + str(ATline))
|
|
|
+
|
|
|
+ #return self.cleanOutput(ATline)
|
|
|
+ return self.cleanOutput(ATout)
|
|
|
|
|
|
# Antwort DICT bereinigen
|
|
|
+ # Anpassung für Micrpython: str.remove() gibt es da nicht, wurde durch replace ersetzt
|
|
|
def cleanOutput(self,outputin):
|
|
|
|
|
|
- output=str(outputin)
|
|
|
+ output=str(outputin.decode("utf-8"))
|
|
|
+
|
|
|
# erstmal suchen wir nach einem OK in der Ausgabe
|
|
|
if not 'Error' in output:
|
|
|
|
|
|
# wir entfernen alle OKs
|
|
|
- while 'OK\n' in output:
|
|
|
- output.remove('OK\n')
|
|
|
+ #while 'OK\n' in output:
|
|
|
+ # output.replace('OK\n','')
|
|
|
|
|
|
# wir entfernen alle \n
|
|
|
- while '\n' in output:
|
|
|
- output.remove('\n')
|
|
|
+ #while '\n' in output:
|
|
|
+ # output.replace('\n','')
|
|
|
+
|
|
|
+ output = output.replace('OK','').replace('\n','').replace('\r','')
|
|
|
+
|
|
|
+ # wir brauchen hier noch einen Output
|
|
|
+ self.debug("cleanOutput Ausgabe: \n" + output)
|
|
|
|
|
|
else:
|
|
|
return 'ERROR'
|
|
|
|
|
|
if len(output) > 0:
|
|
|
- return output[0].replace('\n','')
|
|
|
+ return output
|
|
|
else:
|
|
|
return ' '
|
|
|
|
|
|
|
|
|
+ # Debugging Funktionen
|
|
|
+ def setDebug(self,debugIn=0):
|
|
|
+ self.debugvalue = debugIn
|
|
|
+
|
|
|
+ def getDebug(self):
|
|
|
+ return self.debugvalue
|
|
|
+
|
|
|
+ def debug(self,msg):
|
|
|
+ if self.getDebug() == 1:
|
|
|
+ sys.stderr.write("DEBUG: " + msg + "\n")
|
|
|
+
|
|
|
# Modem TX/RX PIN setter/getter
|
|
|
def setPIN(self,pintx,pinrx):
|
|
|
self.pintx = pintx
|
|
|
@@ -123,6 +150,7 @@ class SIM:
|
|
|
|
|
|
# Konfigurationsoptionen für das Modem
|
|
|
def devSetup(self):
|
|
|
+ print("Modem Setup")
|
|
|
self.sendAT('ATE0')
|
|
|
self.sendAT('AT+CRSL=100')
|
|
|
self.sendAT('AT+CSCS="GSM"')
|
|
|
@@ -131,6 +159,7 @@ class SIM:
|
|
|
# Temperaturchecks
|
|
|
# todo: liefert leider keine Temperaturwerte zurück
|
|
|
def getDevTemp(self):
|
|
|
+ self.debug(self.sendAT('AT+CMTE?'))
|
|
|
self.devTemp = self.sendAT('AT+CMTE?').partition(",")[2]
|
|
|
|
|
|
|
|
|
@@ -139,11 +168,14 @@ class SIM:
|
|
|
self.devInfo = self.sendAT('ATI')
|
|
|
|
|
|
# PIN State
|
|
|
+ # AT Commando der PIN Abfrage
|
|
|
def getDevSIMPINstate(self):
|
|
|
if 'ready' in self.sendAT('AT+CPIN?'):
|
|
|
- self.simpinentered=True
|
|
|
+ self.setSIMPINentered(True)
|
|
|
+ return True
|
|
|
else:
|
|
|
- self.simpinentered=False
|
|
|
+ self.setSIMPINentered(False)
|
|
|
+ return False
|
|
|
|
|
|
# Laufzeitinformationen vom Modem abfragen
|
|
|
def devRuntime(self,timer=None):
|
|
|
@@ -159,8 +191,8 @@ class SIM:
|
|
|
self.getDevSIMPINstate()
|
|
|
print("SIM PIN state: " + str(self.getSIMPINentered()))
|
|
|
|
|
|
- #todo: regelmäßige Abfrage auch von RSSI
|
|
|
- # todo: regelmäßige Abfrage auch ISP
|
|
|
+ self.getDevOperator()
|
|
|
+ self.getDevRSSI()
|
|
|
|
|
|
def getDevProd(self):
|
|
|
self.devProd = self.sendAT('AT+GMM')
|
|
|
@@ -172,19 +204,26 @@ class SIM:
|
|
|
self.devRev = self.sendAT('AT+GMR')
|
|
|
|
|
|
# todo: Netzqualitätsanzeige (RSSI)
|
|
|
+ def getDevRSSI(self):
|
|
|
+ #debugausgabe zum herausfinden der Ausgabe
|
|
|
+ self.debug("RSSI: " + self.sendAT("AT+CSQ"))
|
|
|
+
|
|
|
# todo: Netzprovider Anzeige
|
|
|
+ def getDevOperator(self):
|
|
|
+ #debugausgabe
|
|
|
+ self.debug("Operator: " + self.sendAT("AT+COPS"))
|
|
|
|
|
|
# setzt den PIN auf dem Modem
|
|
|
- def sendPIN(self,pin):
|
|
|
- if not self.getSIMPINentered() and pin is not None:
|
|
|
+ def sendPIN(self,pin=None):
|
|
|
+ if not self.getSIMPINentered() and pin is not None and not self.getDevSIMPINstate():
|
|
|
# PIN fehlt, hier noch eintragen
|
|
|
self.sendAT('AT+CPIN=' + str(pin))
|
|
|
self.setSIMPINentered(True)
|
|
|
|
|
|
- # temporaer: ESP setzt den PIN auf dem Modem
|
|
|
- def sendESPPIN(self,pin):
|
|
|
- self.sendAT('AT+CPIN=' + str(pin))
|
|
|
- self.setSIMPINentered(True)
|
|
|
+ if not self.getSIMPINentered() and self.simpin is not None and not self.getDevSIMPINstate():
|
|
|
+ # PIN fehlt, hier noch eintragen
|
|
|
+ self.sendAT('AT+CPIN=' + str(pin))
|
|
|
+ self.setSIMPINentered(True)
|
|
|
|
|
|
|
|
|
def sendSMS(self,number,text):
|