Python + Gsm + GPS Uygulaması

Başlatan fide, 29 Mayıs 2020, 00:49:30

fide

Omega2+ modül üzerinde python programlama dili ile konum kayıt uygulaması geliştirmeye çalışıyorum. GPRS kısmı henüz aktif değil ama gsm modül ile iletişim, veri alıp gönderme, sms ile işlem yapma, sms cevaplama, GPS konum alma işleme, konum kaydı ve sorgulama şeklinde hazırladım. GSM Modül Quectel MC60 GSM / GPS / GNSS kombo modül.
Projeyi opensource olarak buradan paylaşmak niyetindeyim.

Projede kullanılan donanıma blog sayfamdan ulaşabilirsiniz.
Omega2+ GSM GPS Uygulama Geliştirme Kartı


Önce Port tanımlamaları:
#serial port configure

# terminal seri portu 
terminal=serial.Serial()
terminal.baudrate=115200
terminal.port='/dev/ttyS0'
terminal.open()

#gsm modül iletişim seri portu
ser=serial.Serial()
ser.baudrate=115200
ser.port='/dev/ttyS1'
ser.open()
sleep(0.1)


GPIO için periphery kütüphanesini kullandım. pyoniongpio isimli bir kütüphane var ama stabil değil.
Raspberry pi için deneyecekler BCM library ile değiştirebilirler.


#pin defines 
pin0=2 # GPIO Led
pin1=3 # GPIO Led
pin2=11 # GPIO Led
pin3=18 # GPIO Led
pin4=19 # GPIO Led pcb çizim hatası nedeniyle off


led0= GPIO("/dev/gpiochip0", pin0, "out")
led1= GPIO("/dev/gpiochip0", pin1, "out")
led2= GPIO("/dev/gpiochip0", pin2, "out")
led3= GPIO("/dev/gpiochip0", pin3, "out")
led4= GPIO("/dev/gpiochip0", pin4, "out")


pinPon=16 # GSM Board Power Enable
pinMon=17 # Gsm Module On/Off
pinVE=15 # Gsm Module V ext

gsmBoardPowerOn=GPIO("/dev/gpiochip0", pinPon, "out")
gsmModuleOn=GPIO("/dev/gpiochip0", pinMon, "out")
gsmModuleFeedback=GPIO("/dev/gpiochip0", pinVE, "in")


Ve fonksiyonlar:

Veritabanı Kontrol ediliyor var ise bildirim yapılıyor, yok ise yeniden oluşturuluyor.
import os
import sqlite3 as db

def dbCheck():
 dosyaMevcut=os.path.exists(dbFile)
 if not dosyaMevcut:
 dbCreate()
 else:
 print("db dosyası var.\r\n")

def dbCreate():
 vt=db.connect(dbFile)
 im=vt.cursor()
 im.execute("""
 CREATE TABLE 'smsLog' (
 'id' INTEGER PRIMARY KEY AUTOINCREMENT,
 'telNum' TEXT,
 'date' TEXT,
 'time' TEXT,
 'text' TEXT
 );""")
 vt.commit()
 
 im.execute("""
 CREATE TABLE 'naviLog' (
 'id' INTEGER PRIMARY KEY AUTOINCREMENT,
 'lat' TEXT,
 'long' TEXT,
 'date' TEXT,
 'time' TEXT,
 'speed' REAL,
 'direction' REAL
 
 );""")
 vt.commit()
 vt.close()
 print("info>> Veritabanı olusturuldu\r\n")
 

Veritabanında iki ayrı tablo var. Biri gelen smsleri loglanması için. Gelen smsleri veritabanına kaydedip sim karttan siliyor. Diğeri konum bilgilerini kayıt ediyor.

def smsLog(telNum,date,time,text):
 with db.connect(dbFile) as vt:
 im=vt.cursor()
 sorguText="""INSERT INTO 
 smsLog(telNum,date,time,text) 
 values('{}','{}','{}','{}') """.format(telNum,date,time,text)
 im.execute(sorguText)
 vt.commit()
 print("info>> smsLog eklendi")
 
def naviLog(lat,long,date,time,speed,direction):
 with db.connect(dbFile) as vt:
 im=vt.cursor()
 sorguText="""INSERT INTO 
 naviLog(lat,long,date,time,speed,direction) 
 values('{}','{}','{}','{}','{}','{}') """.format(lat,long,date,time,speed,direction)
 im.execute(sorguText)
 vt.commit()
 print("info>> naviLog eklendi\r\n")


Gsm modüllerle uğraşmanın en büyük sıkıntısı sabit bir komut ve dönüt yapısının olmaması ve arama, internet erişimi gibi bazı komutların cevap süresinin 300 saniyedyi bulabilmesi.
Bazı komut örnekleri:

komut: AT\r\n
olası cevaplar: OK\r\n

komut: ATDxxxxxxxx\r\n
olası cevaplar: CONNECT\r\n, NO CARRIER\r\n vb

Bunun için standart bir kütüphane yapmak ciddi şekilde uğraştırdı beni.


Komut Kütüphanesi:
#namedTuple defines
atCmd = namedtuple('atCmd', ['cmdText','timeout','responses'])
at = atCmd("AT\r", 300, ["OK", "ERROR"])  # AT
atE0 = atCmd("ATE0\r", 300, ["OK", "ERROR"])  # Command Echo
atQGSN = atCmd("AT+QGSN\r", 3000, ["OK", "ERROR"])  # Gsm Serial Number
atCCID = atCmd("AT+CCID\r", 300, ["OK", "ERROR"])  # Sim Abone No
atQNITZ = atCmd("AT+QNITZ=1\r", 300, ["OK", "ERROR"])  # Network Time Sync Enable
atCTZU = atCmd("AT+CTZU=3\r", 300, ["OK", "ERROR"])  # Localized Time Sync
atCTZR = atCmd("AT+CTZR=1\r", 300, ["OK", "ERROR"])  # Time Sync Bildirimi
atCCLK = atCmd("AT+CCLK?\r", 1000, ["OK", "ERROR"])  # Saat?
atQGNSSC = atCmd("AT+QGNSSC=1\r", 300, ["OK", "ERROR"])  # GNSS Power On
atQGNSS = atCmd("AT+QGNSS=0\r", 300, ["OK", "ERROR","+CME ERROR:"])  # GNSS NMEA Tipi
atCMGF = atCmd("AT+CMGF=1\r", 300, ["OK", "ERROR","+CME ERROR:"])  # SMS Format
atCNMI = atCmd("AT+CNMI=2,1\r", 300, ["OK", "ERROR","+CME ERROR:"])  # SMS Notification Type
atQNSTATUS = atCmd("AT+QNSTATUS\r", 1000, ["OK", "ERROR"])  # Network Status
atCSQ = atCmd("AT+CSQ\r", 300, ["OK", "ERROR", "+CME ERROR:"])  # Signal Quality
atCREG = atCmd("AT+CREG?\r", 300, ["OK", "ERROR","+CME ERROR:","+CREG:"])  # Signal Quality
atCMGL = atCmd("""AT+CMGL="REC UNREAD"\r""",3000, ["OK", "ERROR"])
atCMGD = atCmd("AT+CMGD=1,4\r",3000, ["OK", "ERROR"])
atQGNSSRD = atCmd("AT+QGNSSRD?\r",3000,["OK", "ERROR"])
atCSMP = atCmd("AT+CSMP=17,167,0,0\r",1000,["OK", "ERROR"])
atCSCS = atCmd("""AT+CSCS="GSM"\r""",1000,["OK", "ERROR"])
atCMGS = atCmd("""AT+CMGS="{}"\r""",5000,["OK", "ERROR"])
atQIFGCNT = atCmd("AT+QIFGCNT=0\r",1000,["OK", "ERROR"])
atQICSGP = atCmd('AT+QICSGP=1,"INTERNET","",""\r',1000,["OK", "ERROR"])
atQIREGAPP=atCmd("AT+QIREGAPP\r",5000,["OK", "ERROR"])
atCGATT = atCmd("AT+CGATT?\r",5000,["OK", "ERROR"])
atQIACT = atCmd("AT+QIACT\r",5000,["OK", "ERROR"])
atQLOCCFG = atCmd("AT+QLOCCFG?\r",5000,["OK", "ERROR"])
atQCELLLOC = atCmd("AT+QCELLLOC\r",5000,["OK", "ERROR"])

GSM modül uyandırma rutini:
Quectel modül açılış esnasında 3 adet ready mesajı gönderiyor. RDY modülün hazır olduğu, SMS READY sms almak için hazır olunduğu, CALL READY de arama için hazır olduğunu bildiriyor. GSM modül bu üç uyarıyı verene kadar döngü içinde bekliyor.
def gsmBootProc():
 gsmBoardPowerOn.write(True)
 sleep(0.5)
 
 gsmPwrState= int(gsmModuleFeedback.read())
 #TODO: sonra kaldır.
 gsmPwrState= int(gsmModuleFeedback.read())
 print("info>> gsmPwrState:{}\r\n".format(gsmPwrState))
 #TODO: sonra kaldır.
 if gsmPwrState==1:
 print("info>> Gsm module is already on\r\n")
 blink(0)
 
 else:
 print("info>> Gsm Module boots up\r\n")
 gsmModuleOn.write(True)
 sleep(1)
 gsmModuleOn.write(False)
 rdyCount=0
 while (rdyCount<3):
 blink(0)
 print("info>> Wait For RDY's\r\n")
 if ser.in_waiting>0:
 sleep(0.01)
 data=ser.read(ser.in_waiting).decode("utf-8")
 if "RDY" in data:
 rdyCount+=1
 print("info>> RDY\r\n")
 if "SMS Ready" in data:
 rdyCount+=1
 print("info>> SMS Ready\r\n")
 if "Call Ready" in data:
 rdyCount+=1
 print("info>> Call Ready\r\n")
 
 print("info>> Gsm Module is ready\r\n")
 blink(1)
Komut gönderme yapısı kontrolleri de içerdiği için en uzun fonksiyon oldu. Yapı aslında çok basit. Bir komutu göndermek için komutu ekliyorum. atGonder(ate0) gibi. Bu komutun text kısmını yukardakı listeden bulup seri porta gönderiyor. Sonra maksimum timeout kadar bekleyip cevap var mı kontrol ediyor. Gelen cevabın başlangıç textine göre de işlem yapıyor. Sms işleme, gps koordinatlarını raw data içinden parse etme işlemleri de burada yapılıyor.

def atGonder(cmd,param=""):
 global smsAlert
 global mnChange
 global clkChange
 global mntChange
 global yr
 global mnt
 global day
 global mn
 global clk
 global sec
 
 
 modname = globals()['__name__']
 modobj = sys.modules[modname]
#seri portta veri varsa komut göndermeden veriyi al
 data=""
 if cmd=="":
 while(ser.in_waiting>0):
 data+=ser.read(ser.in_waiting).decode("utf-8")
 sleep(0.01)
 print("info>> gsm alert, data:{}\r\n".format(data))
 else:
 komut=getattr(modobj,cmd).cmdText #komut textini al
 if param!="":
 komut=komut.format(param)
 ser.write(komut.encode("utf-8"))
 sleep(0.1)
 sayac=0
 timeout=getattr(modobj,cmd).timeout #süreyi al
 dataVar=False
 timeoutVar=False
 while(dataVar==False) and (timeoutVar==False):
 sayac+=1
 sleep(0.01)
 
 if sayac>timeout: #timeout kontrol
 timeoutVar=True
 
 if ser.in_waiting>0:
 while(ser.in_waiting>0):
 data+=ser.read(ser.in_waiting).decode("utf-8")
 sleep(0.01)
 if len(data)>0:
 dataVar=True
 
 if timeoutVar==True:
 print("info>> header: {}, timeout \r\n".format(cmd))
 if dataVar==True:
 print("info>> data:{}, header: {}\r\n".format(data,cmd))
 #+CCID: "89902860377864179173"
 if "+CCID:" in data:
 ccid=data.split('"')[1]
 print("info>> ccid:{}\r\n".format(ccid))
 #+QGSN: "861359030033482"
 if "+QGSN:" in data:
 gsn=data.split('"')[1]
 print("info>> gsn:{}\r\n".format(gsn))
 #+QNITZ: "20/02/21,22:04:26+12,0"
 if "+QNITZ:" in data:
 localClkSet=True
 print("info>> localClkSet\r\n")
 #+CCLK: "20/02/22,01:11:44+12"
 if "+CCLK:" in data:
 rawTime=data.split('"')[1]
 clkEx=clk
 clk=rawTime[9:11]
 mnEx=mn
 mn=rawTime[12:14]
 sec=rawTime[15:17]
 yr=rawTime[0:2]
 mnt=rawTime[3:5]
 dayEx=day
 day=rawTime[6:8]
 
 if mnEx!=mn:
 print("info>> Dakika değişti\r\n")
 mnChange=True
 if clkEx!=clk:
 print("info>> Saat değişti\r\n")
 clkChange=True
 if dayEx!=day:
 print("info>> Gün değişti\r\n")
 dayChange=True
 
 print("info>> Clock: {}:{}:{}, Date: {}.{}.{}\r\n".format(clk,mn,sec,day,mnt,yr))
 #RDY
 if "RDY" in data:
 print("info>> gsm module ready\r\n")
 gsmReady=True
 
 #+CFUN: 1
 #TODO: +CFUN eklenecek sonra
 
 #+CPIN: READY
 if "+CPIN: READY" in data:
 print("info>> pinReady\r\n")
 pinReady=True

 #Call Ready
 if "Call Ready" in data:
 callReady=True
 print("info>> callReady\r\n")
 
 #SMS Ready
 if "SMS Ready" in data:
 smsReady=True
 print("info>> sms ready\r\n")

 #+CIEV: 10,"28603","BIMcell","BIMcell", 0, 0
 if "+CIEV:" in data:
 operatorName=data.split('"')[3]
 print("info>> Operator Name: {}\r\n".format(operatorName))
 #+CMTI:
 if "+CMTI:" in data:
 rawData=data.split(",")[1]
 msgOrder=int(rawData.strip("\r\n"))
 
 print("info>> +CMTI: {} sms alert\r\n".format(msgOrder))
 smsAlert=True
 #RING
 if "RING" in data:
 print("info>> call alert")
 callAlert=True
 
 #+CREG: 0,1
 if "+CREG:" in data:
 print("info>> Network Status:{}".format(data))
 creg=False
 rawData=int(data.split(",")[1][0])
 if rawData==1:
 creg=True
 else:
 creg=False
 print("info>> CREG: {}\r\n".format(creg)) 
 #+CSQ: 21,0
 if "+CSQ:" in data:
 rawData=data.split(",")[0]
 rawData=rawData.split(":")[1]
 rssi=int(rawData.strip())
 level=""
 if 2<rssi<30:
 level="Normal"
 elif rssi==31:
 level="High"
 elif rssi>31:
 level="weak"
 
 print("info>> +CSQ: {}, Signal is: {}\r\n".format(rssi,level))
 
 #+CMGL: 11,"REC UNREAD","+90505xxxxxx","","2020/02/22 03:23:58+12"\r\nYcycycyc\r\nOK\r\n
 if "+CMGL:" in data:
 #TODO: sms kontrol
 print("info>> sms kontrol\r\n")
 rawSmsData=data.split("\r\n")
 smsOrigin=rawSmsData[1].split(",")
 smsBody=rawSmsData[2].strip()
 smsTelNum=smsOrigin[2].strip('"')
 # 4: smsOrigin:"2020/02/25 19:14:14+12" sms date time
 smsRawDateTime=smsOrigin[4]
 smsDate=smsRawDateTime.split()[0]
 smsDate=smsDate.strip('"')
 smsTime=smsRawDateTime.split()[1][:8]
 print("info>> smsDate:{}, smsTime:{}\r\n".format(smsDate,smsTime))
 for i in smsOrigin:
 print("info>> {}: smsOrigin:{}\r\n".format(smsOrigin.index(i),i))
 print("info>> TelNo:{}, smsBody: {}\r\n".format(smsTelNum,smsBody))
 #TODO: Mesajla iş bittikten sonra sms'i sil
 atGonder("atCMGD")
 print("info>> Toplu SMS silme\r\n")
 #gelen SMS'i logla
 smsLog(smsTelNum,smsDate,smsTime,smsBody)
 if "Blink" in smsBody:
 for i in range(20):
 blink(0)
 if "Loc?" in smsBody:
 sendSMS(smsTelNum,"Will be prepared soon")
 
 
 #+QGNSSRD: GPS / GNSS Data
 """
 info>> data:+QGNSSRD: $GNRMC,162647.000,A,3708.8978,N,02930.5761,E,2.26,79.50,240220,,,A*44
 $GNVTG,79.50,T,,M,2.26,N,4.19,K,A*12
 $GNGGA,162647.000,3708.8978,N,02930.5761,E,1,4,2.73,1004.3,M,35.4,M,,*7B
 $GPGSA,A,3,12,02,05,,,,,,,,,,2.90,2.73,0.98*0A
 $GLGSA,A,3,76,,,,,,,,,,,,2.90,2.73,0.98*13
 $GPGSV,3,1,11,25,77,019,,29,61,291,14,12,50,099,17,02,33,047,14*73
 $GPGSV,3,2,11,31,25,312,,05,19,102,18,21,18,208,,24,14,172,18*74
 $GPGSV,3,3,11,14,07,277,,32,02,253,,06,01,036,*4C
 $GLGSV,2,1,06,87,62,256,,77,61,327,,76,59,148,20,86,44,026,*63
 $GLGSV,2,2,06,75,09,148,,78,09,327,*65
 $GNGLL,3708.8978,N,02930.5761,E,162647.000,A,A*48

 OK
 """
 if "+QGNSSRD:" in data:
 GNRMCList=[]
 GNVTGList=[]
 GNGGAList=[]
 GPGSAList=[]
 GPGSVList=[]
 GNGLLList=[]
 
 GNSSList=data.split("\r\n")
 print("info>> GPS Sentence:{}\r\n".format(GNSSList))
 print("info>> GPS Sentence Length:{}\r\n".format(len(GNSSList)))
 #$GNRMC,163650.000,A,3708.8784,N,02930.5870,E,2.88,217.40,240220,,,A*7E
 for i in GNSSList:
 print("info>> GNSSList:{}\r\n".format (i))
 #$GNRMC,162647.000,A.....
 if ("$GNRMC" in i)  or ("$GPRMC"  in i):
 GNRMCList=i.split(",")
 gpsClk=""
 gpsLat=""
 gpsLatPole=""
 gpsLong=""
 gpsLongPole=""
 gpsDate=""
 gpsSpeedKn=0.0
 gpsSpeedKms=0.0
 gpsDirection=0.0
 
 #saat verisi varsa
 print("info>> GNRMCList:{}\r\n".format(GNRMCList)) 
 
 if GNRMCList[2]=="A": # Eğer gps verisi geçerli ise
 if GNRMCList[1]!="":
 gpsClk=GNRMCList[1][:6]
 
 #enlem verisi varsa
 if GNRMCList[3]!="":
 print("info>> GPS/GNSS list:{}\r\n".format(GNRMCList))
 try:
 gpsLat=GNRMCList[3]
 gpsLatPole=GNRMCList[4]
 except:
 print("info>> {}\r\n".format(sys.exc_info()[0]))
 #boylam verisi varsa
 if GNRMCList[5]!="":
 print("info>> GPS/GNSS list:{}\r\n".format(GNRMCList))
 try:
 gpsLong=GNRMCList[5]
 gpsLongPole=GNRMCList[6]
 except: 
 print("info>> {}\r\n".format(sys.exc_info()[0]))
 
 #knot (hız verisi)
 if GNRMCList[7]!="":
 gpsSpeedKn=float(GNRMCList[7])
 gpsSpeedKms=gpsSpeedKn*knot*3.6
 print("info>> gps Speed:{kn:4.1f} knot; {km:3.1f} km/s \r\n".format(kn=gpsSpeedKn,km=gpsSpeedKms))
 
 #Yön verisi
 if GNRMCList[8]!="":
 gpsDirection=float(GNRMCList[8])
 print("info>> gps Direction:{s:4.2f}\r\n".format(s=gpsDirection))
 #tarih verisi varsa
 if GNRMCList[9]!="":
 gpsDate=GNRMCList[9]
 
 print("info>> GPRMC: clk:{}, Date:{}, Lat:{}{}, Long:{}{}\r\n".format(gpsClk,gpsDate,gpsLat,gpsLatPole,gpsLong,gpsLongPole))
 #TODO: naviDate ve naviTime GPS verisi değil gsm verisidir
 naviDate=yr+ "/"+mnt+ "/"+day
 naviTime=clk+ ":"+mn+ ":"+sec
 lat=gpsLat+gpsLatPole
 long=gpsLong+gpsLongPole
 #TODO: Girilen saat-tarih verisi gps değil gsm saat-tarih verisidir.
 naviLog(lat,long,naviDate,naviTime,gpsSpeedKms,gpsDirection)
 else:
 print("info>> GPS/GNSS data is invalid\r\n")
 #$GNVTG,79.50,T,,M...
 if "$GNVTG" or "$GPVTG"  in i:
 GNVTGList=i.split(",")
 
 #$GNGLL,3708.8978,N,02930.
 if "$GNGLL" or "$GPGLL"  in i:
 GNGLLList=i.split(",")
 #Seriporttan gelen veriyi değer olarak gönder
 return data

SMS Gönderme Rutini atGonder library kullanarak sms gönderme işlemini yapıyor.
Gsm modül aldığı smsi CMTI texti ile bildiriyor. Bu kısımda atGonder içinde algılanıp text işleniyor, sms içeriği, gönderen numara alınıyor. Sms text içinde geçerli On, Off, Blink, Loc? gibi geçerli text varsa ona göre işlem yapılıyor.

#SMS Gönderme fonksiyonu
def sendSMS(num,text):
 print("info>> SMS Rutini")
 atGonder("atCSMP")
 atGonder("atCSCS")
 resp=atGonder("atCMGS",num)
 if bigger in resp: 
 ser.write(text.encode('utf-8'))
 ser.write(bckspc)
 print("info>> smsRutini Sonu\r\n")
 
 if bigger in gelen: 
 ser.write(text.encode('utf-8'))
 ser.write(bckspc)
 print("smsRutini Sonu\r\n")

Led Bildirimleri için GPIO library:
def blink(x):
 if x==0:
 led0.write(False)
 sleep(0.1)
 led0.write(True)
 sleep(0.1)
 if x==1:
 led1.write(False)
 sleep(0.1)
 led1.write(True)
 sleep(0.1)
 if x==2:
 led2.write(False)
 sleep(0.2)
 led2.write(True)
 if x==3:
 led3.write(False)
 sleep(0.1)
 led3.write(True)
 sleep(0.1)
 if x==4:
 led4.write(False)
 sleep(0.1)
 led4.write(True)
 sleep(0.1)
 

Eğer cihazınızın birden fazlası aynı veritabanı ile çalışacaksa cihazlarınıza id vermeniz gerekir bunun için de MAC adresini kullanabilirsiniz.

def getMacAddr():
 eth_mac = get_mac_address(interface="apcli0")
 return eth_mac
 #print("ethernet Mac:{}\r\n".format(eth_mac))



GSM modülün açılıştan sonraki genel ayarları:

atGonder("at")
atGonder("atE0")            
atGonder("atQGSN")
atGonder("atCCID")
atGonder("atQNITZ")
atGonder("atCTZU")
atGonder("atCTZR")
atGonder("atCCLK")
atGonder("atQGNSSC")
atGonder("atCREG")
atGonder("atQGNSS")
atGonder("atCMGF")
atGonder("atCNMI")
atGonder("atQNSTATUS")
atGonder("atCSQ")
#atGonder("atCMGD")


GPS koordinatları hesabında bir derece 60 dakikaya eşit, Google konum hesabında ise bir derece 100 dakikaya eşit. Bu yüzden verilen Gps datadan alınan değer Google Maps üzerinde görüntülenmek istenirse verilen koordinatların derece kısmı aynı kalıp dakika ve saniye kısmı 60'a bölünerek yeniden derece kısmı ile toplanması sonucu Google formatına dönüştürülmüş oluyor.

Örnek:
GPS Şu koorinatı verdi:

4121.0000E ile işaretli boylamı hesaplayalım. GPS bize bu boylamın 41 derece 21 dakikada bulunduğunu belirtiyor.
Bu koordinatı Google Maps üzerinde işleyeceğimiz zaman 41 derece kısmı sabit kalacak 21 dakika kısmını (gerçek koordinatlardaki saniye ve salise kısmını da) 60'a bölerek 35 ile topluyoruz.
21.0000 / 60 =  0.35
41+0.35 = 41.35
sonra bunu google maps linkine ekliyoruz.
"https://www.google.com.tr/maps/place/{}.{}{}+{}.{}{} ".format(en_der,en_str,en_pol,boy_der,boy_str,boy_pol)
https://www.google.com.tr/maps/place/41.35E+41.35N

def hesapla(enlem,boylam):
    #https://www.google.com.tr/maps/place/37.186133N+03.219205E

    en_der=enlem[:2]
    en_toplu=enlem[2:len(enlem)-1]
    #print("enlem: {}\r\n".format(enlem))
    #print("en_toplu: {}\r\n".format(en_toplu))

    en_int=float(en_toplu)/60
    en_str=str(en_int)[2:8]

                                            
    en_pol=enlem[len(enlem)-1:len(enlem)]
    boy_der=boylam[:3]
    boy_toplu=boylam[3:len(boylam)-1]

    #print("boylam: {}\r\n".format(boylam))
    #print("boy_toplu: {}\r\n".format(boy_toplu))

    boy_int=float(boy_toplu)/60
    boy_str=str(boy_int)[2:8]

    #print("boy_str:{}\r\n".format(boy_str))

    boy_pol=boylam[len(boylam)-1:len(boylam)]

    koordinat="""<a href="https://www.google.com.tr/maps/place/{}.{}{}+{}.{}{}"  target="_blank">konum</a>""".format(en_der,en_str,en_pol,boy_der,boy_str,boy_pol)
    return koordinat


While bloğu:

while(True):
 if (sayac%1000==0):
 print("sayac: {}\r\n".format(int(sayac/1000)))
 sayac+=1
 """
 if terminal.in_waiting>0:
 terminalRespText=terminal.read(terminal.in_waiting).decode('utf-8')
 # q tuşu programı kırar
 if "q" in terminalRespText:
 break
 # a tuşu sendSMS çağır
 if "a" in terminalRespText:
 sendSMS("+90505xxxxxx","SMS check. OK")
 # a tuşu sendSMS çağır
 if "s" in terminalRespText:
 atGonder("atQGNSSRD")
 
 if "z" in terminalRespText:
 atGonder("atQIFGCNT")
 if "x" in terminalRespText:
 atGonder("atQICSGP")
 if "c" in terminalRespText:
 atGonder("atQIREGAPP")
 if "v" in terminalRespText:
 atGonder("atQIACT")
 if "b" in terminalRespText:
 atGonder("atQLOCCFG")
 if "n" in terminalRespText:
 atGonder("atQCELLLOC")

 sleep(0.001)
 if ser.in_waiting>0: 
 print("info>> Gsm serial port receive data\r\n")
 blink(2)
 data=atGonder("") 
 
 if (sayac%5000==0):
 #print("saat:\r\n")
 blink(0)
 atGonder("atCCLK")
 
 if (sayac%8000==0):
 #CREG ve Sinyal Seviyesini 8 saniyede bir kontrol et.
 blink(0)
 atGonder("atCREG")
 blink(0)
 atGonder("atCSQ")
 
 
 #TODO:Gps ortalama 30 saniyede çalışsın. 
 if (sayac %30000==0):
 blink(2)
 atGonder("atQGNSSRD")
 
 if smsAlert==True:
 print("info>> SMS Kontrol\r\n")
 smsAlert=False
 blink(2)
 atGonder("atCMGL") # sms Kontrol et
 
 #TODO: Dakika saat ve tarih değişiminde çalışacak rutinler buraya eklenebilir.
 if mnChange==True: # Dakika değişimi
 mnChange=False
 # dakikada bir konum al
 #TODO: Şimdilik GPS 30 sn yede bir çalışsın
 #blink(2)
 #atGonder("atQGNSSRD")
 
 
 if clkChange==True: # Saat değişimi
 clkChange=False
 
 if dayChange==True: # Gün değişimi
 dayChange=False
 
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

fide

Oluşturulan Veritabanından izlenebilir Google maps linki elde etmek için:
Veri Çek:

def getData(dbFile):
    with db.connect(dbFile) as vt:
        im=vt.cursor()
        sorguText="select lat,long,date,time,speed,direction from naviLog order by id desc " #limit (500)"
        im.execute(sorguText)
        veri=im.fetchall()
        vt.commit()
        return (veri)

Hesapla:

def hesapla(enlem,boylam):
    #https://www.google.com.tr/maps/place/37.186133N+03.219205E

    en_der=enlem[:2]
    en_toplu=enlem[2:len(enlem)-1]
    #print("enlem: {}\r\n".format(enlem))
    #print("en_toplu: {}\r\n".format(en_toplu))

    en_int=float(en_toplu)/60
    en_str=str(en_int)[2:8]

                                            
    en_pol=enlem[len(enlem)-1:len(enlem)]
    boy_der=boylam[:3]
    boy_toplu=boylam[3:len(boylam)-1]

    #print("boylam: {}\r\n".format(boylam))
    #print("boy_toplu: {}\r\n".format(boy_toplu))

    boy_int=float(boy_toplu)/60
    boy_str=str(boy_int)[2:8]

    #print("boy_str:{}\r\n".format(boy_str))

    boy_pol=boylam[len(boylam)-1:len(boylam)]

    koordinat="""<a href="https://www.google.com.tr/maps/place/{}.{}{}+{}.{}{}"  target="_blank">konum</a>""".format(en_der,en_str,en_pol,boy_der,boy_str,boy_pol)
    return koordinat

Format oluştur ve html koduna ekle:

veri=getData(dbFile)
rawText=""
sayac=0
for i in veri:
    lat=i[0]
    long=i[1]
    date=i[2]
    time=i[3]
    speed=i[4]
    direction=i[5]
    link=hesapla(lat,long)
    sayac+=1
    rawText+="""<tr>
        <td width=50 align="center">{}</td>
        <td width=150 align="center">{}</td>
        <td width=150 align="center">{}</td>
        <td width=150 align="center">{}</td>
        <td width=150 align="center">{}</td>
        <td width=150 align="center">{}</td>
        </tr>""".format(sayac,date,time,int(speed),int(direction),link)

#print(rawText)

linkText="""<html>
        <body>
                <table border=1>
                        <tr>
                                <td width=50 align="center"><h3>Sıra</h3></td>
                                <td width=150 align="center"><h3>Tarih</h3></td>
                                <td width=150 align="center"><h3>Saat</h3></td>
                                <td width=150 align="center"><h3>Hız</h3></td>
                                <td width=150 align="center"><h3>Yön</h3></td>
                                <td width=150 align="center"><h3>Konum</h3></td>
                                
                        </tr>
                        {}
                </table>
        </body>
</html>""".format(rawText)

htmlFile=dbFilePath + "/navi.html"
with open(htmlFile,"w") as dosya:
    dosya.write(linkText)
    
new = 2 # open in a new tab, if possible

url = dbFilePath + "navi.html"
webbrowser.open(url,new=new)
"""
// open an HTML file on my own (Windows) computer
url = "file://d/testdata.html"
webbrowser.open(url,new=new)
"""
print("OK")


Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

fide

Yukarıdaki dosyalar buradan indirilebilir.

https://easyupload.io/mp6ual
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com