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:
95
app.py
95
app.py
@@ -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
|
||||
}
|
||||
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()
|
||||
|
||||
|
||||
BIN
data/log.txt
BIN
data/log.txt
Binary file not shown.
78
test_monitoring_server.py
Normal file
78
test_monitoring_server.py
Normal file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script to verify connection to monitoring server
|
||||
"""
|
||||
|
||||
import requests
|
||||
import socket
|
||||
import sys
|
||||
|
||||
# Configuration
|
||||
MONITORING_SERVER = "http://rpi-ansible:80/logs"
|
||||
|
||||
def test_connection():
|
||||
"""Test if monitoring server is reachable"""
|
||||
print(f"Testing connection to: {MONITORING_SERVER}\n")
|
||||
|
||||
# Get local info
|
||||
try:
|
||||
hostname = socket.gethostname()
|
||||
device_ip = socket.gethostbyname(hostname)
|
||||
print(f"Local hostname: {hostname}")
|
||||
print(f"Local IP: {device_ip}\n")
|
||||
except Exception as e:
|
||||
print(f"Error getting local info: {e}\n")
|
||||
hostname = "unknown"
|
||||
device_ip = "0.0.0.0"
|
||||
|
||||
# Test 1: Simple GET request
|
||||
print("1. Testing simple GET request...")
|
||||
try:
|
||||
response = requests.get(MONITORING_SERVER, timeout=5)
|
||||
print(f" ✓ GET successful (Status: {response.status_code})")
|
||||
print(f" Response: {response.text[:200]}\n")
|
||||
except Exception as e:
|
||||
print(f" ✗ GET failed: {e}\n")
|
||||
|
||||
# Test 2: POST with test data
|
||||
print("2. Testing POST with test data...")
|
||||
try:
|
||||
test_data = {
|
||||
"hostname": hostname,
|
||||
"device_ip": device_ip,
|
||||
"nume_masa": "TEST_STATION",
|
||||
"log_message": "Test message from client"
|
||||
}
|
||||
print(f" Payload: {test_data}")
|
||||
response = requests.post(MONITORING_SERVER, json=test_data, timeout=5)
|
||||
print(f" ✓ POST successful (Status: {response.status_code})")
|
||||
print(f" Response: {response.text}\n")
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
print(f" ✗ Connection error: {e}")
|
||||
print(f" - Server may be unreachable at {MONITORING_SERVER}\n")
|
||||
except requests.exceptions.Timeout:
|
||||
print(f" ✗ Request timeout (5s)")
|
||||
print(f" - Server may be offline or slow\n")
|
||||
except Exception as e:
|
||||
print(f" ✗ POST failed: {e}\n")
|
||||
|
||||
# Test 3: Ping server IP
|
||||
print("3. Testing network connectivity to server...")
|
||||
import subprocess
|
||||
try:
|
||||
server_ip = "192.168.1.103"
|
||||
result = subprocess.run(
|
||||
["ping", "-c", "1", server_ip],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
timeout=5
|
||||
)
|
||||
if result.returncode == 0:
|
||||
print(f" ✓ Server IP {server_ip} is reachable\n")
|
||||
else:
|
||||
print(f" ✗ Server IP {server_ip} is NOT reachable\n")
|
||||
except Exception as e:
|
||||
print(f" ✗ Ping failed: {e}\n")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_connection()
|
||||
Reference in New Issue
Block a user