Add .gitignore, update app.py and config.py, remove stale docs
This commit is contained in:
472
app.py
472
app.py
@@ -129,8 +129,258 @@ except ImportError as e:
|
||||
def jsonify(data):
|
||||
return data
|
||||
|
||||
import configparser
|
||||
import json
|
||||
|
||||
|
||||
def load_config():
|
||||
"""
|
||||
Load application configuration from data/config.txt (INI format).
|
||||
Falls back to legacy file (device_info.txt) and hardcoded defaults.
|
||||
"""
|
||||
config_path = "./data/config.txt"
|
||||
defaults = {
|
||||
"chrome_url": "http://10.76.140.17/iweb_v2/index.php/traceability/production",
|
||||
"chrome_local_url": "",
|
||||
"chrome_insecure_origin": "http://10.76.140.17",
|
||||
"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",
|
||||
"device_hostname": "unknown-device",
|
||||
"device_ip": "127.0.0.1",
|
||||
"device_location": "",
|
||||
"device_info_reviewed_at": "1970-01-01T00:00:00",
|
||||
"last_synced": "1970-01-01T00:00:00",
|
||||
}
|
||||
|
||||
cfg = dict(defaults)
|
||||
parser = configparser.ConfigParser()
|
||||
|
||||
if os.path.exists(config_path):
|
||||
try:
|
||||
parser.read(config_path)
|
||||
|
||||
if parser.has_section("chrome"):
|
||||
if parser.has_option("chrome", "chrome_url"):
|
||||
cfg["chrome_url"] = parser.get("chrome", "chrome_url")
|
||||
if parser.has_option("chrome", "chrome_local_url"):
|
||||
cfg["chrome_local_url"] = parser.get("chrome", "chrome_local_url")
|
||||
if parser.has_option("chrome", "chrome_insecure_origin"):
|
||||
cfg["chrome_insecure_origin"] = parser.get("chrome", "chrome_insecure_origin")
|
||||
|
||||
if parser.has_section("card_api"):
|
||||
if parser.has_option("card_api", "base_url"):
|
||||
cfg["card_post_base_url"] = parser.get("card_api", "base_url")
|
||||
|
||||
if parser.has_section("server"):
|
||||
if parser.has_option("server", "log_url"):
|
||||
cfg["server_log_url"] = parser.get("server", "log_url")
|
||||
if parser.has_option("server", "update_host"):
|
||||
cfg["update_host"] = parser.get("server", "update_host")
|
||||
if parser.has_option("server", "update_user"):
|
||||
cfg["update_user"] = parser.get("server", "update_user")
|
||||
if parser.has_option("server", "internet_check_host"):
|
||||
cfg["internet_check_host"] = parser.get("server", "internet_check_host")
|
||||
|
||||
if parser.has_section("device"):
|
||||
if parser.has_option("device", "work_place"):
|
||||
cfg["device_name"] = parser.get("device", "work_place")
|
||||
elif parser.has_option("device", "name"):
|
||||
cfg["device_name"] = parser.get("device", "name")
|
||||
if parser.has_option("device", "hostname"):
|
||||
cfg["device_hostname"] = parser.get("device", "hostname")
|
||||
if parser.has_option("device", "ip"):
|
||||
cfg["device_ip"] = parser.get("device", "ip")
|
||||
if parser.has_option("device", "info_reviewed_at"):
|
||||
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_section("meta"):
|
||||
if parser.has_option("meta", "last_synced"):
|
||||
cfg["last_synced"] = parser.get("meta", "last_synced")
|
||||
|
||||
print(f"\u2713 Configuration loaded from {config_path}")
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not parse {config_path}: {e}. Using defaults.")
|
||||
else:
|
||||
# Fall back to legacy individual files
|
||||
try:
|
||||
with open("./data/device_info.txt", "r") as f:
|
||||
lines = f.read().strip().split('\n')
|
||||
if len(lines) >= 1 and lines[0].strip():
|
||||
cfg["device_hostname"] = lines[0].strip()
|
||||
if len(lines) >= 2 and lines[1].strip():
|
||||
cfg["device_ip"] = lines[1].strip()
|
||||
except Exception:
|
||||
pass
|
||||
print("config.txt not found - using legacy files and defaults")
|
||||
|
||||
return cfg
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Server config sync (runs once at startup)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _get_mac_address():
|
||||
"""Return the MAC address of the primary network interface."""
|
||||
for iface in ['eth0', 'wlan0', 'eth1']:
|
||||
mac_path = f'/sys/class/net/{iface}/address'
|
||||
try:
|
||||
if os.path.exists(mac_path):
|
||||
with open(mac_path) as f:
|
||||
mac = f.read().strip()
|
||||
if mac and mac != '00:00:00:00:00:00':
|
||||
return mac
|
||||
except Exception:
|
||||
continue
|
||||
# Fallback: derive from UUID node
|
||||
import uuid as _uuid
|
||||
raw = _uuid.getnode()
|
||||
return ':'.join(f'{(raw >> i) & 0xff:02x}' for i in range(40, -1, -8))
|
||||
|
||||
|
||||
def _write_config_from_server(new_cfg):
|
||||
"""Overwrite data/config.txt with config received from the server."""
|
||||
import configparser as _cp
|
||||
p = _cp.ConfigParser()
|
||||
|
||||
p.add_section("chrome")
|
||||
p.set("chrome", "chrome_url", new_cfg.get("chrome_url", ""))
|
||||
p.set("chrome", "chrome_local_url", new_cfg.get("chrome_local_url", ""))
|
||||
p.set("chrome", "chrome_insecure_origin", new_cfg.get("chrome_insecure_origin", ""))
|
||||
|
||||
p.add_section("card_api")
|
||||
p.set("card_api", "base_url", new_cfg.get("card_api_base_url", ""))
|
||||
|
||||
p.add_section("server")
|
||||
p.set("server", "log_url", new_cfg.get("server_log_url", ""))
|
||||
p.set("server", "update_host", new_cfg.get("update_host", ""))
|
||||
p.set("server", "update_user", new_cfg.get("update_user", ""))
|
||||
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", ""))
|
||||
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.add_section("meta")
|
||||
sync_ts = new_cfg.get("config_updated_at") or datetime.now().isoformat()
|
||||
p.set("meta", "last_synced", sync_ts)
|
||||
|
||||
os.makedirs("./data", exist_ok=True)
|
||||
with open("./data/config.txt", "w") as f:
|
||||
f.write("# WMT Application Configuration\n")
|
||||
f.write(f"# Synced from server: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
|
||||
p.write(f)
|
||||
print(f"\u2713 config.txt written from server (server ts: {sync_ts})")
|
||||
|
||||
|
||||
def sync_config_with_server():
|
||||
"""
|
||||
Called once at startup.
|
||||
- Derives base URL from server_log_url in APP_CONFIG.
|
||||
- If server config is newer than last_synced → pull and overwrite config.txt, reload APP_CONFIG.
|
||||
- Otherwise → send a device-info update request to the server.
|
||||
Returns True if config was pulled from server.
|
||||
"""
|
||||
global APP_CONFIG
|
||||
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()
|
||||
|
||||
last_synced_str = APP_CONFIG.get("last_synced", "1970-01-01T00:00:00")
|
||||
try:
|
||||
last_synced = datetime.fromisoformat(last_synced_str)
|
||||
except Exception:
|
||||
last_synced = datetime(1970, 1, 1)
|
||||
|
||||
local_info_reviewed_str = APP_CONFIG.get("device_info_reviewed_at", "1970-01-01T00:00:00")
|
||||
try:
|
||||
local_info_reviewed = datetime.fromisoformat(local_info_reviewed_str)
|
||||
except Exception:
|
||||
local_info_reviewed = datetime(1970, 1, 1)
|
||||
|
||||
print(f"Checking server config (MAC={mac}, last_synced={last_synced_str}, info_reviewed_at={local_info_reviewed_str}) ...")
|
||||
|
||||
# --- Step 1: get server timestamp ---
|
||||
ts_resp = _req.get(
|
||||
f"{server_base}/api/wmt/config/timestamp",
|
||||
params={"mac": mac}, timeout=5
|
||||
)
|
||||
ts_resp.raise_for_status()
|
||||
ts_data = ts_resp.json()
|
||||
|
||||
server_ts_str = ts_data.get("latest_updated_at", "1970-01-01T00:00:00")
|
||||
try:
|
||||
server_ts = datetime.fromisoformat(server_ts_str)
|
||||
except Exception:
|
||||
server_ts = datetime(1970, 1, 1)
|
||||
|
||||
server_info_reviewed_str = ts_data.get("device_info_reviewed_at") or "1970-01-01T00:00:00"
|
||||
try:
|
||||
server_info_reviewed = datetime.fromisoformat(server_info_reviewed_str)
|
||||
except Exception:
|
||||
server_info_reviewed = datetime(1970, 1, 1)
|
||||
|
||||
# Pull if global settings are newer OR if admin has reviewed device info more recently
|
||||
needs_pull = server_ts > last_synced or server_info_reviewed > local_info_reviewed
|
||||
|
||||
if needs_pull:
|
||||
# --- Step 2a: pull config ---
|
||||
print(f"Server config is newer ({server_ts_str}), pulling ...")
|
||||
cfg_resp = _req.get(f"{server_base}/api/wmt/config/{mac}", timeout=5)
|
||||
cfg_resp.raise_for_status()
|
||||
_write_config_from_server(cfg_resp.json())
|
||||
APP_CONFIG = load_config()
|
||||
print("\u2705 Config synced from server.")
|
||||
return True
|
||||
else:
|
||||
# --- Step 2b: push device info ---
|
||||
print("Local config is current, sending device info to server ...")
|
||||
try:
|
||||
_hostname = socket.gethostname()
|
||||
_ip = socket.gethostbyname(_hostname)
|
||||
except Exception:
|
||||
_hostname = 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("device_name", ""),
|
||||
"hostname": _hostname,
|
||||
"device_ip": _ip,
|
||||
"client_config_mtime": last_synced_str,
|
||||
"client_info_reviewed_at": local_info_reviewed_str,
|
||||
},
|
||||
timeout=5,
|
||||
)
|
||||
print("\u2705 Device info update request sent.")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"Config sync skipped (server unreachable or error): {e}")
|
||||
return False
|
||||
|
||||
|
||||
# Load global application configuration
|
||||
APP_CONFIG = load_config()
|
||||
|
||||
# Attempt to sync with server at startup (non-blocking – failures are logged and ignored)
|
||||
sync_config_with_server()
|
||||
|
||||
# Early configuration mode detection (before heavy initialization)
|
||||
def early_launch_configuration_mode():
|
||||
"""
|
||||
@@ -139,21 +389,23 @@ def early_launch_configuration_mode():
|
||||
try:
|
||||
print("🔧 Configuration mode detected - launching Screen.html in Chromium")
|
||||
|
||||
# Get absolute path to Screen.html
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
screen_html_path = os.path.join(current_dir, "Files", "Screen.html")
|
||||
|
||||
# Path to Screen.html relative to the WMT working directory
|
||||
screen_html_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Files", "Screen.html")
|
||||
screen_html_relative = "./Files/Screen.html"
|
||||
if os.path.exists(screen_html_relative):
|
||||
screen_html_path = os.path.abspath(screen_html_relative)
|
||||
|
||||
if not os.path.exists(screen_html_path):
|
||||
print(f"❌ Screen.html not found at: {screen_html_path}")
|
||||
return False
|
||||
|
||||
print(f"📄 Loading Screen.html from: {screen_html_path}")
|
||||
|
||||
|
||||
# Terminate any existing Chromium processes
|
||||
chromium_process_name = "chromium"
|
||||
# Local log only in configuration mode
|
||||
logging.info("Refreshing Chromium process (configuration mode)")
|
||||
# Local log only in configuration mode
|
||||
logging.info("Refreshing Chromium process (configuration mode)")
|
||||
|
||||
try:
|
||||
subprocess.run(["pkill", "-f", chromium_process_name], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
time.sleep(5) # Wait for processes to terminate
|
||||
@@ -168,11 +420,12 @@ def early_launch_configuration_mode():
|
||||
except Exception as e:
|
||||
logging.error(f"Failed to refresh Chromium process (configuration mode): {e}")
|
||||
return False
|
||||
|
||||
print("✅ Configuration mode launched successfully")
|
||||
print("ℹ️ Network connectivity checks disabled")
|
||||
print("ℹ️ Server status messages disabled")
|
||||
print("🔧 Device running in configuration mode")
|
||||
print("🔧 To exit configuration mode, change idmasa.txt content to device name")
|
||||
print("🔧 To exit configuration mode, change work_place in config.txt")
|
||||
return True
|
||||
|
||||
except FileNotFoundError:
|
||||
@@ -189,24 +442,23 @@ print("CONFIGURATION MODE DETECTION")
|
||||
print("=" * 60)
|
||||
|
||||
try:
|
||||
with open("./data/idmasa.txt", "r") as f:
|
||||
name = f.readline().strip() or "noconfig"
|
||||
name = APP_CONFIG.get("device_name", "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 idmasa.txt to device name to exit configuration mode")
|
||||
|
||||
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:
|
||||
@@ -215,21 +467,9 @@ try:
|
||||
else:
|
||||
print("✅ Device in normal operation mode")
|
||||
CONFIGURATION_MODE = False
|
||||
|
||||
except FileNotFoundError:
|
||||
print("Warning: idmasa.txt not found, using default 'noconfig'")
|
||||
name = "noconfig"
|
||||
CONFIGURATION_MODE = False
|
||||
# Create the file with default value
|
||||
try:
|
||||
os.makedirs("./data", exist_ok=True)
|
||||
with open("./data/idmasa.txt", "w") as f:
|
||||
f.write("noconfig")
|
||||
print("✓ Created default idmasa.txt file")
|
||||
except Exception as e:
|
||||
print(f"Could not create idmasa.txt: {e}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error reading idmasa.txt: {e}")
|
||||
print(f"Error in configuration mode detection: {e}")
|
||||
name = "noconfig"
|
||||
CONFIGURATION_MODE = False
|
||||
|
||||
@@ -305,7 +545,6 @@ def check_system_requirements():
|
||||
|
||||
# 2. Check required files and create defaults if missing
|
||||
required_files = {
|
||||
'./data/idmasa.txt': 'noconfig',
|
||||
'./data/log.txt': '',
|
||||
'./data/tag.txt': '',
|
||||
'./data/device_info.txt': 'unknown-device\n127.0.0.1\n'
|
||||
@@ -609,11 +848,23 @@ def get_device_info():
|
||||
except Exception as file_error:
|
||||
print(f"Could not load from file: {file_error}")
|
||||
|
||||
# Final fallback if everything fails
|
||||
# Final fallback: use values from APP_CONFIG (config.txt [device] section)
|
||||
try:
|
||||
cfg_hostname = APP_CONFIG.get("device_hostname", "")
|
||||
cfg_ip = APP_CONFIG.get("device_ip", "")
|
||||
if cfg_hostname and cfg_hostname != "unknown-device":
|
||||
hostname = cfg_hostname
|
||||
device_ip = cfg_ip or "127.0.0.1"
|
||||
print(f"Loaded from config.txt - Hostname: {hostname}, IP: {device_ip}")
|
||||
return hostname, device_ip
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Absolute last resort defaults
|
||||
print("All methods failed - Using default values")
|
||||
hostname = hostname or "unknown-device"
|
||||
device_ip = "127.0.0.1"
|
||||
|
||||
|
||||
# Try to save these default values for next time
|
||||
try:
|
||||
os.makedirs("./data", exist_ok=True)
|
||||
@@ -622,7 +873,7 @@ def get_device_info():
|
||||
print(f"Saved fallback values to {config_file}")
|
||||
except Exception as e:
|
||||
print(f"Could not save fallback values: {e}")
|
||||
|
||||
|
||||
return hostname, device_ip
|
||||
|
||||
# Perform system initialization (first run setup)
|
||||
@@ -652,29 +903,42 @@ def delete_old_logs():
|
||||
else:
|
||||
log_info_with_server(f"Log file does not exist: {log_file}")
|
||||
|
||||
# Function to read the name (idmasa) from the file
|
||||
# Function to read the work place name from config
|
||||
def read_name_from_file():
|
||||
try:
|
||||
with open("./data/idmasa.txt", "r") as file:
|
||||
n_masa = file.readline().strip()
|
||||
n_masa = APP_CONFIG.get("device_name", "")
|
||||
if n_masa:
|
||||
return n_masa
|
||||
except FileNotFoundError:
|
||||
logging.error("File ./data/idmasa.txt not found.")
|
||||
return "unknown"
|
||||
except Exception:
|
||||
pass
|
||||
return "unknown"
|
||||
|
||||
def _get_os_version() -> str:
|
||||
"""Read OS pretty-name from /etc/os-release (Raspberry Pi OS, etc.)."""
|
||||
try:
|
||||
with open("/etc/os-release") as f:
|
||||
for line in f:
|
||||
if line.startswith("PRETTY_NAME="):
|
||||
return line.split("=", 1)[1].strip().strip('"')
|
||||
except Exception:
|
||||
pass
|
||||
return ""
|
||||
|
||||
# Function to send logs to a remote server for the Server_monitorizare APP
|
||||
def send_log_to_server(log_message, n_masa, hostname, device_ip):
|
||||
host = hostname
|
||||
device = device_ip
|
||||
try:
|
||||
|
||||
log_data = {
|
||||
"hostname": str(host),
|
||||
"device_ip": str(device),
|
||||
"hostname": str(hostname),
|
||||
"device_ip": str(device_ip),
|
||||
"nume_masa": str(n_masa),
|
||||
"log_message": str(log_message)
|
||||
"log_message": str(log_message),
|
||||
# Device metadata – keeps the server record up to date automatically
|
||||
"device_type": "Raspberry Pi",
|
||||
"os_version": _get_os_version(),
|
||||
"location": APP_CONFIG.get("device_location", ""),
|
||||
"mac_address": _get_mac_address(),
|
||||
}
|
||||
server_url = "http://rpi-ansible:80/logs" # Replace with your server's URL
|
||||
server_url = APP_CONFIG.get("server_log_url", "http://rpi-ansible:80/logs")
|
||||
print(log_data) # Debugging: Print log_data to verify its contents
|
||||
response = requests.post(server_url, json=log_data, timeout=5)
|
||||
response.raise_for_status()
|
||||
@@ -683,7 +947,7 @@ def send_log_to_server(log_message, n_masa, hostname, device_ip):
|
||||
logging.error("Failed to send log to server: %s", e)
|
||||
# Wrapper for logging.info to also send logs to the server Monitorizare APP
|
||||
def log_info_with_server(message):
|
||||
n_masa = read_name_from_file() # Read name (idmasa) from the file
|
||||
n_masa = read_name_from_file() # Read work place name from config
|
||||
formatted_message = f"{message} (n_masa: {n_masa})" # Format the message
|
||||
logging.info(formatted_message) # Log the formatted message
|
||||
|
||||
@@ -706,6 +970,7 @@ def execute_system_command(command):
|
||||
allowed_commands = [
|
||||
"sudo apt update",
|
||||
"sudo apt upgrade -y",
|
||||
"sudo apt update && sudo apt upgrade -y", # Combined update and upgrade
|
||||
"sudo apt autoremove -y",
|
||||
"sudo apt autoclean",
|
||||
"sudo reboot",
|
||||
@@ -811,9 +1076,9 @@ if FLASK_AVAILABLE:
|
||||
Checks version, downloads newer files if available, and restarts the device
|
||||
"""
|
||||
try:
|
||||
# Configuration
|
||||
SERVER_HOST = "rpi-ansible"
|
||||
SERVER_USER = "pi"
|
||||
# Configuration (read from APP_CONFIG, falling back to hardcoded defaults)
|
||||
SERVER_HOST = APP_CONFIG.get("update_host", "rpi-ansible")
|
||||
SERVER_USER = APP_CONFIG.get("update_user", "pi")
|
||||
SERVER_PASSWORD = "Initial01!"
|
||||
SERVER_APP_PATH = "/home/pi/Desktop/prezenta/app.py"
|
||||
SERVER_REPO_PATH = "/home/pi/Desktop/prezenta/Files/reposytory"
|
||||
@@ -990,6 +1255,76 @@ sudo reboot
|
||||
except:
|
||||
pass
|
||||
|
||||
@command_app.route('/update_config', methods=['POST'])
|
||||
def update_config_endpoint():
|
||||
"""
|
||||
Update configuration from Server_Monitorizare_v2.
|
||||
Accepts a JSON body with sections matching config.txt structure.
|
||||
Example body: {"chrome": {"chrome_url": "http://..."}}
|
||||
"""
|
||||
global APP_CONFIG
|
||||
|
||||
ALLOWED_SECTIONS = {
|
||||
"chrome": ["chrome_url", "chrome_local_url", "chrome_insecure_origin"],
|
||||
"card_api": ["base_url"],
|
||||
"server": ["log_url", "update_host", "update_user", "internet_check_host"],
|
||||
"device": ["name", "hostname", "ip"],
|
||||
}
|
||||
|
||||
try:
|
||||
data = request.json
|
||||
if not data:
|
||||
return jsonify({"error": "JSON body required"}), 400
|
||||
|
||||
config_path = "./data/config.txt"
|
||||
parser = configparser.ConfigParser()
|
||||
if os.path.exists(config_path):
|
||||
parser.read(config_path)
|
||||
|
||||
updated_keys = []
|
||||
for section, allowed_keys in ALLOWED_SECTIONS.items():
|
||||
if section in data and isinstance(data[section], dict):
|
||||
if not parser.has_section(section):
|
||||
parser.add_section(section)
|
||||
for key in allowed_keys:
|
||||
if key in data[section]:
|
||||
parser.set(section, key, str(data[section][key]))
|
||||
updated_keys.append(f"{section}.{key}")
|
||||
|
||||
os.makedirs("./data", exist_ok=True)
|
||||
with open(config_path, "w") as f:
|
||||
f.write("# WMT Application Configuration\n")
|
||||
f.write(f"# Last updated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
|
||||
parser.write(f)
|
||||
|
||||
APP_CONFIG = load_config()
|
||||
log_info_with_server(f"Configuration updated via API: {updated_keys}")
|
||||
return jsonify({"status": "success", "updated_keys": updated_keys}), 200
|
||||
|
||||
except Exception as e:
|
||||
log_info_with_server(f"Error updating config: {str(e)}")
|
||||
return jsonify({"error": f"Failed to update configuration: {str(e)}"}), 500
|
||||
|
||||
@command_app.route('/reload_config', methods=['POST'])
|
||||
def reload_config_endpoint():
|
||||
"""
|
||||
Reload configuration from data/config.txt into memory without restarting.
|
||||
"""
|
||||
global APP_CONFIG
|
||||
try:
|
||||
APP_CONFIG = load_config()
|
||||
log_info_with_server("Configuration reloaded via API")
|
||||
return jsonify({
|
||||
"status": "success",
|
||||
"message": "Configuration reloaded",
|
||||
"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"),
|
||||
}), 200
|
||||
except Exception as e:
|
||||
return jsonify({"error": f"Failed to reload config: {str(e)}"}), 500
|
||||
|
||||
def start_command_server():
|
||||
"""
|
||||
Start the Flask server with enhanced port handling and fallback
|
||||
@@ -1100,7 +1435,7 @@ def post_backup_data():
|
||||
|
||||
# Function to check internet connection
|
||||
def check_internet_connection():
|
||||
hostname = "10.76.140.17"
|
||||
hostname = APP_CONFIG.get("internet_check_host", "10.76.140.17")
|
||||
cmd_block_wifi = 'sudo rfkill block wifi'
|
||||
cmd_unblock_wifi = 'sudo rfkill unblock wifi'
|
||||
log_info_with_server('Internet connection check loaded')
|
||||
@@ -1133,10 +1468,11 @@ def check_internet_connection():
|
||||
time.sleep(5) # Wait for processes to terminate
|
||||
|
||||
# Relaunch Chromium
|
||||
url = "10.76.140.17/iweb_v2/index.php/traceability/production"
|
||||
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")
|
||||
subprocess.Popen(
|
||||
["chromium", "--test-type", "--noerrors", "--kiosk", "--start-fullscreen",
|
||||
"--unsafely-treat-insecure-origin-as-secure=http://10.76.140.17", url],
|
||||
["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
|
||||
)
|
||||
log_info_with_server("Chromium process restarted successfully.")
|
||||
@@ -1156,8 +1492,9 @@ else:
|
||||
|
||||
# Launch Chromium with the specified URLs (only if not in configuration mode)
|
||||
if not CONFIGURATION_MODE:
|
||||
url = "10.76.140.17/iweb_v2/index.php/traceability/production" # pentru cazul in care raspberiul nu are sistem de prezenta
|
||||
subprocess.Popen(["chromium", "--test-type", "--noerrors", "--kiosk", "--start-fullscreen", "--unsafely-treat-insecure-origin-as-secure=http://10.76.140.17", url], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL, start_new_session=True)
|
||||
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")
|
||||
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:
|
||||
print("🔧 Configuration mode: Main application browser launch DISABLED")
|
||||
@@ -1246,23 +1583,14 @@ except Exception as e:
|
||||
|
||||
# Initialize table name/ID
|
||||
print("Initializing device configuration...")
|
||||
name = "idmasa"
|
||||
name = APP_CONFIG.get("device_name", "noconfig")
|
||||
logging.info("LED controls initialized")
|
||||
|
||||
logging.info("Variabila Id Masa A fost initializata ")
|
||||
|
||||
# Device name is already loaded during early configuration detection
|
||||
# Use the existing name variable or reload if needed
|
||||
if 'name' not in globals():
|
||||
try:
|
||||
with open("./data/idmasa.txt", "r") as f:
|
||||
name = f.readline().strip() or "noconfig"
|
||||
print(f"✓ Device name reloaded: {name}")
|
||||
if not CONFIGURATION_MODE:
|
||||
log_info_with_server(f"Device name initialized: {name}")
|
||||
except Exception as e:
|
||||
print(f"Error reloading device name: {e}")
|
||||
name = "noconfig"
|
||||
print(f"✓ Device name set from config: {name}")
|
||||
if not CONFIGURATION_MODE:
|
||||
log_info_with_server(f"Device name initialized: {name}")
|
||||
|
||||
logging.info(name)
|
||||
#clasa reader
|
||||
@@ -1275,7 +1603,8 @@ class Reader(rdm6300.BaseReader):
|
||||
return
|
||||
|
||||
afisare = time.strftime("%Y-%m-%d&%H:%M:%S")
|
||||
date = f'https://dataswsibiusb01.sibiusb.harting.intra/RO_Quality_PRD/api/record/{name}/{card.value}/1/{afisare}\n'
|
||||
_base = APP_CONFIG.get("card_post_base_url", "https://dataswsibiusb01.sibiusb.harting.intra/RO_Quality_PRD/api/record")
|
||||
date = f'{_base}/{name}/{card.value}/1/{afisare}\n'
|
||||
info = date
|
||||
if name == "noconfig":
|
||||
led1.on()
|
||||
@@ -1294,7 +1623,8 @@ class Reader(rdm6300.BaseReader):
|
||||
return
|
||||
|
||||
afisare = time.strftime("%Y-%m-%d&%H:%M:%S")
|
||||
date = f'https://dataswsibiusb01.sibiusb.harting.intra/RO_Quality_PRD/api/record/{name}/{card.value}/0/{afisare}\n'
|
||||
_base = APP_CONFIG.get("card_post_base_url", "https://dataswsibiusb01.sibiusb.harting.intra/RO_Quality_PRD/api/record")
|
||||
date = f'{_base}/{name}/{card.value}/0/{afisare}\n'
|
||||
info = date
|
||||
if name == "noconfig":
|
||||
led1.off()
|
||||
|
||||
Reference in New Issue
Block a user