update untuk penyesuaian mulai hitung saat menerima pesan dari tombol

This commit is contained in:
Alberto-Audrix committed 2026-08-11 16:22:35 +07:00
1 parent 41c4a558b1
commit 3c30ded269
7 files changed
+471 -99

No files matched your search

+70 -8
View File
@@ -139,6 +139,20 @@ CONTROL_SOCKET_ENABLED = os.getenv("CONTROL_SOCKET_ENABLED", "false").lower() ==
CONTROL_SOCKET_HOST = os.getenv("CONTROL_SOCKET_HOST", "127.0.0.1")
CONTROL_SOCKET_PORT = int(os.getenv("CONTROL_SOCKET_PORT", "5090"))
# --- Status webhook gate (direction-locked when IN or OUT) ---
# When enabled, counting runs only while status is IN or OUT, and only that
# direction is counted (IN → in crossings, OUT → out crossings). OFF pauses all.
STATUS_WEBHOOK_ENABLED = os.getenv("STATUS_WEBHOOK_ENABLED", "false").lower() == "true"
STATUS_WEBHOOK_FILE = os.getenv(
"STATUS_WEBHOOK_FILE",
"/opt/zenai-kpc-python/status_webhook_state",
)
_active_raw = os.getenv("STATUS_WEBHOOK_ACTIVE_VALUES", "IN,OUT")
STATUS_WEBHOOK_ACTIVE_VALUES = frozenset(
part.strip().upper() for part in _active_raw.split(",") if part.strip()
)
STATUS_WEBHOOK_INACTIVE_VALUE = os.getenv("STATUS_WEBHOOK_INACTIVE_VALUE", "OFF").strip().upper()
CROSS_FLASH_FRAMES = 12
POPUP_LIFETIME = 20
LINE_PULSE_FRAMES = 12
@@ -750,6 +764,21 @@ def read_counting_flag(default=True):
return default
def read_status_webhook():
"""Return normalized status from webhook file, or inactive value on error."""
try:
with open(STATUS_WEBHOOK_FILE, "r", encoding="utf-8") as f:
data = json.load(f)
status = str(data.get("status", "")).strip().upper()
return status or STATUS_WEBHOOK_INACTIVE_VALUE
except Exception:
return STATUS_WEBHOOK_INACTIVE_VALUE
def status_webhook_allows_counting(status):
return status in STATUS_WEBHOOK_ACTIVE_VALUES
def write_control_file(counting):
"""Create/update the control file atomically (used to seed defaults)."""
try:
@@ -1221,6 +1250,8 @@ def run():
last_snapshot_cleanup = 0.0
counting_active = True
status_nyala_active = True
status_webhook_value = STATUS_WEBHOOK_INACTIVE_VALUE
last_control_poll = 0.0
control_socket = None
if CONTROL_ENABLED:
@@ -1236,6 +1267,13 @@ def run():
control_socket = start_control_socket()
except Exception as exc:
print(f"[{now_str()}] Failed to start control socket: {exc}")
if STATUS_WEBHOOK_ENABLED:
status_webhook_value = read_status_webhook()
status_nyala_active = status_webhook_allows_counting(status_webhook_value)
print(
f"Status webhook enabled | file={STATUS_WEBHOOK_FILE} | "
f"status={status_webhook_value}"
)
cap, w, h, fps = connect_stream(SOURCE)
if cap is None:
@@ -1288,15 +1326,30 @@ def run():
cross_events_frame = []
detect_events_frame = []
if CONTROL_ENABLED and (now - last_control_poll) >= CONTROL_POLL_SEC:
if (CONTROL_ENABLED or STATUS_WEBHOOK_ENABLED) and (
now - last_control_poll
) >= CONTROL_POLL_SEC:
last_control_poll = now
new_flag = read_counting_flag(CONTROL_DEFAULT_COUNTING)
if new_flag != counting_active:
counting_active = new_flag
print(f"[{now_str()}] Counting {'RESUMED' if counting_active else 'PAUSED'} via control file")
if CONTROL_ENABLED:
new_flag = read_counting_flag(CONTROL_DEFAULT_COUNTING)
if new_flag != counting_active:
counting_active = new_flag
print(
f"[{now_str()}] Counting "
f"{'RESUMED' if counting_active else 'PAUSED'} via control file"
)
if STATUS_WEBHOOK_ENABLED:
new_status = read_status_webhook()
if new_status != status_webhook_value:
status_webhook_value = new_status
status_nyala_active = status_webhook_allows_counting(
status_webhook_value
)
print(f"[{now_str()}] Status webhook {status_webhook_value}")
counting_allowed = counting_active and status_nyala_active
skip_inference = False
if not counting_active:
if not counting_allowed:
skip_inference = True
elif MOTION_DETECTION_ENABLED:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
@@ -1450,6 +1503,12 @@ def run():
# Prefer decisive motion if both count triggers fire in one jump.
count_in = in_down and not st["counted"]
count_out = out_up and not st["counted"]
if STATUS_WEBHOOK_ENABLED:
# Webhook IN → only IN counts; OUT → only OUT counts.
if status_webhook_value == "IN":
count_out = False
elif status_webhook_value == "OUT":
count_in = False
if count_in and count_out:
if cy >= prev_cy:
count_out = False
@@ -1586,8 +1645,11 @@ def run():
)
popups = draw_popups(frame, popups, frame_idx)
if CONTROL_ENABLED and not counting_active:
badge = "COUNTING PAUSED"
if (CONTROL_ENABLED or STATUS_WEBHOOK_ENABLED) and not counting_allowed:
if STATUS_WEBHOOK_ENABLED and not status_nyala_active:
badge = status_webhook_value
else:
badge = "COUNTING PAUSED"
(bw, bh), _ = cv2.getTextSize(badge, cv2.FONT_HERSHEY_SIMPLEX, 0.6, 2)
bx = w // 2 - bw // 2
overlay_rect(frame, bx - 14, 48, bx + bw + 14, 48 + bh + 18, C_PANEL, alpha=0.75)