====== Status Display ====== If you attach a type SSD1306 128x64 OLED display to the i2c pins on your TimePi, you can use this script to display the current system status. {{https://i.imgur.com/M9aoeXk.mp4?960x624}} #! /usr/bin/python # John Miller 2022-03-28 # Combined from: https://learn.adafruit.com/adafruit-pioled-128x32-mini-oled-for-raspberry-pi/usage # and: http://www.danmandle.com/blog/getting-gpsd-to-work-with-python/ import os from gps import * from time import * import threading import subprocess from board import SCL, SDA import busio from PIL import Image, ImageDraw, ImageFont import adafruit_ssd1306 gpsd = None #seting the global variable # Create the I2C interface. i2c = busio.I2C(SCL, SDA) # create display class disp = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c) # Clear display. disp.fill(0) disp.show() # Create blank image for drawing. # Make sure to create image with mode '1' for 1-bit color. width = disp.width height = disp.height image = Image.new("1", (width, height)) # Get drawing object to draw on image. draw = ImageDraw.Draw(image) draw.rectangle((0, 0, width, height), outline=0, fill=0) padding = -2 top = padding bottom = height - padding x = 0 font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 11) class GpsPoller(threading.Thread): def __init__(self): threading.Thread.__init__(self) global gpsd #bring it in scope gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info self.current_value = None self.running = True #setting the thread running to true def run(self): global gpsd while gpsp.running: gpsd.next() #this will continue to loop and grab EACH set of gpsd info to clear the buffer if __name__ == '__main__': gpsp = GpsPoller() # create the thread try: gpsp.start() # start it up while True: # It may take a second or two to get good data # print(gpsd.fix.latitude,', ',gpsd.fix.longitude,' Time: ',gpsd.utc) os.system('clear') # clear LCD draw.rectangle((0, 0, width, height), outline=0, fill=0) ipv4 = os.popen('ip addr show eth0 | grep "\" | awk \'{ print $2 }\' | awk -F "/" \'{ print $1 }\'').read().strip() load = os.popen("cat /proc/loadavg | awk '{print $1 \", \" $2 \", \" $3}'").read()[:-1] days = os.popen("expr `cat /proc/uptime | cut -d '.' -f1` % 31556926 / 86400").read()[:-1] hours = os.popen("expr `cat /proc/uptime | cut -d '.' -f1` % 31556926 % 86400 / 3600").read()[:-1] minutes = os.popen("expr `cat /proc/uptime | cut -d '.' -f1` % 31556926 % 86400 % 3600 / 60").read()[:-1] cputemp = os.popen("sensors | grep temp1 | awk '{print substr($2,2);}' | sed -n '2p'").read()[:-1] rtctemp = os.popen("sensors | grep temp1 | awk '{print substr($2,2);}' | sed -n '1p'").read()[:-1] date = os.popen("date +%Y-%m-%d").read()[:-1] time = os.popen("date -u +'%T %Z'").read()[:-1] reference = os.popen("chronyc tracking | sed -n 1p | awk '{print $5}' | tr -d '(),'").read()[:-1] stratum = os.popen("chronyc tracking | sed -n 2p | awk '{print $3}'").read()[:-1] jitter = os.popen("chronyc sources | sed -n 3p | awk '{print $10}'").read()[:-1] statusdict = {0: 'Unknown', 1: 'GPS', 2: 'DGPS', 3: 'RTK', 4: 'RTK FLT', 5: 'DR', 6: 'GNSSDR', 7: 'Surveyed', 8: 'SIM', 9: 'PPS'} fixdict = {1: 'No Fix', 2: '2D', 3: '3D'} draw.text((x, top + 0), "==== SYSTEM ====", font=font, fill=255) draw.text((x, top + 12), "IP: " + ipv4, font=font, fill=255) draw.text((x, top + 22), "Load: " + load, font=font, fill=255) draw.text((x, top + 32), "CPU Temp: " + cputemp, font=font, fill=255) draw.text((x, top + 42), "RTC Temp: " + rtctemp, font=font, fill=255) draw.text((x, top + 52), "Uptime: " + days + "D " + hours + "H " + minutes + "M", font=font, fill=255) disp.image(image) disp.show() sleep(5) draw.rectangle((0, 0, width, height), outline=0, fill=0) draw.text((x, top + 0), "===== GNSS =====", font=font, fill=255) draw.text((x, top + 12), "Seen: " + str(len(gpsd.satellites)) + " Used: " + str(gpsd.satellites_used), font=font, fill=255) draw.text((x, top + 22), "Fix Type: " + fixdict.get(gpsd.fix.mode), font=font, fill=255) draw.text((x, top + 32), "Status: " + statusdict.get(gpsd.fix.status), font=font, fill=255) draw.text((x, top + 42), "TDOP: " + str(gpsd.tdop), font=font, fill=255) draw.text((x, top + 52), "PDOP: " + str(gpsd.pdop), font=font, fill=255) disp.image(image) disp.show() sleep(5) #set to whatever draw.rectangle((0, 0, width, height), outline=0, fill=0) draw.text((x, top + 0), "==== CHRONY ====", font=font, fill=255) draw.text((x, top + 12), "Date: " + date, font=font, fill=255) draw.text((x, top + 22), "Time: " + time, font=font, fill=255) draw.text((x, top + 32), "Reference: " + reference, font=font, fill=255) draw.text((x, top + 42), "Stratum: " + stratum, font=font, fill=255) draw.text((x, top + 52), "PPS Jitter: " + jitter, font=font, fill=255) disp.image(image) disp.show() sleep(5) except (KeyboardInterrupt, SystemExit): #when you press ctrl+c print("\nKilling Thread...") gpsp.running = False gpsp.join() # wait for the thread to finish what it's doing # clear screen draw.rectangle((0, 0, width, height), outline=0, fill=0) disp.image(image) disp.show() print("Done.\nExiting.")