Problem mit inkonsistenten variablen Status in der Taste -Thread -Schleife (Raspberry Pi + Flask API + Threading)Python

Python-Programme
Anonymous
 Problem mit inkonsistenten variablen Status in der Taste -Thread -Schleife (Raspberry Pi + Flask API + Threading)

Post by Anonymous »

obs: Wenn mehr Kontext benötigt wird, werde ich ihn senden und entschuldige mich für ein Englisch- oder Codefehler, da die Frage von Ai < /p>
übersetzt wurde. Ich führe eine auf Flash-basierte API auf einem Raspberry-Pi durch, der einen Drehkreuz mit einem Servo-Motor steuert. Es integriert sich in ein Gesichtserkennungssystem, und sein Hauptfluss lautet: < /p>
empfängt Gesichtserkennungsdaten (über externe API). Die Verwendung globaler Variablen und Nutzfunktionen wurde eine Logik in die Verwendung einer Catracastate -Klasse zur Verwaltung des Status geändert. Das Problem, mit dem ich ausgesetzt bin, bleibt jedoch weiterhin bestehen. Hier ist, was passiert: < /p>
Bei der ersten Drücke, alle Werte (Card_id, Winkel usw.) kommen keine oder 0 durch, obwohl ich weiß, dass sie früher eingestellt sind. Thread geht manchmal in den Logikblock fort. < /p>
Dieses Problem wird nur in der ersten Iteration angezeigt. Danach funktioniert die Logik wie erwartet. IS_HOLIDING Global, Lokal und klassengebunden-alle hatten ein ähnliches Verhalten.
Überprüfung des Datenflusss und Drucks bestätigen die Werte, aber der Thread sieht sie als keine/0. Klarheit): < /p>

Code: Select all

#-> (this is not a print) Current angle is taken from the env so it should have # # value, card id is set...
Button pressed: False
Button state: True

Current angle: 0
🔍 check_student_pass started with card_id: None
➡️ Moving servo to 0°
⚠️ No card read. Skipping request.
Then on the second try:

#-> (this is not a print) here is the second attempt, even though the button that # should be true remains as false, as if it had not changed
Current angle: 85
🔍 check_student_pass started with card_id: cpf2
✅ Passage confirmed
➡️ Moving servo to 65°
🔗 Sending confirmation to server: cpf2
🧠 Additional Context:

< /code>
Ich verwende rpi.gpio, eine benutzerdefinierte Klasse (Catracastat), um Kartenlesungen und Wiederholungen zu verfolgen. Frage: < /p>
Warum sind meine Variablen (Card_id, Winkel usw.) keine oder 0 auf der ersten Schleife -Iteration des Schaltflächen -Threads, obwohl sie im Voraus eindeutig eingestellt sind? Wie kann ich sicherstellen, dass der Thread sofort den richtigen aktualisierten Zustand sieht?import RPi.GPIO as GPIO
import time
import threading
import requests
import os
from datetime import datetime
from servo_controller import set_angle, get_current_angle
from api.global_state import catraca_state

BUTTON_PIN = 23  # Button GPIO pin
CONFIRM_PASS_URL = "https://your.api.endpoint/turnstile/pass"  # Replace with real endpoint
TURNSTILE_NAME = os.getenv("TURNSTILE_ID", 1)
TOKEN = "REPLACE_WITH_REAL_TOKEN"
headers = {
"Authorization": f"Bearer {TOKEN}"
}
DEBUG = True

# Setup GPIO pin for the button
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)  # Using PULL-UP configuration

def _monitor_button():
"""Infinite loop that checks if the button is pressed and sends a confirmation to the server."""
is_holding = False

try:
while True:
if GPIO.input(BUTTON_PIN) != GPIO.HIGH:
print("🔴 Button pressed. is_holding:", is_holding)
if is_holding:
time.sleep(0.01)
continue
is_holding = True

print("Proceeding to check angle")
current_angle = get_current_angle()
print("Current angle:", current_angle)
[ANGLE_OPEN, ANGLE_CLOSE] = catraca_state.get_catraca_angles()

if catraca_state.get_always_open():
print("🟢 'Always open' mode is ON. Skipping motor and API.")
time.sleep(0.01)
continue

last_card_id = catraca_state.get_last_card_id()

card_id = check_student_pass(last_card_id)

# Give time for the person to pass
time.sleep(1)
print(f"➡️ Moving servo to {ANGLE_CLOSE}°")
set_angle(ANGLE_CLOSE)

if card_id is not None:
last_card_id = card_id

if last_card_id is None:
print("⚠️ No card ID detected.  Request will not be sent.")
else:
try:
print(f"🔗 Sending confirmation to server: {last_card_id}")
response = requests.put(
CONFIRM_PASS_URL,
json={
"CPF": last_card_id,
"turnstileName": TURNSTILE_NAME
},
headers=headers,
timeout=5
)
print(f"📡 Server response: {response.status_code} - {response.text}")

if response.status_code == 200:
print("✅ Passage successfully confirmed!")
else:
print("⚠️ Failed to confirm passage.")

catraca_state.reset_last_card_id()

except requests.exceptions.RequestException as e:
print(f"❌ Error communicating with server: {e}")
else:
is_holding = False

time.sleep(0.01)
except KeyboardInterrupt:
GPIO.cleanup()
print("🛑 Button monitoring stopped.")

def start_button_monitor():
"""Starts the thread to monitor the button press."""
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
t = threading.Thread(target=_monitor_button, daemon=True)
t.start()

def check_student_pass(last_card_id):
"""
Logic to verify if the same student has passed twice in a row.
If true, returns the card_id of the student who should have passed instead.

This prevents someone from passing with another person's facial recognition.
"""
print(f"🔍 check_student_pass started with card_id: {last_card_id}")

if last_card_id is None:
return None

catraca_state.update_student_pass(last_card_id, True)
print(f"✅ Updated pass count for card_id: {last_card_id}")

students_pass_list = catraca_state.get_students_pass()
print(f"📋 Total students in memory: {len(students_pass_list)}")

flag_double_pass = False
double_pass_student = None

student_passing = next((s for s in students_pass_list if s['card_id'] == last_card_id), None)

if student_passing is None:
print(f"⚠️ No student found with card_id: {last_card_id}")
return None

print(f"👤 Student found: {student_passing['card_id']}, group: {student_passing['group_id']}, count: {student_passing['pass_count']}")

is_not_whitelisted = student_passing['group_id'] != 2
print(f"🚫 Not in whitelist? {is_not_whitelisted}")

for student in students_pass_list:
if is_not_whitelisted and student['pass_count'] == 0 and student['group_id'] == 2:
print(f"🔄 Case 1: Whitelisted student who hasn't passed yet found: {student['card_id']}")
return student['card_id']

if student_passing['pass_count'] >= 2:
flag_double_pass = True
double_pass_student = student_passing
print(f"⚠️ Student {student_passing['card_id']} passed more than once: {student_passing['pass_count']}")

if flag_double_pass:
t1 = double_pass_student['identification_time']
print(f"🕒 Identification time of double-pass student: {t1}")

for student in students_pass_list:
if student['card_id'] == double_pass_student['card_id']:
print(f"⏭️ Skipping self comparison for: {student['card_id']}")
continue

t2 = student['identification_time']
print(f"🔄 Comparing with: {student['card_id']}, group: {student['group_id']}, count: {student['pass_count']}, time: {t2}")

if student['pass_count'] == 0 and t1 >  t2 and student['group_id'] == 2:
print(f"✅ Case 2: Whitelisted student who was identified earlier and hasn't passed: {student['card_id']}")
student['pass_count'] += 1
catraca_state.update_student_pass(student['card_id'], True)
double_pass_student['pass_count'] -= 1
catraca_state.update_student_pass(double_pass_student['card_id'], False)
print(f"🔄 Adjusted counts: {student['card_id']}={student['pass_count']}, {double_pass_student['card_id']}={double_pass_student['pass_count']}")
return student['card_id']

print(f"❌ No special case detected. Returning None")
return None

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post