From a16833a739cc5e0dc2bd0c44e2597e57900838aa Mon Sep 17 00:00:00 2001 From: ske087 Date: Mon, 27 Apr 2026 14:12:21 +0300 Subject: [PATCH] Add card_presence support: app.py (load/sync/log/RFID+LED gating), config.py GUI dropdown --- app.py | 81 ++++++++++++++++++++++++++++++++++--------------------- config.py | 24 ++++++++++++----- 2 files changed, 68 insertions(+), 37 deletions(-) diff --git a/app.py b/app.py index ddebf29..f74a0a8 100644 --- a/app.py +++ b/app.py @@ -153,6 +153,7 @@ def load_config(): "device_ip": "127.0.0.1", "device_location": "", "device_info_reviewed_at": "1970-01-01T00:00:00", + "card_presence": "enable", "last_synced": "1970-01-01T00:00:00", } @@ -198,6 +199,8 @@ def load_config(): cfg["device_info_reviewed_at"] = parser.get("device", "info_reviewed_at") if parser.has_option("device", "location"): cfg["device_location"] = parser.get("device", "location") + if parser.has_option("device", "card_presence"): + cfg["card_presence"] = parser.get("device", "card_presence") if parser.has_section("meta"): if parser.has_option("meta", "last_synced"): @@ -269,6 +272,7 @@ def _write_config_from_server(new_cfg): p.set("device", "ip", new_cfg.get("device_ip", "")) p.set("device", "location", new_cfg.get("location") or new_cfg.get("device_location", "")) p.set("device", "info_reviewed_at", new_cfg.get("info_reviewed_at") or "1970-01-01T00:00:00") + p.set("device", "card_presence", new_cfg.get("card_presence", "enable")) p.add_section("meta") sync_ts = new_cfg.get("config_updated_at") or datetime.now().isoformat() @@ -364,6 +368,7 @@ def sync_config_with_server(): "device_ip": _ip, "client_config_mtime": last_synced_str, "client_info_reviewed_at": local_info_reviewed_str, + "card_presence": APP_CONFIG.get("card_presence", "enable"), }, timeout=5, ) @@ -381,6 +386,12 @@ APP_CONFIG = load_config() # Attempt to sync with server at startup (non-blocking – failures are logged and ignored) sync_config_with_server() +# --------------------------------------------------------------------------- +# Card presence flag – controls whether RFID functions are started +# --------------------------------------------------------------------------- +CARD_PRESENCE_ENABLED = APP_CONFIG.get("card_presence", "enable").strip().lower() == "enable" +print(f"Card presence: {'ENABLED' if CARD_PRESENCE_ENABLED else 'DISABLED'}") + # Early configuration mode detection (before heavy initialization) def early_launch_configuration_mode(): """ @@ -986,6 +997,7 @@ def send_log_to_server(log_message, n_masa, hostname, device_ip): "os_version": _get_os_version(), "location": APP_CONFIG.get("device_location", ""), "mac_address": _get_mac_address(), + "card_presence": APP_CONFIG.get("card_presence", "enable"), } server_url = APP_CONFIG.get("server_log_url", "http://rpi-ansible:80/logs") print(log_data) # Debugging: Print log_data to verify its contents @@ -1607,28 +1619,32 @@ def post_info_thread(info): print(f"Async posting failed, using sync fallback: {e}") post_info(info) -# Initialize LEDs with error handling -try: - print("Initializing LED controls...") - led1 = OutputDevice(23) - led2 = OutputDevice(24) - print("✓ LED controls initialized successfully") - log_info_with_server("LED controls initialized") -except Exception as e: - print(f"Warning: Could not initialize LED controls: {e}") - print("Creating dummy LED objects - visual feedback will be disabled") - # Create dummy LED objects that don't crash the app - class DummyLED: - def __init__(self, pin): - self.pin = pin - def on(self): - print(f"LED {self.pin} would turn ON") - def off(self): - print(f"LED {self.pin} would turn OFF") - +# Initialize LEDs – only when card reader is active +class DummyLED: + def __init__(self, pin): + self.pin = pin + def on(self): + pass + def off(self): + pass + +if CARD_PRESENCE_ENABLED: + try: + print("Initializing LED controls...") + led1 = OutputDevice(23) + led2 = OutputDevice(24) + print("✓ LED controls initialized successfully") + log_info_with_server("LED controls initialized") + except Exception as e: + print(f"Warning: Could not initialize LED controls: {e}") + print("Creating dummy LED objects - visual feedback will be disabled") + led1 = DummyLED(23) + led2 = DummyLED(24) + log_info_with_server("LED controls using dummy mode") +else: + print("🚫 Card presence disabled – LED controls skipped") led1 = DummyLED(23) led2 = DummyLED(24) - log_info_with_server("LED controls using dummy mode") # Initialize table name/ID print("Initializing device configuration...") @@ -1726,13 +1742,18 @@ def initialize_rfid_reader(): log_info_with_server("ERROR: RFID reader initialization failed") return None -# Start RFID reader -try: - rfid_reader = initialize_rfid_reader() - if rfid_reader is None: - print("WARNING: Application starting without RFID functionality") - print("Card reading will not work until RFID reader is properly configured") -except Exception as e: - print(f"Critical error initializing RFID reader: {e}") - log_info_with_server(f"Critical RFID error: {str(e)}") - print("Application will start but RFID functionality will be disabled") +# Start RFID reader only if card_presence is enabled +if CARD_PRESENCE_ENABLED: + try: + rfid_reader = initialize_rfid_reader() + if rfid_reader is None: + print("WARNING: Application starting without RFID functionality") + print("Card reading will not work until RFID reader is properly configured") + except Exception as e: + print(f"Critical error initializing RFID reader: {e}") + log_info_with_server(f"Critical RFID error: {str(e)}") + print("Application will start but RFID functionality will be disabled") +else: + rfid_reader = None + print("🚫 Card presence disabled – RFID reader NOT started") + log_info_with_server("Card presence is disabled – RFID reader skipped, running without card reader") diff --git a/config.py b/config.py index ef26ac3..af98232 100644 --- a/config.py +++ b/config.py @@ -47,6 +47,7 @@ def _read_config(): "hostname": p.get("device", "hostname", fallback=socket.gethostname()), "device_ip": p.get("device", "ip", fallback=_get_local_ip()), "location": p.get("device", "location", fallback=""), + "card_presence": p.get("device", "card_presence", fallback="enable"), "info_reviewed_at":p.get("device", "info_reviewed_at", fallback="1970-01-01T00:00:00"), # preserve other sections verbatim "chrome_url": p.get("chrome", "chrome_url", fallback=""), @@ -84,6 +85,7 @@ def _write_config(cfg): p.set("device", "hostname", cfg["hostname"]) p.set("device", "ip", cfg["device_ip"]) p.set("device", "location", cfg.get("location", "")) + p.set("device", "card_presence", cfg.get("card_presence", "enable")) p.set("device", "info_reviewed_at", cfg.get("info_reviewed_at", "1970-01-01T00:00:00")) # Bump last_synced → tells app.py local config is newer → push update request @@ -176,6 +178,12 @@ def main(): size=(INPUT_W, 1), tooltip="Physical location, e.g. Floor 2, Line A, Masa-01")], + [sg.Text("Card Presence", size=(LABEL_W, 1)), + sg.Combo(["enable", "disable"], + default_value=cfg.get("card_presence", "enable"), + key="-CARD_PRESENCE-", size=(INPUT_W - 2, 1), readonly=True, + tooltip="enable = card reader active; disable = no card reader")], + # ── Read-only system info ───────────────────────────────── [sg.HorizontalSeparator()], [sg.Text("── System Info (read-only) ──", font=("Arial Bold", 13), @@ -218,9 +226,10 @@ def main(): break if event == "-SAVE-": - new_hostname = values["-HOSTNAME-"].strip() - new_masa = values["-MASA-"].strip() - new_location = values["-LOCATION-"].strip() + new_hostname = values["-HOSTNAME-"].strip() + new_masa = values["-MASA-"].strip() + new_location = values["-LOCATION-"].strip() + new_card_presence = values["-CARD_PRESENCE-"] if not new_hostname or not new_masa: _show_result("Validation Error", @@ -228,10 +237,11 @@ def main(): continue # Update cfg dict with edited values - cfg["hostname"] = new_hostname - cfg["device_name"] = new_masa - cfg["location"] = new_location - cfg["device_ip"] = local_ip + cfg["hostname"] = new_hostname + cfg["device_name"] = new_masa + cfg["location"] = new_location + cfg["card_presence"] = new_card_presence + cfg["device_ip"] = local_ip # 1. Save config.txt (bumps last_synced → triggers server update request) try: