crowny-space(:9607) 기능 확장 3종 — 시간트리거·에너지적산·웹브릿지
개요
라이브 서비스 crowny-space(홈어시스턴트, 포트 9607, LaunchAgent org.crowny.space)의
서버.한선에 3종 확장을 추가: ①자동화 시간/일몰일출 트리거, ②에너지 적산·누진요금,
③웹 하이드레이션 브릿지(bridge.js). 기존 라이브 파일을 직접 수정(트랙 소유 서비스,
사전 백업 후 허용).
무엇을 했는지
1) 자동화 시간 트리거
- 자동화 규칙의 triggerEntity 필드에
time:HH:MM 또는 sun:sunset±N/sun:sunrise±N
형식을 지원(기존 entity 트리거와 스키마 호환 유지, 접두어로 구분).
- 일출/일몰은 서울 기준 월별 고정 12행 테이블(근사, 1차 — 정밀 천문계산은 후속).
GET /api/tick 신설: 외부 크론/허브가 1분 주기로 두드리는 설계(서버 내 상주 타이머
스레드 없음 — VM 제약 회피). 현재 시각과 미발화 규칙을 대조해 발화, 같은 규칙은
하루 1회만(data/자동화발화.psv로 날짜별 발화기록 추적). 발화 시 기존
_엔티티설정
경로 재사용 + 로그북/감사 기록.
- 나눗셈 자연반올림 함정 회피용
_절단나눗셈(a,b) 헬퍼, HH:MM↔분 변환 _HHMM분/_분HHMM.
2) 에너지 적산·누진요금
- data/전력적산.psv: 덧쓰기(append) 대신 쓰기(overwrite) 단일행 스냅샷으로 설계
(
lastEpoch|lastDate|todayWh|monthKey|monthWh|hintMonth). 자동화 append-log
패턴을 그대로 썼다면 1분 주기 tick이 하루 1440행씩 쌓여 문자열 65535B 하드캡을
금방 넘기므로(가드레일 실측 함정), 이 파일만 예외적으로 overwrite 스냅샷 채택.
- POST /api/command(상태변화) + GET /api/tick마다
_에너지적산() 호출 — 경과시간×
현재 kW(sensor.power_total)를 정수 Wh로 적산(
_kW문자열_W로 "1.8" 같은 kW 문자열을
float 없이 정수 Watt로 파싱).
GET /api/energy → {today_wh, month_kwh, tier, est_bill}. 한국 주택용 누진
3단계(300/450kWh 경계) 근사 계산 — 기본요금 910/1600/7300 + 전력량요금
1200/2146/3070(원/10kWh 스케일, 각 구간 소비량만 해당 구간 단가로 과금하는 실제
누진 방식대로 구간별 분리 계산).
- 월 280kWh↑ 도달 시 로그북 + 감사에 절전 힌트 1회 기록(월 1회 가드로 중복 방지).
- 셀코어 정책에
에너지_누진접근 룰 추가(4번째 등록 룰).
3) 웹 하이드레이션 브릿지
GET /(앱.html 스트리밍) 완료 후 소켓에 <script src="/bridge.js"></script> 추가
전송(Connection:close라 Content-Length 문제 없음, 파일 자체는 무수정).
GET /bridge.js 신설 — /Users/ef/crowny-space/웹브릿지.js 서빙(신규, ~180줄).
30초 폴링으로 /api/entities·/api/logbook·/api/energy 를 받아
window.__crownySpaceLive 갱신 +
document.title = "Crowny Space · 라이브 N기기" +
console.log. 연속 실패 시 30→120초 점진 백오프.
CrownyAI 번들 spaceBridge.js와의
충돌 방지: 전역 가드
window.__crownySpaceBridge가 이미 있으면 폴링 완전 스킵.
- 동반 파일
웹브릿지.한선(브라우저 전용 로직이라 완전 등가 실행은 불가하나, 같은
3-엔드포인트 폴링/집계를 체계 curl 경유로 재현하는 서버측 동반 로직).
검증 (전부 라이브 실측, 2026-07-17)
CROWNY_STRICT=1 hanseonc_high 서버.한선 — 경고 0, 컴파일 성공.
launchctl kickstart -k gui/501/org.crowny.space 재기동 → 기존 기능 회귀:
/health, /api/spaces, /api/entities, POST /api/command, /api/logbook 전부 정상
(light.kitchen 70→55 커맨드 확인).
- 신규:
-
/api/tick 2회 호출 — 1회차 발화, 2회차 fired:0(멱등 확인).
- time: 트리거 시나리오(auto_test_time, 트리거=현재시각) → 1회 발화·엔티티 반영·
자동화발화.psv 기록, 재호출 시 미발화(중복방지 확인).
- sun: 트리거 시나리오(auto_test_sun, sun:sunset-173 = 7월 일몰19:56-173분=17:03
현재시각과 일치하도록 역산) → 정상 발화, HH:MM 산술 검증됨.
-
/api/energy 필드 4종(today_wh/month_kwh/tier/est_bill) 확인, 실측 값
{"today_wh":33,"month_kwh":0.0,"tier":1,"est_bill":910}.
-
curl / | tail 에
<script src="/bridge.js"></script> 태그 확인.
-
/bridge.js 200, 7294바이트 서빙 확인.
- 테스트로 주입한 임시 자동화 규칙(auto_test_time/auto_test_sun)·발화기록·엔티티
상태(light.veranda/light.study)는 검증 후 원상복구(API로 원래 값 재설정 + PSV에서
테스트 규칙 행 제거) — 라이브 데이터 오염 없음.
관련 파일
/Users/ef/crowny-space/서버.한선 (수정, 백업: 서버.한선.bak-확장전-1784265866)
/Users/ef/crowny-space/서버.toau (재컴파일 배포)
/Users/ef/crowny-space/웹브릿지.js (신규)
/Users/ef/crowny-space/웹브릿지.한선 (신규, 동반)
/Users/ef/crowny-space/data/자동화발화.psv (신규 데이터 파일)
/Users/ef/crowny-space/data/전력적산.psv (신규 데이터 파일, overwrite 스냅샷)
크라우니코드
lookup HIT 0건 / MISS 5건(시간트리거·에너지적산·누진요금·웹브릿지·브릿지폴링 검색,
전부 신규 로직으로 직접 생성) / learn 추가 3건(시간트리거에너지적산 브레인학습 1건 +
시간트리거매칭·에너지적산정수Wh 패턴학습 2건).
잔여 이슈
- 일출/일몰 테이블은 월별 고정 근사값(1차) — 정밀 천문계산(위도/경도 기반)은 후속 과제.
- 에너지 적산은 tick 호출 주기(외부 크론 1분 가정)에 의존 — 크론이 오래 끊기면
스냅샷의
간격 값이 3600초 초과 시 60초로 클램프(과다 적산 방지용 안전장치이나,
장시간 다운 시 그 구간 실사용량은 반영되지 않음 — 근사 한계로 인지 필요).
- 누진요금 계산은 부가세/전력산업기반기금 등 제외한 근사치(기본요금+전력량요금만).
- 웹브릿지.js는 1차 최소 범위(상태보관+타이틀+로그) — DOM 캡처/렌더링은 CrownyAI
브릿지 트랙(spaceBridge.js) 통합 시 후속.