Implement dual logging workflow: noconfig vs configured mode

NOCONFIG MODE (device not configured):
- Sends 'App initialized' message on startup
- Sends 'RFID initialized' message after RFID ready
- Sends 'App working' message on startup
- Sends periodic 'App working' health status every 5 minutes
- Card inserted/removed events sent directly to monitoring server

CONFIGURED MODE (table ID set):
- Sends 'App initialized' and startup messages
- Card events POST to Harting API first
- Only sends to monitoring server on successful API post
- Failed posts saved to tag.txt backup file
- Backup data sent with summary when internet restored

Changes:
- Added send_health_status() function for periodic monitoring
- Updated process_card_events() to handle both workflows
- Updated main() to send startup messages and start health monitor
- Improved monitoring server URL to use rpi-ansible hostname
- Added retry logic for monitoring server requests
This commit is contained in:
RPI User
2025-12-19 15:08:02 +02:00
parent f82424cffb
commit e0f7ec34f2
3 changed files with 163 additions and 16 deletions

101
app.py
View File

@@ -24,7 +24,7 @@ import rdm6300
# ============================================================================
# Server URLs
MONITORING_SERVER = "http://192.168.1.103:80/logs"
MONITORING_SERVER = "http://rpi-ansible:80/logs"
HARTING_API_BASE = "https://dataswsibiusb01.sibiusb.harting.intra/RO_Quality_PRD/api/record"
WIFI_CHECK_HOST = "10.76.140.17"
@@ -139,7 +139,7 @@ def read_idmasa():
return "noconfig"
def send_log_to_server(message, hostname, device_ip, name):
"""Send log message to monitoring server"""
"""Send log message to monitoring server with retry logic"""
try:
log_data = {
"hostname": hostname,
@@ -147,11 +147,36 @@ def send_log_to_server(message, hostname, device_ip, name):
"nume_masa": name,
"log_message": message
}
response = requests.post(MONITORING_SERVER, json=log_data, timeout=5)
response.raise_for_status()
return True
logging.debug(f"[LOG] Sending to {MONITORING_SERVER}: {log_data}")
print(f"[LOG] Sending: {log_data}")
# Try up to 3 times with small delay
for attempt in range(3):
try:
response = requests.post(MONITORING_SERVER, json=log_data, timeout=5)
response.raise_for_status()
logging.info(f"✓ Log sent to server: {message}")
print(f"✓ Log sent successfully")
return True
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as e:
if attempt < 2:
time.sleep(1) # Wait 1 second before retry
continue
raise
return False
except requests.exceptions.Timeout:
logging.warning(f"✗ Log request timeout after retries: {message}")
print(f"✗ Timeout sending log")
return False
except requests.exceptions.ConnectionError as e:
logging.warning(f"✗ Connection error sending log: {e}")
print(f"✗ Connection error: {e}")
return False
except Exception as e:
logging.warning(f"Failed to send log to server: {e}")
logging.warning(f"Failed to send log to server: {e}")
print(f"✗ Failed to send log: {e}")
return False
def post_to_harting(url, verify=False, timeout=3):
@@ -336,17 +361,24 @@ class RFIDReader(rdm6300.BaseReader):
def process_card_events(hostname, device_ip):
"""Main thread checks card flags and processes them"""
name = read_idmasa()
while True:
try:
# Re-read name each time to catch configuration changes
name = read_idmasa()
# Check for inserted cards
card_id, timestamp = card_state.get_inserted()
if card_id is not None:
logging.info(f"[Main] Processing CARD INSERTED: {card_id}")
# Skip posting to Harting API if device is not configured
if name != "noconfig":
if name == "noconfig":
# NOCONFIG MODE: Send card event directly to monitoring server
message = f"Card {card_id} inserted"
send_log_to_server(message, hostname, device_ip, name)
logging.info(f"✓ Card insert logged to monitoring: {message}")
else:
# CONFIGURED MODE: Try to post to Harting API first
# Build API URL (1 = ON/inserted)
url = f"{HARTING_API_BASE}/{name}/{card_id}/1/{timestamp}"
@@ -362,16 +394,19 @@ def process_card_events(hostname, device_ip):
f.write(url + "\n")
except Exception as e:
logging.error(f"Failed to save backup: {e}")
else:
logging.debug(f"Device not configured (noconfig). Skipping API post for card {card_id}")
# Check for removed cards
card_id, timestamp = card_state.get_removed()
if card_id is not None:
logging.info(f"[Main] Processing CARD REMOVED: {card_id}")
# Skip posting to Harting API if device is not configured
if name != "noconfig":
if name == "noconfig":
# NOCONFIG MODE: Send card event directly to monitoring server
message = f"Card {card_id} removed"
send_log_to_server(message, hostname, device_ip, name)
logging.info(f"✓ Card remove logged to monitoring: {message}")
else:
# CONFIGURED MODE: Try to post to Harting API first
# Build API URL (0 = OFF/removed)
url = f"{HARTING_API_BASE}/{name}/{card_id}/0/{timestamp}"
@@ -387,8 +422,6 @@ def process_card_events(hostname, device_ip):
f.write(url + "\n")
except Exception as e:
logging.error(f"Failed to save backup: {e}")
else:
logging.debug(f"Device not configured (noconfig). Skipping API post for card {card_id}")
# Very small sleep for fast response (10ms = check 100x per second)
time.sleep(0.01)
@@ -608,6 +641,27 @@ def launch_chromium(name):
print(f"✗ Failed to launch Chromium: {e}")
logging.error(f"Failed to launch Chromium: {e}")
def send_health_status(hostname, device_ip):
"""Send periodic health status messages when device is not configured"""
logging.info("Health status monitor started")
while True:
try:
name = read_idmasa()
# Only send health status when device is NOT configured
if name == "noconfig":
message = f"App working - RFID monitoring active"
send_log_to_server(message, hostname, device_ip, name)
logging.info(f"✓ Health check sent: {message}")
# Send every 5 minutes
time.sleep(300) # 5 minutes
except Exception as e:
logging.error(f"Error in health status monitor: {e}")
time.sleep(30)
# ============================================================================
# MAIN APPLICATION
# ============================================================================
@@ -635,6 +689,10 @@ def main():
print(f"API: {HARTING_API_BASE}")
print()
# Send startup message to monitoring server
name = read_idmasa()
send_log_to_server("App initialized", hostname, device_ip, name)
# Thread 1: Start RFID reader (background, listening for cards)
rfid_reader = initialize_rfid_reader(hostname, device_ip)
if not rfid_reader:
@@ -642,6 +700,7 @@ def main():
logging.error("RFID reader initialization failed - exiting")
sys.exit(1)
print("✓ RFID reader started in background")
send_log_to_server("RFID initialized", hostname, device_ip, name)
# Thread 2: Start card event processor (main thread checks flags and processes)
card_processor_thread = threading.Thread(
@@ -663,13 +722,23 @@ def main():
wifi_thread.start()
print("✓ WiFi monitor started")
# Thread 4: Start health status monitor (sends periodic status when noconfig)
health_thread = threading.Thread(
target=send_health_status,
args=(hostname, device_ip),
daemon=False,
name="HealthMonitor"
)
health_thread.start()
print("✓ Health status monitor started")
# Launch Chromium browser
print("\nInitializing Chromium launcher...")
time.sleep(2) # Give system time to stabilize
launch_chromium(read_idmasa())
print()
logging.info("RFID Client operational")
send_log_to_server("RFID Client operational", hostname, device_ip, read_idmasa())
send_log_to_server("App working", hostname, device_ip, name)
print("✓ RFID Client operational - waiting for cards...")
print()