← 목록
기타 2026-07-19 8KB 읽기 8분

crowny-space 지오펜스 재실(Presence) 트래커 — 서버(:9607) 확장

개요

crowny-space(:9607, /Users/ef/crowny-space) SpModuleControl 재실 스트립이 시드 정적 데이터였던 것을, 실좌표 기반 지오펜스 판정 + 4상(티/타/옴/음) 재실품질 + 자동화 엔진 실연동으로 확장했다.

학습DB 재사용(HIT)

crownycode-learn.sh lookup/search로 사전 조회:

  • 지오펜스_다각형판정 — HIT였으나 내용이 가져오기 "셀코어" 스텁뿐이라 실사용 로직 없음(재사용 불가, 사유 기록 후 신규 작성).
  • fn_지오펜싱_지오펜스생성공간, fn_위치서비스_거리계산정확 — HIT, 아이디어(원형 존/위경도 111 근사) 참고했으나 정수 1e6 스케일·자연반올림 함정 대응을 위해 상수를 재도출해 신규 구현.
  • 다각형 판정은 스펙 조건("포함 가능하면") 미충족으로 이번 범위에서 제외.

신규 lib: /Users/ef/crowny-space/규격/지오펜스.한선

  • 좌표 표현: 위도/경도 ×1e6 정수. 좌표E6()가 십진도(<1000)/스케일드 정수 자동 판별.
  • 거리m(): 하버사인 float 함정 회피 — 정수 등장방형(equirectangular) 근사. 위도축 111320m/도, 경도축은 수도권 위도(~37.5°N) cos 보정을 상수(88300)로 미리 곱해 삼각함수 호출 없이 처리. 실측검증: 0.001도 위도차≈111m·경도차≈88m(표준값 대비 오차 <1%).
  • 존생성/존이름/존위도E6/존경도E6/존반경: PSV 문자열 인코딩("이름|위도E6|경도E6|반경m") — 구조체 대신 필드분리 문자열(배열 재호출 함정 회피).
  • 존판정(존들,위,경): 반경 내 최근접 존 이름, 없으면 "".
  • 재실판정(존이름,홈존이름,마지막보고초,현재초): 4상 — 티(존내)/타(존밖)/옴(신선도 600초 초과)/음(미보고, 마지막보고초<=0).
  • 지오펜스정책등록(): 셀코어 룰 병행표현(문서화용, 판정 정본은 함수 자체).
  • 자체시험 지오_자체시험() — GEO_SELFTEST=1 게이트, 22 assert 전량 ALL_PASS(좌표정규화·거리축·경계 포함/제외·최근접우선·존 필드왕복·4상 전체·신선도 경계).
  • 실측 함정 1건: -126.978류 십진도 리터럴 ×1e6 float 곱셈이 ±1~2 오차(VM 부동소수 정밀도, 37.5665류는 정확 왕복) — 자체시험은 정확 왕복이 검증된 리터럴로 고정, 존 판정 스케일(수십~수백m)에는 무해.
  • CROWNY_STRICT=1 경고 0.

server.한선 확장

  • 가져오기 "규격/지오펜스.한선" 추가.
  • 신규 데이터: data/재실.psv(person|zone|sinceSec|lastReportSec|latE6|lonE6, append-log), data/재실발화.psv(all_out/first_in 중복발화 방지), data/재실집계상태.psv(전원밖↔귀가 집계 상태).
  • POST /api/presence — {"person","lat","lon"}(십진도 또는 1e6 스케일 정수 모두 수용) → 존판정 → 재실.psv 기록(같은 존 유지 시 since 보존, 존 전환 시 since 갱신) → _재실전환체크() 즉시 호출.
  • GET /api/persons — 재실.psv 실데이터 우선(zone·since·quality 4상 포함), 미보고 인물은 기존 정적 시드값 폴백(quality="음").
  • GET /space/env·GET /space/interlock — 재실 카운트/occupancy를 _재실카운트()(로스터 중 "티" 인원)로 계산, 실데이터 전무 시 기존 하드코딩 값(1) 폴백.
  • 외출/귀가 자동화 트리거 승격: _재실전환체크()가 로스터 전원이 "타"(존밖, 신선)일 때 최초 이탈시각부터 15분(_재실전원밖유예초=900) 경과 시 _자동화매칭("presence.all_out","1",0) 발화(기존 자동화 엔진 경로 재사용, 재발화 방지 가드 포함). 전원밖 상태에서 한 명이라도 "티"로 복귀하면 즉시 presence.first_in 발화(그레이스 없음).
  • 자동화.psv seed의 auto1("외출 감지 → 외출 모드") 트리거를 lock.frontpresence.all_out으로 승격. 기존 라이브 데이터 자동 마이그레이션(멱등, 재기동마다 트리거가 아직 lock.front면 승격 행 append, 이미 승격됐으면 스킵).
  • GET /api/tick_재실전환체크() 호출 추가(60초 무료 tick에서 그레이스 판정).
  • 검증

    • 지오펜스.한선: STRICT 경고 0, GEO_SELFTEST=1 → ALL_PASS 22/22.
    • server.한선: STRICT 경고 0.
    • 배포: 서버.한선/서버.toau 타임스탬프 백업(*.bak-재실확장전-1784382420) 후 재컴파일 → launchctl kickstart -k org.crowny.space → /health 200 확인.
    • 회귀 12종 무손상 라이브 확인: health/spaces/entities/command→logbook/tick/energy/bridge.js/ingest/commands(GET)/hub·register/scenes·run/bills 전부 정상 응답(파라미터 오류 응답은 기존 검증 로직 그대로 — 회귀 아님).
    • E2E 라이브 실측(부산 좌표를 "존밖"으로 사용):
    1. 준영·수진·하윤 집 좌표(37.5665,126.9780) 보고 → /api/persons 전원 home:1,zone:"집",quality:"티" 확인. 2. 1인씩 존밖 보고 → 부분 이탈 상태에서 tick fired:0(미발화) 확인, 전원 이탈 완료 시점에도 즉시는 미발화(그레이스 유지) 확인. 3. since를 1000초 전으로 백데이트(그레이스 15분 경과 시뮬레이션, lastReportSec은 신선 유지) 후 tick → 로그북에 entity:light.living, from:1→0, cause:"automation", causeRef:"auto1:외출 감지 → 외출 모드" 발화 확인 + 감사로그 "전원 외출 확정(15분 경과) → presence.all_out 트리거" 확인. 재호출 tick은 재발화 안 함(dedup 확인, 재실발화.psv all_out|<sinceSec>). 4. 준영 귀가 보고(집 좌표) → 감사로그 "첫 귀가 감지 → presence.first_in 트리거" 즉시 확인(그레이스 없음), 재실집계상태 away→home 전환 확인. 5. 하윤 lastReportSec을 700초 전으로 백데이트 → /api/persons에서 quality:"옴" 확인(신선도 초과, 600초 한계). 6. 시험 후 data/재실*.psv 3종 삭제 → /api/persons·/space/env·/space/interlock 전부 폴백 시드 상태로 복원 확인.

    크라우니코드

    lookup HIT 3건(지오펜스_다각형판정=재사용불가스텁, fn_지오펜싱_지오펜스생성공간·fn_위치서비스_거리계산정확=아이디어 참고 후 신규 구현) / MISS(자체 신규 로직: 좌표E6 스케일정규화, 정수 등장방형 거리, 4상 재실판정, 전환체크 그레이스+dedup) / crownycode-brain.sh learn "지오펜스재실판정" 규격/지오펜스.한선 학습 완료.

    관련 파일

    • /Users/ef/crowny-space/규격/지오펜스.한선 (신규)
    • /Users/ef/crowny-space/서버.한선 (확장, 백업: 서버.한선.bak-재실확장전-1784382420)
    • /Users/ef/crowny-space/서버.toau (재컴파일 배포, 백업: 서버.toau.bak-재실확장전-1784382420)
    • data/재실.psv, data/재실발화.psv, data/재실집계상태.psv (신규 데이터 스키마, 시험 후 삭제 상태로 정리 완료 — 실보고 유입 시 자동 생성)

    touchedExistingFiles

    • /Users/ef/crowny-space/서버.한선
    • /Users/ef/crowny-space/서버.toau
    • /Users/ef/crowny-space/data/자동화.psv (auto1 트리거 마이그레이션 append — 정상 운영 변경, 되돌리지 않음)

    잔여 이슈

    • 폰/비콘 → 허브 → /api/presence 실보고 연동은 범위 외(후속 작업).
    • 다각형 지오펜스 미구현(원형만) — 학습DB 재사용 패턴이 스텁이라 실사용 불가했던 것이 사유. 필요 시 신규 구현 필요.
    • 공간별(교회/사무실/상점) 존 좌표는 데모용 근사치 — 실좌표로 교체 필요.
    • since 필드는 존 진입 시각(epoch초)만 반환 — 프론트엔드에서 "n분 전" 등 사람이 읽는 표시로 변환 필요(현재 서버는 raw epoch초만 내려줌).