diff --git a/app.py b/app.py index f74a0a8..0138be2 100644 --- a/app.py +++ b/app.py @@ -140,15 +140,15 @@ def load_config(): """ config_path = "./data/config.txt" defaults = { - "chrome_url": "http://10.76.140.17/iweb_v2/index.php/traceability/production", + "chrome_url": "http://filesibiusb05.sibiusb.harting.intra/iweb_v2/index.php/traceability/production", "chrome_local_url": "", - "chrome_insecure_origin": "http://10.76.140.17", + "chrome_insecure_origin": "http://filesibiusb05.sibiusb.harting.intra", "card_post_base_url": "https://dataswsibiusb01.sibiusb.harting.intra/RO_Quality_PRD/api/record", "server_log_url": "http://rpi-ansible:80/logs", "update_host": "rpi-ansible", "update_user": "pi", - "internet_check_host": "10.76.140.17", - "device_name": "notconfig", + "internet_check_host": "filesibiusb05.sibiusb.harting.intra", + "work_place": "notconfig", "device_hostname": "unknown-device", "device_ip": "127.0.0.1", "device_location": "", @@ -188,9 +188,9 @@ def load_config(): if parser.has_section("device"): if parser.has_option("device", "work_place"): - cfg["device_name"] = parser.get("device", "work_place") + cfg["work_place"] = parser.get("device", "work_place") elif parser.has_option("device", "name"): - cfg["device_name"] = parser.get("device", "name") + cfg["work_place"] = parser.get("device", "name") if parser.has_option("device", "hostname"): cfg["device_hostname"] = parser.get("device", "hostname") if parser.has_option("device", "ip"): @@ -267,8 +267,22 @@ def _write_config_from_server(new_cfg): p.set("server", "internet_check_host", new_cfg.get("internet_check_host", "")) p.add_section("device") - p.set("device", "work_place", new_cfg.get("device_name", "notconfig")) - p.set("device", "hostname", new_cfg.get("hostname", "")) + # Only overwrite work_place if the server provides a non-empty value. + # This prevents a freshly migrated device from losing its idmasa-sourced + # work_place on first startup when the server doesn't know the device yet. + server_device_name = new_cfg.get("device_name", "").strip() + local_work_place = APP_CONFIG.get("work_place", "").strip() + effective_work_place = server_device_name if server_device_name else (local_work_place or "notconfig") + p.set("device", "work_place", effective_work_place) + # Same guard for hostname: prefer server value, fall back to OS hostname, + # then whatever was in local config. Never blank it. + server_hostname = new_cfg.get("hostname", "").strip() + if not server_hostname: + try: + server_hostname = socket.gethostname() + except Exception: + server_hostname = APP_CONFIG.get("device_hostname", "").strip() + p.set("device", "hostname", server_hostname) 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") @@ -363,7 +377,7 @@ def sync_config_with_server(): f"{server_base}/api/wmt/config/update_request", json={ "mac_address": mac, - "device_name": APP_CONFIG.get("device_name", ""), + "device_name": APP_CONFIG.get("work_place", ""), "hostname": _hostname, "device_ip": _ip, "client_config_mtime": last_synced_str, @@ -452,29 +466,118 @@ print("=" * 60) print("CONFIGURATION MODE DETECTION") print("=" * 60) + +def _try_autoconfigure_from_prezenta(): + """ + If work_place is still 'notconfig', look for the idmasa.txt left behind by + the migration playbook in Prezenta_Old_Data and use it to self-configure. + Updates config.txt and reloads APP_CONFIG. + Returns True if a valid work_place was found and written. + """ + global APP_CONFIG + idmasa_candidates = [ + "/home/pi/Desktop/Prezenta_Old_Data/data/idmasa.txt", + "/home/pi/Desktop/Prezenta_Old_Data/Files/idmasa.txt", + "/home/pi/Desktop/Prezenta/data/idmasa.txt", + "/home/pi/Desktop/Prezenta/Files/idmasa.txt", + ] + for path in idmasa_candidates: + if os.path.exists(path): + try: + with open(path, "r") as f: + value = f.read().strip() + if value and value.lower() != "notconfig": + print(f"✅ Auto-configure: found work_place='{value}' in {path}") + # Write into config.txt [device] section + import configparser as _cp + p = _cp.ConfigParser() + p.read("./data/config.txt") + if not p.has_section("device"): + p.add_section("device") + p.set("device", "work_place", value) + # Also capture real hostname/IP + try: + _hn = socket.gethostname() + _ip = socket.gethostbyname(_hn) + except Exception: + _hn = APP_CONFIG.get("device_hostname", "") + _ip = APP_CONFIG.get("device_ip", "") + p.set("device", "hostname", _hn) + p.set("device", "ip", _ip) + os.makedirs("./data", exist_ok=True) + with open("./data/config.txt", "w") as f: + f.write("# WMT Application Configuration\n") + f.write(f"# Auto-configured from {path}\n\n") + p.write(f) + APP_CONFIG = load_config() + print(f"✅ config.txt updated: work_place={value}, hostname={_hn}, ip={_ip}") + return True + except Exception as e: + print(f"Warning: could not read {path}: {e}") + return False + + +def _send_first_registration_log(): + """ + Send device info to the server immediately after auto-configuration so the + server record is created before the periodic sync runs. + """ + try: + import requests as _req + import urllib.parse as _up + parsed = _up.urlparse(APP_CONFIG.get("server_log_url", "http://rpi-ansible:80/logs")) + server_base = f"{parsed.scheme}://{parsed.netloc}" + mac = _get_mac_address() + try: + _hn = socket.gethostname() + _ip = socket.gethostbyname(_hn) + except Exception: + _hn = APP_CONFIG.get("device_hostname", "") + _ip = APP_CONFIG.get("device_ip", "") + _req.post( + f"{server_base}/api/wmt/config/update_request", + json={ + "mac_address": mac, + "device_name": APP_CONFIG.get("work_place", ""), + "hostname": _hn, + "device_ip": _ip, + "card_presence": APP_CONFIG.get("card_presence", "enable"), + "client_config_mtime": APP_CONFIG.get("last_synced", "1970-01-01T00:00:00"), + }, + timeout=5, + ) + print(f"✅ Registration sent to server (work_place={APP_CONFIG.get('work_place')}, hostname={_hn})") + except Exception as e: + print(f"Warning: could not send first registration to server: {e}") + + try: - name = APP_CONFIG.get("device_name", "noconfig") + name = APP_CONFIG.get("work_place", "noconfig") print(f"✓ Device name loaded: {name}") # Check if device is in configuration mode if name.lower() == "notconfig": print("🔧 Device configured for setup mode (notconfig)") - # Launch configuration mode - if early_launch_configuration_mode(): - print("🚀 Configuration mode active - application will run in setup mode") - print("⚠️ Network connectivity checks are DISABLED") - print("⚠️ Server status messages are DISABLED") - print("🔧 Change config.txt [device] name to exit configuration mode") - - # Set global flag for configuration mode - CONFIGURATION_MODE = True - - print("🔧 Configuration mode activated - continuing with RFID reader initialization") - print("🔧 Network and server monitoring will remain disabled") - else: - print("❌ Failed to launch configuration mode, continuing with normal operation") + # --- Try to self-configure from Prezenta_Old_Data before entering config mode --- + if _try_autoconfigure_from_prezenta(): + name = APP_CONFIG.get("work_place", "notconfig") + print(f"✅ Auto-configuration successful — work_place='{name}', skipping config mode") + _send_first_registration_log() CONFIGURATION_MODE = False + else: + # No idmasa.txt found — fall through to manual configuration mode + if early_launch_configuration_mode(): + print("🚀 Configuration mode active - application will run in setup mode") + print("⚠️ Network connectivity checks are DISABLED") + print("⚠️ Server status messages are DISABLED") + print("🔧 Change config.txt [device] name to exit configuration mode") + CONFIGURATION_MODE = True + print("🔧 Configuration mode activated - continuing with RFID reader initialization") + print("🔧 Network and server monitoring will remain disabled") + else: + print("❌ Failed to launch configuration mode, continuing with normal operation") + CONFIGURATION_MODE = False else: print("✅ Device in normal operation mode") CONFIGURATION_MODE = False @@ -529,7 +632,7 @@ def _ensure_printer(device_name): # Run auto-printer setup only when device has a real work_place -_auto_printer_name = APP_CONFIG.get("device_name", "notconfig") +_auto_printer_name = APP_CONFIG.get("work_place", "notconfig") if not CONFIGURATION_MODE and _auto_printer_name.lower() != "notconfig": _ensure_printer(_auto_printer_name) else: @@ -966,7 +1069,7 @@ def delete_old_logs(): # Function to read the work place name from config def read_name_from_file(): try: - n_masa = APP_CONFIG.get("device_name", "") + n_masa = APP_CONFIG.get("work_place", "") if n_masa: return n_masa except Exception: @@ -1381,7 +1484,7 @@ sudo reboot "chrome_url": APP_CONFIG.get("chrome_url"), "card_post_base_url": APP_CONFIG.get("card_post_base_url"), "server_log_url": APP_CONFIG.get("server_log_url"), - "device_name": APP_CONFIG.get("device_name"), + "device_name": APP_CONFIG.get("work_place"), }), 200 except Exception as e: return jsonify({"error": f"Failed to reload config: {str(e)}"}), 500 @@ -1496,7 +1599,7 @@ def post_backup_data(): # Function to check internet connection def check_internet_connection(): - hostname = APP_CONFIG.get("internet_check_host", "10.76.140.17") + hostname = APP_CONFIG.get("internet_check_host", "filesibiusb05.sibiusb.harting.intra") cmd_block_wifi = 'sudo rfkill block wifi' cmd_unblock_wifi = 'sudo rfkill unblock wifi' log_info_with_server('Internet connection check loaded') @@ -1529,8 +1632,8 @@ def check_internet_connection(): time.sleep(5) # Wait for processes to terminate # Relaunch Chromium - url = APP_CONFIG.get("chrome_url", "http://10.76.140.17/iweb_v2/index.php/traceability/production") - chrome_insecure = APP_CONFIG.get("chrome_insecure_origin", "http://10.76.140.17") + url = APP_CONFIG.get("chrome_url", "http://filesibiusb05.sibiusb.harting.intra/iweb_v2/index.php/traceability/production") + chrome_insecure = APP_CONFIG.get("chrome_insecure_origin", "http://filesibiusb05.sibiusb.harting.intra") subprocess.Popen( ["chromium", "--test-type", "--noerrors", "--kiosk", "--start-fullscreen", f"--unsafely-treat-insecure-origin-as-secure={chrome_insecure}", url], @@ -1551,10 +1654,50 @@ if not CONFIGURATION_MODE: else: print("🔧 Configuration mode: Internet connectivity monitoring DISABLED") +# --------------------------------------------------------------------------- +# Periodic server config sync (background thread) +# --------------------------------------------------------------------------- + +def _periodic_config_sync(): + """ + Background thread: re-checks the server for config updates every 5 minutes. + When a new config is pulled, Chromium is restarted with the updated URLs. + """ + sync_interval = 300 # seconds (5 minutes) + while True: + time.sleep(sync_interval) + try: + config_changed = sync_config_with_server() + if config_changed and not CONFIGURATION_MODE: + print("🔄 Config changed – restarting Chromium with updated settings.") + try: + subprocess.run(["pkill", "-f", "chromium"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + time.sleep(5) + _url = APP_CONFIG.get("chrome_url", "") + _insecure = APP_CONFIG.get("chrome_insecure_origin", "") + subprocess.Popen( + ["chromium", "--test-type", "--noerrors", "--kiosk", "--start-fullscreen", + f"--unsafely-treat-insecure-origin-as-secure={_insecure}", _url], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, + stdin=subprocess.DEVNULL, start_new_session=True + ) + print("✅ Chromium restarted with new config.") + except Exception as e: + print(f"Warning: Could not restart Chromium after config update: {e}") + except Exception as e: + print(f"Periodic config sync error: {e}") + +if not CONFIGURATION_MODE: + _sync_thread = threading.Thread(target=_periodic_config_sync, daemon=True, name="config-sync") + _sync_thread.start() + print("✅ Periodic server config sync started (every 5 min)") +else: + print("🔧 Configuration mode: Periodic config sync DISABLED") + # Launch Chromium with the specified URLs (only if not in configuration mode) if not CONFIGURATION_MODE: - url = APP_CONFIG.get("chrome_url", "http://10.76.140.17/iweb_v2/index.php/traceability/production") - chrome_insecure = APP_CONFIG.get("chrome_insecure_origin", "http://10.76.140.17") + url = APP_CONFIG.get("chrome_url", "http://filesibiusb05.sibiusb.harting.intra/iweb_v2/index.php/traceability/production") + chrome_insecure = APP_CONFIG.get("chrome_insecure_origin", "http://filesibiusb05.sibiusb.harting.intra") subprocess.Popen(["chromium", "--test-type", "--noerrors", "--kiosk", "--start-fullscreen", f"--unsafely-treat-insecure-origin-as-secure={chrome_insecure}", url], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL, start_new_session=True) print("✅ Main application browser launched") else: @@ -1648,7 +1791,7 @@ else: # Initialize table name/ID print("Initializing device configuration...") -name = APP_CONFIG.get("device_name", "noconfig") +name = APP_CONFIG.get("work_place", "noconfig") logging.info("LED controls initialized") logging.info("Variabila Id Masa A fost initializata ")