From a97dcd07a51c7e0b056b4191d252658d3744273c Mon Sep 17 00:00:00 2001 From: default Date: Tue, 31 Mar 2026 01:54:48 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8F=96=E6=B6=88=E7=AD=BE=E9=80=80(cl?= =?UTF-8?q?ock=5Fout)=E6=9C=BA=E5=88=B6=EF=BC=8C=E4=BB=85=E4=BF=9D?= =?UTF-8?q?=E7=95=99=E7=AD=BE=E5=88=B0=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GPS定位偏差导致设备频繁误判为离开围栏触发签退, 移除所有签退逻辑:围栏出栏不再创建clock_out, 设备考勤(0xB0/0xB1)和蓝牙打卡(0xB2)统一只记录签到。 via [HAPI](https://hapi.run) Co-Authored-By: HAPI --- app/services/fence_checker.py | 38 +++++------------------------------ app/tcp_server.py | 14 +++---------- 2 files changed, 8 insertions(+), 44 deletions(-) diff --git a/app/services/fence_checker.py b/app/services/fence_checker.py index 39e41a8..b41ce01 100644 --- a/app/services/fence_checker.py +++ b/app/services/fence_checker.py @@ -290,39 +290,11 @@ async def check_device_fences( ) elif not currently_inside and was_inside: - # EXIT: inside -> outside = clock_out - if state and state.last_transition_at: - elapsed = (now - state.last_transition_at).total_seconds() - if elapsed < min_interval: - logger.debug( - "Fence %d debounce: %ds < %ds, skip clock_out for device %d", - fence.id, int(elapsed), min_interval, device_id, - ) - _update_state(state, currently_inside, now, latitude, longitude) - continue - - # Daily dedup: only one clock_out per device per day - if await _has_attendance_today(session, device_id, "clock_out"): - logger.info( - "Fence skip clock_out: device=%d fence=%d(%s) already clocked out today", - device_id, fence.id, fence.name, - ) - else: - attendance = _create_attendance( - device_id, imei, "clock_out", latitude, longitude, - address, recorded_at, fence, device_info, - ) - session.add(attendance) - - event = _build_event( - device_id, imei, fence, "clock_out", - latitude, longitude, address, recorded_at, - ) - events.append(event) - logger.info( - "Fence auto clock_out: device=%d fence=%d(%s)", - device_id, fence.id, fence.name, - ) + # EXIT: inside -> outside — skip clock_out (GPS drift causes false exits) + logger.debug( + "Fence exit ignored: device=%d fence=%d(%s), no clock_out created", + device_id, fence.id, fence.name, + ) # 4. Update state if state is None: diff --git a/app/tcp_server.py b/app/tcp_server.py index 9602e7f..686247c 100644 --- a/app/tcp_server.py +++ b/app/tcp_server.py @@ -1730,16 +1730,12 @@ class TCPManager: gps_positioned = gps["gps_positioned"] pos += 12 - # Terminal info (1 byte) - contains clock_in/clock_out status bits + # Terminal info (1 byte) - parse status bits (clock_out disabled due to GPS drift) attendance_type = "clock_in" terminal_info = 0 if len(content) > pos: terminal_info = content[pos] - status_code = (terminal_info >> 2) & 0x0F - if status_code == 0b0010: - attendance_type = "clock_out" - elif status_code == 0b0001: - attendance_type = "clock_in" + # status_code = (terminal_info >> 2) & 0x0F — always use clock_in pos += 1 # voltage_level (1 byte) @@ -1992,13 +1988,9 @@ class TCPManager: beacon_battery = raw_batt * 0.01 pos += 2 - # Terminal info (1 byte) - clock_in/clock_out + # Terminal info (1 byte) - parse but always use clock_in (clock_out disabled) attendance_type = "clock_in" if len(content) > pos: - terminal_info = content[pos] - status_code = (terminal_info >> 2) & 0x0F - if status_code == 0b0010: - attendance_type = "clock_out" pos += 1 # Terminal reserved (2 bytes) - echo back