5 Commits

Author SHA1 Message Date
Tarek 5a09095cda Call and GPS functionality added 2020-09-03 20:41:10 +02:00
Tarek 4d495905cd README updated 2020-09-03 20:36:59 +02:00
Tarek 76387c74c7 Call and GPS functionality added 2020-09-03 17:06:40 +02:00
Tarek 7c3a6ad886 Call and GPS functionality added 2020-09-03 17:04:39 +02:00
Tarek 32ba0c839f add setup files for PyPi 2020-09-02 12:23:56 +02:00
5 changed files with 309 additions and 10 deletions
+39 -6
View File
@@ -6,6 +6,8 @@ With gsmHat, you can easily use the functionality of the Waveshare GSM/GPRS/GNSS
gsmHat was written for Python 3. It provides the following features gsmHat was written for Python 3. It provides the following features
- Non-blocking receiving and sending SMS in background - Non-blocking receiving and sending SMS in background
- Non-blocking calling
- Non-blocking refreshing of actual gps position
## Usage ## Usage
@@ -13,15 +15,14 @@ In the following paragraphs, I am going to describe how you can get and use gsmH
### Getting it ### Getting it
To download scrapeasy, either fork this github repo or simply use Pypi via pip. To download gsmHat, either fork this github repo or simply use Pypi via pip.
```sh ```sh
$ pip3 install gsmHat $ pip3 install gsmHat
``` ```
### Prepare ### Prepare
* Install your sim card in your module, connect the GSM antenna and mount the module on the pin headers of your Raspberry Pi * Install your sim card in your module, connect the GSM and the GPS antennas and mount the module on the pin headers of your Raspberry Pi. Make sure, that you **do not** need to enter Pin Code to use your card. Pin Codes are not supported yet.
Make sure, that you **do not** need to enter Pin Code to use your card
* Enable the Uart Interface in your Raspberry Pi * Enable the Uart Interface in your Raspberry Pi
@@ -37,7 +38,7 @@ $ pip3 install gsmHat
1. Import gsmHat to your project 1. Import gsmHat to your project
```Python ```Python
from gsmHat import GSMHat, SMS from gsmHat import GSMHat, SMS, GPS
``` ```
2. Init gsmHat 2. Init gsmHat
@@ -76,10 +77,42 @@ Message = 'Hello mobile world'
# Send SMS # Send SMS
gsm.SMS_write(Number, Message) gsm.SMS_write(Number, Message)
``` ```
6. Or you can call a number
```Python
Number = '+491601234567'
gsm.Call(Number) # This call hangs up automatically after 15 seconds
time.sleep(10) # Wait 10 seconds ...
gsm.HangUp() # Or you can HangUp by yourself earlier
gsm.Call(Number, 60) # Or lets change the timeout to 60 seconds. This call hangs up automatically after 60 seconds
```
7. Lets see, where your Raspberry Pi (in a car or in a motocycle or on a cat?) is positioned on earth
```Python
# Get actual GPS position
GPSObj = gsm.GetActualGPS()
# Lets print some values
print('GNSS_status: %s' % str(GPSObj.GNSS_status))
print('Fix_status: %s' % str(GPSObj.Fix_status))
print('UTC: %s' % str(GPSObj.UTC))
print('Latitude: %s' % str(GPSObj.Latitude))
print('Longitude: %s' % str(GPSObj.Longitude))
print('Altitude: %s' % str(GPSObj.Altitude))
print('Speed: %s' % str(GPSObj.Speed))
print('Course: %s' % str(GPSObj.Course))
print('HDOP: %s' % str(GPSObj.HDOP))
print('PDOP: %s' % str(GPSObj.PDOP))
print('VDOP: %s' % str(GPSObj.VDOP))
print('GPS_satellites: %s' % str(GPSObj.GPS_satellites))
print('GNSS_satellites: %s' % str(GPSObj.GNSS_satellites))
print('Signal: %s' % str(GPSObj.Signal))
```
## What will come in the future? ## What will come in the future?
* Outgoing and Incoming Calls
* GPS functionality
* More options to configure the module (e.g. using sim cards with pin code) * More options to configure the module (e.g. using sim cards with pin code)
## On which platform was gsmHat developed and tested? ## On which platform was gsmHat developed and tested?
+1 -1
View File
@@ -1 +1 @@
from gsmHat.gsmHat import GSMHat, SMS from gsmHat.gsmHat import GSMHat, SMS, GPS
+238 -3
View File
@@ -4,6 +4,7 @@ import logging
import serial import serial
import threading import threading
import time import time
import math
import re import re
from datetime import datetime from datetime import datetime
import RPi.GPIO as GPIO import RPi.GPIO as GPIO
@@ -15,23 +16,57 @@ class SMS:
self.Receiver = '' self.Receiver = ''
self.Date = '' self.Date = ''
class GPS:
EarthRadius = 6371e3 # meters
@staticmethod
def CalculateDeltaP(Position1, Position2):
phi1 = Position1.Latitude * math.pi / 180.0
phi2 = Position2.Latitude * math.pi / 180.0
deltaPhi = (Position2.Latitude - Position1.Latitude) * math.pi / 180.0
deltaLambda = (Position2.Longitude - Position1.Longitude) * math.pi / 180.0
a = math.sin(deltaPhi / 2) * math.sin(deltaPhi / 2) + math.cos(phi1) * math.cos(phi2) * math.sin(deltaLambda / 2) * math.sin(deltaLambda / 2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
d = GPS.EarthRadius * c # in meters
return d
def __init__(self):
self.GNSS_status = 0
self.Fix_status = 0
self.UTC = '' # yyyyMMddhhmmss.sss
self.Latitude = 0.0 # ±dd.dddddd [-90.000000,90.000000]
self.Longitude = 0.0 # ±ddd.dddddd [-180.000000,180.000000]
self.Altitude = 0.0 # in meters
self.Speed = 0.0 # km/h [0,999.99]
self.Course = 0.0 # degrees [0,360.00]
self.HDOP = 0.0 # [0,99.9]
self.PDOP = 0.0 # [0,99.9]
self.VDOP = 0.0 # [0,99.9]
self.GPS_satellites = 0 # [0,99]
self.GNSS_satellites = 0 # [0,99]
self.Signal = 0.0 # % max = 55 dBHz
class GSMHat: class GSMHat:
"""GSM Hat Backend with SMS Functionality (for now)""" """GSM Hat Backend with SMS Functionality (for now)"""
regexGetSingleValue = r'([+][a-zA-Z\ ]+(:\ ))([\d]+)' regexGetSingleValue = r'([+][a-zA-Z\ ]+(:\ ))([\d]+)'
regexGetAllValues = r'([+][a-zA-Z:\s]+)([\w\",\s+\/:]+)' regexGetAllValues = r'([+][a-zA-Z:\s]+)([\w\",\s+\/:.]+)'
timeoutSerial = 5 timeoutSerial = 5
timeoutGPSActive = 1
timeoutGPSInactive = 5
def __init__(self, SerialPort, Baudrate): def __init__(self, SerialPort, Baudrate):
self.__baudrate = Baudrate self.__baudrate = Baudrate
self.__port = SerialPort self.__port = SerialPort
self.__logger = logging.getLogger(__name__) self.__logger = logging.getLogger(__name__)
self.__logger.setLevel(logging.DEBUG) self.__logger.setLevel(logging.INFO)
self.__loggerFileHandle = logging.FileHandler('gsmHat.log') self.__loggerFileHandle = logging.FileHandler('gsmHat.log')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
self.__loggerFileHandle.setFormatter(formatter) self.__loggerFileHandle.setFormatter(formatter)
self.__loggerFileHandle.setLevel(logging.DEBUG) self.__loggerFileHandle.setLevel(logging.INFO )
self.__logger.addHandler(self.__loggerFileHandle) self.__logger.addHandler(self.__loggerFileHandle)
self.__connect() self.__connect()
@@ -56,6 +91,16 @@ class GSMHat:
self.__smsToBuild = None self.__smsToBuild = None
self.__smsList = [] self.__smsList = []
self.__smsSendList = [] self.__smsSendList = []
self.__numberToCall = ''
self.__sendHangUp = False
self.__startGPS = False
self.__GPSstarted = False
self.__GPSstartSending = False
self.__GPSstopSending = False
self.__GPScollectData = False
self.__GPSactualData = GPS()
self.__GPStimeout = self.timeoutGPSInactive * 1000
self.__GPSwaittime = 0
self.__workerThread = threading.Thread(target=self.__workerThread, daemon=True) self.__workerThread = threading.Thread(target=self.__workerThread, daemon=True)
self.__workerThread.start() self.__workerThread.start()
@@ -105,6 +150,35 @@ class GSMHat:
newSMS.Message = Message newSMS.Message = Message
self.__smsSendList.append(newSMS) self.__smsSendList.append(newSMS)
def Call(self, Number, Timeout = 15):
if self.__numberToCall == '':
self.__numberToCall = str(Number)
self.__callTimeout = Timeout
return True
return False
def HangUp(self):
self.__sendHangUp = True
def GetActualGPS(self):
return self.__GPSactualData
def __startGPSUnit(self):
self.__startGPS = True
def __startGPSsending(self):
self.__GPSstartSending = True
def __stopGPSsending(self):
self.__GPSstopSending = True
def __collectGPSData(self):
self.__GPScollectData = True
def ColData(self):
self.__collectGPSData()
def close(self): def close(self):
self.__disconnect() self.__disconnect()
self.__logger.info('Serial connection to '+self.__port+' closed') self.__logger.info('Serial connection to '+self.__port+' closed')
@@ -171,6 +245,74 @@ class GSMHat:
numSMS = int(rawData[1]) numSMS = int(rawData[1])
self.__logger.debug('New SMS in memory ' + storage + ' at position ' + str(numSMS)) self.__logger.debug('New SMS in memory ' + storage + ' at position ' + str(numSMS))
self.__smsToRead = numSMS self.__smsToRead = numSMS
# GPS Data coming here
elif '+CGNSINF:' in self.__serData:
self.__logger.debug('New GPS Data:')
match = re.findall(self.regexGetAllValues, self.__serData)
rawData = match[0][1].split(',')
newGPS = GPS()
try:
newGPS.GNSS_status = int(rawData[0])
except:
pass
try:
newGPS.Fix_status = int(rawData[1])
except:
pass
try:
newGPS.UTC = datetime.strptime(rawData[2][:-4], '%Y%m%d%H%M%S')
except:
pass
try:
newGPS.Latitude = float(rawData[3])
except:
pass
try:
newGPS.Longitude = float(rawData[4])
except:
pass
try:
newGPS.Altitude = float(rawData[5])
except:
pass
try:
newGPS.Speed = float(rawData[6])
except:
pass
try:
newGPS.Course = float(rawData[7])
except:
pass
try:
newGPS.HDOP = float(rawData[10])
except:
pass
try:
newGPS.PDOP = float(rawData[11])
except:
pass
try:
newGPS.VDOP = float(rawData[12])
except:
pass
try:
newGPS.GPS_satellites = int(rawData[14])
except:
pass
try:
newGPS.GNSS_satellites = int(rawData[15])
except:
pass
try:
newGPS.Signal = float(rawData[18])/55.0
except:
pass
self.__GPSactualData = newGPS
self.__serData = '' self.__serData = ''
@@ -222,6 +364,8 @@ class GSMHat:
actTime = int(round(time.time() * 1000)) actTime = int(round(time.time() * 1000))
if self.__state == 1: if self.__state == 1:
if self.__sendToHat('AT+CMGF=1'): if self.__sendToHat('AT+CMGF=1'):
self.__startGPSUnit()
self.__stopGPSsending()
self.__state = 2 self.__state = 2
elif self.__state == 2: elif self.__state == 2:
if self.__waitForUnlock(): if self.__waitForUnlock():
@@ -279,15 +423,106 @@ class GSMHat:
self.__nextState = 2 self.__nextState = 2
self.__waitTime = actTime + 5000 self.__waitTime = actTime + 5000
elif self.__state == 40:
if self.__sendToHat('ATD' + self.__numberToCall + ';'):
self.__state = 41
elif self.__state == 41:
if self.__waitForUnlock():
self.__waitTime = actTime + self.__callTimeout * 1000
self.__state = 42
elif self.__state == 42:
# Wait x Seconds
if actTime > self.__waitTime or self.__sendHangUp == True:
self.__numberToCall = ''
self.__sendHangUp = True
self.__state = 97
self.__nextState = 2
self.__waitTime = actTime + 5000
elif self.__state == 43:
if self.__sendToHat('AT+CHUP'):
self.__state = 44
elif self.__state == 44:
if self.__waitForUnlock():
self.__sendHangUp = False
self.__state = 97
self.__nextState = 2
self.__waitTime = actTime + 5000
elif self.__state == 50:
if self.__sendToHat('AT+CGNSPWR=1'):
self.__state = 51
elif self.__state == 51:
if self.__waitForUnlock():
self.__logger.debug('GPS powered on')
self.__startGPS = False
self.__state = 97
self.__nextState = 2
self.__waitTime = actTime + 5000
elif self.__state == 52:
if self.__sendToHat('AT+CGNSTST=1'):
self.__state = 55
self.__logger.debug('GPS start sending')
self.__GPSstartSending = False
elif self.__state == 53:
if self.__sendToHat('AT+CGNSTST=0'):
self.__state = 55
self.__GPSstopSending = False
elif self.__state == 54:
if self.__sendToHat('AT+CGNSINF'):
self.__state = 55
self.__GPScollectData = False
elif self.__state == 55:
if self.__waitForUnlock():
self.__state = 97
self.__nextState = 2
self.__waitTime = actTime + 5000
elif self.__state == 97: elif self.__state == 97:
# Check if new SMS to send is there # Check if new SMS to send is there
if len(self.__smsSendList) > 0: if len(self.__smsSendList) > 0:
self.__state = 30 self.__state = 30
# Check if we have to Call somebody
elif self.__numberToCall != '':
self.__state = 40
# Should I Hang Up ?
elif self.__sendHangUp:
self.__state = 43
# Check if new SMS is there # Check if new SMS is there
elif self.__smsToRead > 0: elif self.__smsToRead > 0:
self.__state = 20 self.__state = 20
# Check if GPS Unit should start
elif self.__startGPS:
self.__state = 50
# Check if GPS Unit should start send
elif self.__GPSstartSending:
self.__state = 52
# Check if GPS Unit should stop send
elif self.__GPSstopSending:
self.__state = 53
# Check if Single GPS Data should be collected
elif self.__GPScollectData:
self.__state = 54
elif actTime > self.__GPSwaittime:
self.__GPScollectData = True
self.__GPSwaittime = actTime + self.__GPStimeout
# Wait x Seconds # Wait x Seconds
elif actTime > self.__waitTime: elif actTime > self.__waitTime:
self.__state = self.__nextState self.__state = self.__nextState
Executable
+2
View File
@@ -0,0 +1,2 @@
[metadata]
description-file = README.md
Executable
+29
View File
@@ -0,0 +1,29 @@
from distutils.core import setup
setup(
name = 'gsmHat',
packages = ['gsmHat'],
version = '0.2',
license='MIT',
description = 'Using the Waveshare GSM/GPRS/GNSS Hat for Raspberry Pi with Python',
author = 'Tarek Tounsi',
author_email = 'software@tounsi.de',
url = 'https://github.com/Civlo85/gsmHat',
download_url = 'https://github.com/Civlo85/gsmHat/archive/v_02.tar.gz',
keywords = ['Waveshare', 'GSM', 'GPS', 'Raspberry', 'Pi'],
install_requires=[
'serial',
'datetime',
'logging',
],
classifiers=[
'Development Status :: 3 - Alpha', # Chose either "3 - Alpha", "4 - Beta" or "5 - Production/Stable" as the current state of your package
'Intended Audience :: Developers',
'Topic :: Software Development :: Build Tools',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
],
)