From 7c346caa5ca76f9d804d53ac77c7aada646cf91c Mon Sep 17 00:00:00 2001 From: SpaceNerd0717 Date: Fri, 14 Nov 2025 23:36:20 -0500 Subject: [PATCH 1/2] Update main.py --- main.py | 239 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 198 insertions(+), 41 deletions(-) diff --git a/main.py b/main.py index 1d3de91..16c1c9c 100644 --- a/main.py +++ b/main.py @@ -27,7 +27,7 @@ COUNTDOWN_HTML = os.path.join(app_folder, "countdown.html") GONOGO_HTML = os.path.join(app_folder, "gonogo.html") SHEET_LINK = "" session = requests.Session() -appVersion = "0.6.1" +appVersion = "0.7.0" SETTINGS_FILE = os.path.join(app_folder, "settings.json") # Default settings @@ -53,6 +53,8 @@ DEFAULT_SETTINGS.setdefault("gn_bg_color", "#111111") DEFAULT_SETTINGS.setdefault("gn_border_color", "#FFFFFF") DEFAULT_SETTINGS.setdefault("gn_go_color", "#00FF00") DEFAULT_SETTINGS.setdefault("gn_nogo_color", "#FF0000") +DEFAULT_SETTINGS.setdefault("gn_caution_color", "#FFA500") # orange +DEFAULT_SETTINGS.setdefault("html_gn_caution_color", "#FFA500") DEFAULT_SETTINGS.setdefault("gn_font_px", 20) DEFAULT_SETTINGS.setdefault("appearance_mode", "dark") @@ -133,16 +135,28 @@ def fetch_gonogo(): mode = settings.get("mode", "spreadsheet") # If manual mode, read values from a runtime stash (set by the GUI buttons) if mode == "buttons": - # stored values will be on the app class; fallback to N/A + # stored values will be on the function object (set by the GUI dialog/buttons) try: - return [ - getattr(fetch_gonogo, "manual_range", "N/A"), - getattr(fetch_gonogo, "manual_weather", "N/A"), - getattr(fetch_gonogo, "manual_vehicle", "N/A"), - ] + range_val = getattr(fetch_gonogo, "manual_range", "N/A") + weather_val = getattr(fetch_gonogo, "manual_weather", "N/A") + vehicle_val = getattr(fetch_gonogo, "manual_vehicle", "N/A") + + # If values are numeric strings or numbers, we keep them numeric (so formatting + coloring works) + # convert empty strings -> "N/A" + def normv(v): + if v is None: + return "N/A" + s = str(v).strip() + if s == "": + return "N/A" + return s + + return [normv(range_val), normv(weather_val), normv(vehicle_val)] except Exception: return ["N/A", "N/A", "N/A"] + + # spreadsheet mode link = settings.get("sheet_link", SHEET_LINK) col = max(1, int(settings.get("column", 12))) - 1 @@ -172,34 +186,81 @@ def fetch_gonogo(): # Helper for color # ------------------------- def get_status_color(status): - """Return color name for a Go/No-Go status string.""" + """ + Accepts status which may be: + - a percentage string/number (e.g. '82', '82.0', 82) + - 'GO', 'NO-GO', 'CAUTION' or variants + - anything else -> white + Returns CSS color names / hex strings. + """ try: - s = str(status or "").strip().upper() - # normalize to letters only so variants like 'NO GO', 'NO-GO', 'NOGO' match - norm = re.sub(r"[^A-Z]", "", s) + if status is None: + return "white" + s = str(status).strip() + # Try numeric percentage first + try: + pct = float(s.replace("%", "")) + + # Bound it to 0..100 + pct = max(0.0, min(100.0, pct)) + if pct >= 75.0: + return "green" + if pct >= 50.0: + return "orange" + return "red" + except Exception: + pass + + # Non-numeric: interpret standard words + norm = re.sub(r"[^A-Z]", "", s.upper()) if norm == "GO": return "green" - if norm == "NOGO": + if norm == "NOGO" or norm == "NOGO" or norm == "NOGO": return "red" - # fallback: treat unknown/empty as white + if norm == "CAUTION" or norm == "CAUT": + return "orange" return "white" except Exception: return "white" def format_status_display(status): + """ + Formats the status for display: + - numeric -> 'NN%' (rounded as needed) + - 'NO-GO'/'GO' -> canonical formatting + - otherwise return original string + """ try: - s = str(status or "").strip().upper() - norm = re.sub(r"[^A-Z]", "", s) + if status is None: + return "N/A" + s = str(status).strip() + # numeric + try: + pct = float(s) + # bound and show as integer if whole, else one decimal + pct = max(0.0, min(100.0, pct)) + if abs(pct - round(pct)) < 0.001: + return f"{int(round(pct))}%" + return f"{pct:.1f}%" + except Exception: + pass + + # canonical text forms + norm = re.sub(r"[^A-Z]", "", s.upper()) if norm == "GO": return "GO" if norm == "NOGO": return "NO-GO" + if norm == "CAUTION": + return "CAUTION" + # fallback to raw return s except Exception: return str(status or "") + # ------------------------- # Write Countdown HTML # ------------------------- @@ -251,30 +312,28 @@ body {{ f.write(html) -# ------------------------- -# Write Go/No-Go HTML -# ------------------------- def write_gonogo_html(gonogo_values=None): if gonogo_values is None: gonogo_values = ["N/A", "N/A", "N/A"] s = load_settings() - # Prefer HTML-specific settings; fall back to GUI appearance settings for backwards compatibility bg = s.get("html_bg_color", s.get("bg_color", "#000000")) text = s.get("html_text_color", s.get("text_color", "#FFFFFF")) font = s.get("html_font_family", s.get("font_family", "Consolas, monospace")) gn_bg = s.get("html_gn_bg_color", s.get("gn_bg_color", "#111111")) gn_border = s.get("html_gn_border_color", s.get("gn_border_color", "#FFFFFF")) - gn_go = s.get("html_gn_go_color", s.get("gn_go_color", "#00FF00")) - gn_nogo = s.get("html_gn_nogo_color", s.get("gn_nogo_color", "#FF0000")) gn_px = int(s.get("html_gn_font_px", s.get("gn_font_px", 28))) - # normalize and format display values so variants like 'NO GO' become 'NO-GO' - disp0 = format_status_display(gonogo_values[0]) - disp1 = format_status_display(gonogo_values[1]) - disp2 = format_status_display(gonogo_values[2]) - n0 = re.sub(r"[^A-Z]", "", (str(gonogo_values[0] or "")).strip().upper()) - n1 = re.sub(r"[^A-Z]", "", (str(gonogo_values[1] or "")).strip().upper()) - n2 = re.sub(r"[^A-Z]", "", (str(gonogo_values[2] or "")).strip().upper()) + # Prepare display text and color for each item + disp = [format_status_display(v) for v in gonogo_values] + + def pick_css_color(v): + return get_status_color(v) + + c0 = pick_css_color(gonogo_values[0]) + c1 = pick_css_color(gonogo_values[1]) + c2 = pick_css_color(gonogo_values[2]) + + # Inline style approach per box to ensure color picks up numeric/word cases html = f""" @@ -301,8 +360,6 @@ body {{ text-align: center; background-color: {gn_bg}; }} -.go {{ color: {gn_go}; }} -.nogo {{ color: {gn_nogo}; }} {mission_div_hidden} diff --git a/readme.md b/readme.md index fc72e21..5d0bab8 100644 --- a/readme.md +++ b/readme.md @@ -12,6 +12,9 @@ For setting up the HTML sources to use in OBS, or similiar softwares. Follow the 2. Select "Local file" 3. Select html file 4. Check both "Shutdown source when not visible" and "Refresh browser when scene becomes active" +5. Install the extension "xObsBrowserAutoRefresh" + - Download from https://obsproject.com/forum/resources/xobsbrowserautorefresh-timed-automatic-browser-source-refreshing.1677 + - Set auto refresh times to whatever you desire. INSTALL INSTRUCTIONS