#!/usr/bin/python # -*- coding:utf-8 -*- import RPi.GPIO as GPIO import serial import time from datetime import datetime import os import signal from influxdb_client import InfluxDBClient, Point from influxdb_client.client.write_api import SYNCHRONOUS import logging # Set up logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') # GPIO configuration GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) try: ser = serial.Serial('/dev/ttyUSB3', 115200) ser.flushInput() except serial.SerialException as e: logging.error(f"Failed to open serial port: {e}") exit(1) myhost = os.uname()[1] # InfluxDB settings INFLUXDB_URL = "http://100.64.0.24:8086" INFLUXDB_TOKEN = "IPtqPXbaXuuMHvx_tUOt1cmIZfLHucd-9DcepXTVpQc-fNKBhp6pkhyTsq_XnoGXdxwILy5AFFgZ_QUZCE5Jhg==" INFLUXDB_ORG = "juandiego" # Replace with your organization name INFLUXDB_BUCKET = "gpsdata" # Initialize InfluxDB client try: client = InfluxDBClient(url=INFLUXDB_URL, token=INFLUXDB_TOKEN, org=INFLUXDB_ORG) write_api = client.write_api(write_options=SYNCHRONOUS) logging.info("Successfully connected to InfluxDB") except Exception as e: logging.error(f"Failed to connect to InfluxDB: {e}") exit(1) def parse_gps_data(gps_string): parts = gps_string.split(',') if len(parts) < 4: logging.warning(f"Incomplete GPS data: {gps_string}") return None try: lat = float(parts[0][:2]) + float(parts[0][2:]) / 60 if parts[1] == 'S': lat = -lat lon = float(parts[2][:3]) + float(parts[2][3:]) / 60 if parts[3] == 'W': lon = -lon return lat, lon except Exception as e: logging.error(f"Error parsing GPS data: {e}") return None def write_to_influxdb(lat, lon): timestamp = int(time.time() * 1000000000) # nanosecond precision try: gps_point = Point("gps_location") \ .tag("host", myhost) \ .field("latitude", lat) \ .field("longitude", lon) \ .field("geolocation", f"{lat},{lon}") \ .time(timestamp) write_api.write(bucket=INFLUXDB_BUCKET, record=gps_point) logging.info(f"Data written to InfluxDB: Lat: {lat}, Lon: {lon}") except Exception as e: logging.error(f"Failed to write to InfluxDB: {e}") def send_at(command, back, timeout): try: ser.write((command + '\r\n').encode()) time.sleep(timeout) if ser.inWaiting(): time.sleep(0.01) rec_buff = ser.read(ser.inWaiting()).decode() if back in rec_buff: gps_data = rec_buff.split('+CGPSINFO: ')[1].split('\r\n')[0] logging.debug(f"Raw GPS data: {gps_data}") parsed_data = parse_gps_data(gps_data) if parsed_data: lat, lon = parsed_data logging.info(f"GPS: Lat: {lat:.6f}, Lon: {lon:.6f}") write_to_influxdb(lat, lon) return 1 else: logging.warning(f"Expected response not found. Received: {rec_buff}") else: logging.warning("No data received from GPS module") except Exception as e: logging.error(f"Error communicating with GPS module: {e}") return 0 def get_gps_position(): return send_at('AT+CGPSINFO', '+CGPSINFO:', 1) def initialize_gps(): logging.info('Starting GPS') if send_at('AT+CGPS=1', 'OK', 1): logging.info("GPS module initialized successfully") else: logging.error("Failed to initialize GPS module") time.sleep(2) # Main execution initialize_gps() logging.info("Getting GPS position...") if not get_gps_position(): logging.warning("Failed to get GPS position") # Clean up ser.close() GPIO.cleanup() client.close() logging.info("GPS tracking completed. Goodbye!")