feat: 取消签退(clock_out)机制,仅保留签到记录
GPS定位偏差导致设备频繁误判为离开围栏触发签退, 移除所有签退逻辑:围栏出栏不再创建clock_out, 设备考勤(0xB0/0xB1)和蓝牙打卡(0xB2)统一只记录签到。 via [HAPI](https://hapi.run) Co-Authored-By: HAPI <noreply@hapi.run>
This commit is contained in:
@@ -290,39 +290,11 @@ async def check_device_fences(
|
|||||||
)
|
)
|
||||||
|
|
||||||
elif not currently_inside and was_inside:
|
elif not currently_inside and was_inside:
|
||||||
# EXIT: inside -> outside = clock_out
|
# EXIT: inside -> outside — skip clock_out (GPS drift causes false exits)
|
||||||
if state and state.last_transition_at:
|
logger.debug(
|
||||||
elapsed = (now - state.last_transition_at).total_seconds()
|
"Fence exit ignored: device=%d fence=%d(%s), no clock_out created",
|
||||||
if elapsed < min_interval:
|
device_id, fence.id, fence.name,
|
||||||
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,
|
|
||||||
)
|
|
||||||
|
|
||||||
# 4. Update state
|
# 4. Update state
|
||||||
if state is None:
|
if state is None:
|
||||||
|
|||||||
@@ -1730,16 +1730,12 @@ class TCPManager:
|
|||||||
gps_positioned = gps["gps_positioned"]
|
gps_positioned = gps["gps_positioned"]
|
||||||
pos += 12
|
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"
|
attendance_type = "clock_in"
|
||||||
terminal_info = 0
|
terminal_info = 0
|
||||||
if len(content) > pos:
|
if len(content) > pos:
|
||||||
terminal_info = content[pos]
|
terminal_info = content[pos]
|
||||||
status_code = (terminal_info >> 2) & 0x0F
|
# status_code = (terminal_info >> 2) & 0x0F — always use clock_in
|
||||||
if status_code == 0b0010:
|
|
||||||
attendance_type = "clock_out"
|
|
||||||
elif status_code == 0b0001:
|
|
||||||
attendance_type = "clock_in"
|
|
||||||
pos += 1
|
pos += 1
|
||||||
|
|
||||||
# voltage_level (1 byte)
|
# voltage_level (1 byte)
|
||||||
@@ -1992,13 +1988,9 @@ class TCPManager:
|
|||||||
beacon_battery = raw_batt * 0.01
|
beacon_battery = raw_batt * 0.01
|
||||||
pos += 2
|
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"
|
attendance_type = "clock_in"
|
||||||
if len(content) > pos:
|
if len(content) > pos:
|
||||||
terminal_info = content[pos]
|
|
||||||
status_code = (terminal_info >> 2) & 0x0F
|
|
||||||
if status_code == 0b0010:
|
|
||||||
attendance_type = "clock_out"
|
|
||||||
pos += 1
|
pos += 1
|
||||||
|
|
||||||
# Terminal reserved (2 bytes) - echo back
|
# Terminal reserved (2 bytes) - echo back
|
||||||
|
|||||||
Reference in New Issue
Block a user