Created
March 30, 2025 20:11
-
-
Save filbot/0e98902e0be5b642649541b9df85aaa3 to your computer and use it in GitHub Desktop.
Python script to display PiAware data on an LCD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import time | |
| import json | |
| import os | |
| from RPLCD.i2c import CharLCD | |
| def get_cpu_temperature(): | |
| """Reads CPU temperature in °C from the system file.""" | |
| try: | |
| with open("/sys/class/thermal/thermal_zone0/temp", "r") as f: | |
| temp = float(f.read().strip()) / 1000.0 | |
| return temp | |
| except Exception as e: | |
| print("Error reading CPU temperature:", e) | |
| return None | |
| def get_uptime(): | |
| """Reads uptime from /proc/uptime and returns a string in HH:MM:SS format.""" | |
| try: | |
| with open("/proc/uptime", "r") as f: | |
| uptime_seconds = float(f.read().split()[0]) | |
| hours = int(uptime_seconds // 3600) | |
| minutes = int((uptime_seconds % 3600) // 60) | |
| seconds = int(uptime_seconds % 60) | |
| return f"{hours:02}:{minutes:02}:{seconds:02}" | |
| except Exception as e: | |
| print("Error reading uptime:", e) | |
| return "N/A" | |
| def get_aircraft_messages(): | |
| """ | |
| Reads the aircraft.json file to get the cumulative number of ADS‑B messages. | |
| Returns an integer count or None on failure. | |
| """ | |
| path = "/run/dump1090-fa/aircraft.json" | |
| try: | |
| with open(path, "r") as f: | |
| data = json.load(f) | |
| return int(data.get("messages", 0)) | |
| except Exception as e: | |
| print("Error reading aircraft messages:", e) | |
| return None | |
| def update_row(lcd, row, new_str, prev_str): | |
| """ | |
| Updates only the characters that have changed in a given row. | |
| Always iterates over 20 columns. | |
| """ | |
| for col in range(20): | |
| new_char = new_str[col] if col < len(new_str) else " " | |
| prev_char = prev_str[col] if col < len(prev_str) else " " | |
| if new_char != prev_char: | |
| lcd.cursor_pos = (row, col) | |
| lcd.write_string(new_char) | |
| def format_line(label, value): | |
| """ | |
| Returns a 20-character string with the label left-aligned | |
| and the value right-aligned. | |
| """ | |
| remaining = 20 - len(label) | |
| line = f"{label}{value:>{remaining}}" | |
| return line[:20] | |
| def main(): | |
| # Initialize the LCD: adjust I2C address if needed (commonly 0x27). | |
| lcd = CharLCD('PCF8574', 0x27, port=1, cols=20, rows=4) | |
| lcd.clear() | |
| # We'll store the last displayed lines to avoid rewriting unchanged characters. | |
| prev_lines = [" " * 20 for _ in range(4)] | |
| # Get initial ADS‑B message count. | |
| prev_messages = get_aircraft_messages() | |
| if prev_messages is None: | |
| prev_messages = 0 | |
| # Variable to store peak ADS‑B rate observed. | |
| peak_adsb_rate = 0 | |
| while True: | |
| cpu_temp = get_cpu_temperature() | |
| uptime_str = get_uptime() | |
| current_messages = get_aircraft_messages() | |
| if current_messages is None: | |
| current_messages = prev_messages | |
| # Calculate the current ADS‑B message rate (messages per second). | |
| current_adsb_rate = current_messages - prev_messages | |
| prev_messages = current_messages | |
| # Update the peak if needed. | |
| if current_adsb_rate > peak_adsb_rate: | |
| peak_adsb_rate = current_adsb_rate | |
| # Build each line with a label on the left and value on the right. | |
| # New order remains as: Row0 = Current ADS-B, Row1 = Peak ADS-B, | |
| # Row2 = CPU TEMP, Row3 = UPTIME. | |
| adsb_line = format_line("ADS-B:", f"{current_adsb_rate:>3} msg/s") | |
| peak_line = format_line("PEAK:", f"{peak_adsb_rate:>3} msg/s") | |
| cpu_line = format_line("CPU TEMP:", f"{cpu_temp:.1f}C" if cpu_temp is not None else "N/A") | |
| uptime_line = format_line("UPTIME:", uptime_str) | |
| new_lines = [ | |
| adsb_line.ljust(20)[:20], | |
| peak_line.ljust(20)[:20], | |
| cpu_line.ljust(20)[:20], | |
| uptime_line.ljust(20)[:20] | |
| ] | |
| # Update only changed characters per row. | |
| for row in range(4): | |
| if new_lines[row] != prev_lines[row]: | |
| update_row(lcd, row, new_lines[row], prev_lines[row]) | |
| prev_lines[row] = new_lines[row] | |
| time.sleep(1) | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment