Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 32 additions & 79 deletions modules/gps/src/gpsinterface.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import threading
from .steGPS import Gps
from core.sensor import Sensor
# Define RX and TX pins for the board's serial port connected to the GPS.
# These are the defaults you should use for the GPS FeatherWing.
# For other boards set RX = GPS module TX, and TX = GPS module RX pins.
Expand All @@ -9,89 +8,43 @@
from .settings import Settings


class GpsInterface(Sensor):
class GpsInterface():

def __init__(self, settings: Settings, timezone_hours=+1):
self._settings = settings
self._settings_lock = threading.Lock()
self._gps = Gps('/dev/ttyAMA1', timezone_hours)
def __init__(
self,
latitude_start: float,
longitude_start: float,
latitude_end: float,
longitude_end: float,
serial_port: str,
):
self._latitude_start = latitude_start
self._longitude_start = longitude_start
self._latitude_end = latitude_end
self._longitude_end = longitude_end
self._gps = Gps(serial_port)

def signal(self, value: str):
if value == 'reset':
self.reset_distance()

def export(self):
def read_data(self):
return {
'timestamp': self.timestamp,
'latitude': round(self.latitude, 6),
'longitude': round(self.longitude, 6),
'altitude': self.altitude,
'speedGPS': round(self.speed, 2),
'distanceGPS': self.travelled_distance,
'satellites': self.satellites
'timestampGPS': self._gps.timestamp,
'latitude': round(self._gps.latitude, 6),
'longitude': round(self._gps.longitude, 6),
'altitude': self._gps.altitude,
'speedGPS': round(self._gps.speed, 2),
'distanceGPS': self._gps.travelled_distance,
'satellites': self._gps.satellites,
'distance2timing': self.distance2timing()
}

def update_settings(self, settings: Settings):
with self._settings_lock:
self._settings = settings

@property
def position(self):
return self._gps.position

@property
def latitude(self):
return self._gps.latitude

@property
def longitude(self):
return self._gps.longitude

@property
def altitude(self):
return self._gps.altitude

@property
def speed(self):
return self._gps.speed

@property
def satellites(self):
return self._gps.satellites

@property
def day_time(self):
return self._gps.message_time

@property
def date(self):
return self._gps.date

@property
def timestamp(self):
return self._gps.timestamp

def distance(self, latitude: float, longitude: float):
return self._gps.distance(latitude, longitude)

@property
def travelled_distance(self):
return self._gps.travelled_distance

@property

# it returns distance from rider position to timing zone
def distance2timing(self):
latitude = float(self._settings.latitude_timing_start)
longitude = float(self._settings.longitude_timing_start)
return self._gps.distance(latitude, longitude)
# if distance to the end of time zone is less than distance to start of it
# it means that timing zone is already passed by the rider
distance_to_start = self._gps.distance(self._latitude_start, self._longitude_end)
distance_to_end = self._gps.distance(self._latitude_end, self._longitude_end)
if distance_to_start > distance_to_end:
return 0.0
return distance_to_start

def reset_distance(self):
self._gps.travelled_distance = 0

def is_in_timing(self):
latitude_start = float(self._settings.latitude_timing_start)
longitude_start = float(self._settings.longitude_timing_start)
latitude_end = float(self._settings.latitude_timing_end)
longitude_end = float(self._settings.longitude_timing_end)
distance_start = self._gps.distance(latitude_start, longitude_start)
distance_end = self._gps.distance(latitude_end, longitude_end)
return distance_end - distance_start < self._settings.trap_length
138 changes: 101 additions & 37 deletions modules/gps/src/main.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,107 @@
import time
import sys
import json
from .settings import Settings
from core.mqtt import MqttSensor
import asyncio
import threading
import logging
import os

from core import log, Mqtt, Database, time

from .gpsinterface import GpsInterface


gps: GpsInterface


def message_handler(topic, message):
if topic == 'signals':
gps.signal(message.decode())


def start():
# total arguments
n = len(sys.argv)
if n < 2:
print("Total arguments passed:", n)
return
print("Mqtt server ip:", sys.argv[1])
print('Starting GPS')
settings = Settings({
'trap_length': 200,
'latitude_timing_start': 45.032888,
'longitude_timing_start': 7.792347,
'latitude_timing_end': 45.032888,
'longitude_timing_end': 7.792347
}, 'gps')
global gps
gps = GpsInterface(settings)
mqtt = MqttSensor(sys.argv[1], 1883, 'gps', ['reset'],
settings, message_handler)
# global data storage
data = dict()


async def read_data(gps_interface):
while True:
data.update(gps_interface.read_data())

await asyncio.sleep(0.1)


async def mqtt():
while True:
try:
async with Mqtt() as client:
while True:
for key, value in data.items():
await client.sensor_publish(f"gps/{key}", value)
await asyncio.sleep(0.2)
except Exception as e:
log.err(e)
finally:
await asyncio.sleep(1)


async def write_db(db):
curr_row = None
row = {
"timestamp": str(0),
"timestampGPS": str(0),
"latitude": 0,
"longitude": 0,
"altitude": 0,
"speedGPS": 0,
"distanceGPS": 0,
"satellites": 0,
"distance2timing": 0
}

while True:
print(gps.export())
mqtt.publish(json.dumps(gps.export()))
time.sleep(1)
try:
row.update(data)

if row != curr_row:
row.update({"timestamp": time.human_timestamp()})

db.insert("gps", list(row.values()))

curr_row = dict(row)
except:
pass
finally:
await asyncio.sleep(0.2)


async def main():
while True:
try:
# retrive configurations from db
home_path = os.getenv("HOME")
db_path = os.getenv("DATABASE_PATH") or f"{home_path}/bob/database.db"

db = Database(table="gps", path=db_path, max_pending=10)
config = db.config("gps")

bike = config.get("name")
latitude_start = config.get(f"latitude_start")
longitude_start = config.get(f"longitude_start")
latitude_end = config.get(f"latitude_end")
longitude_end = config.get(f"longitude_start")
serial_port = config.get(f"{bike}_gps_serial")

gps_interface = GpsInterface(
latitude_start,
longitude_start,
latitude_end,
longitude_end,
serial_port
)

await asyncio.gather(
read_data(gps_interface),
mqtt(),
write_db(db),
)
# todo: exception should be something related to serial port
except Exception as e:
print(e)
await asyncio.sleep(0.5)


def entry_point():
asyncio.run(main())


if __name__ == '__main__':
start()
if __name__ == "__main__":
entry_point()