import os import curses import time MERThreshold = 0 def display_percent(stdscr, id, meaning, value): stdscr.addstr(2+id, 0, f"{meaning}: {float(value)/100:.2f} %\n") def display_mer(stdscr, id, meaning, value): stdscr.addstr(2+id, 0, f"{meaning}: {float(value)/10:.1f} dB (need {MERThreshold:.1f} dB)\n") def display_yes_no(stdscr, id, meaning, value): stdscr.addstr(2+id, 0, f"{meaning}: {'yes' if value != 0 else 'no'}\n") def display_state(stdscr, id, meaning, value): states = [ "initialising", "searching", "found headers", "DVB-S lock", "DVB-S2 lock" ] if value < len(states): stdscr.addstr(2+id, 0, f"{meaning}: {states[value]}\n") else: stdscr.addstr(2+id, 0, f"{meaning}: {value}\n") def display_modcod_s(stdscr, id, meaning, value): modcods = [ "QPSK 1/2", "QPSK 2/3", "QPSK 3/4", "QPSK 5/6", "QPSK 6/7", "QPSK 7/8" ] if value < len(modcods): stdscr.addstr(2+id, 0, f"{meaning}: {modcods[value]}\n") else: stdscr.addstr(2+id, 0, f"{meaning}: {value}\n") global MERThreshold MERThreshold = 0 def display_modcod_s2(stdscr, id, meaning, value): modcods = [ "DummyPL", "QPSK 1/4", "QPSK 1/3", "QPSK 2/5", "QPSK 1/2", "QPSK 3/5", "QPSK 2/3", "QPSK 3/4", "QPSK 4/5", "QPSK 5/6", "QPSK 8/9", "QPSK 9/10", "8PSK 3/5", "8PSK 2/3", "8PSK 3/4", "8PSK 5/6", "8PSK 8/9", "8PSK 9/10", "16APSK 2/3", "16APSK 3/4", "16APSK 4/5", "16APSK 5/6", "16APSK 8/9", "16APSK 9/10", "32APSK 3/4", "32APSK 4/5", "32APSK 5/6", "32APSK 8/9", "32APSK 9/10" ] MER_thresholds = [ 0, -2.3, -1.2, -0.3, 1.0, 2.3, 3.1, 4.1, 4.7, 5.2, 6.2, 6.5, 5.5, 6.6, 7.9, 9.4, 10.7, 11.0, 9.0, 10.2, 11.0, 11.6, 12.9, 13.2, 12.8, 13.7, 14.3, 15.7, 16.1 ] if value < len(modcods): stdscr.addstr(2+id, 0, f"{meaning}: {modcods[value]}\n") else: stdscr.addstr(2+id, 0, f"{meaning}: {value}\n") global MERThreshold if value < len(MER_thresholds): MERThreshold = MER_thresholds[value] else: MERThreshold = 0 def display_status(stdscr, id, value): meanings = [ "", "State", "LNA Gain", "Puncture Rate", "I Symbol Power", "Q Symbol Power", "Carrier Frequency", "I Constellation", "Q Constellation", "Symbol Rate", "Viterbi Error Rate", "BER", "MER", "Service Provider", "Service", "Null Ratio", "ES PID", "ES Type", "MODCOD", "Short Frames", "Pilot Symbols", "LDPC Error Count", "BCH Error Count", "BCH Uncorrected", "LNB Voltage Enabled", "LNB H Polarisation", "AGC1 Gain", "AGC2 Gain" ] if id < len(meanings): if id in [19, 20, 23, 24, 25]: display_yes_no(stdscr, id, meanings[id], int(value)) elif id == 1: state = int(value) display_state(stdscr, id, meanings[id], state) elif id in [10, 11]: display_percent(stdscr, id, meanings[id], int(value)) elif id == 12: display_mer(stdscr, id, meanings[id], int(value)) elif id == 18: state = int(value) if state == 3: display_modcod_s(stdscr, id, meanings[id], int(value)) elif state == 4: display_modcod_s2(stdscr, id, meanings[id], int(value)) else: stdscr.addstr(2+id, 0, f"{meanings[id]}: {value}\n") else: stdscr.addstr(2+id, 0, f"{id}: {value}\n") def main(stdscr): os.system('clear') stdscr.addstr(1, 0, "LongMynd DATV Receiver Status\n") try: status_fifo = open("longmynd_main_status", "r") except Exception as e: stdscr.addstr(2, 0, f"Failed to open status fifo: {e}\n") stdscr.refresh() time.sleep(2) return stdscr.scrollok(True) stdscr.addstr(2, 0, "Listening\n") stdscr.refresh() while True: status_message = status_fifo.readline().strip() if status_message.startswith('$'): parts = status_message[1:].split(',') if parts: n = int(parts[0]) m_str = parts[1] if len(parts) > 1 else '' display_status(stdscr, n, m_str) stdscr.refresh() if __name__ == "__main__": curses.wrapper(main)