본문 바로가기
스마트폰 (Mobile)

Home Assistant 센서 교체 시 히스토리 상태·통계 데이터 연속성 유지

by 날으는물고기 2025. 9. 5.

Home Assistant 센서 교체 시 히스토리 상태·통계 데이터 연속성 유지

728x90

이전 센서의 상태(states)와 통계(statistics) 히스토리를 “새 센서”에서 끊기지 않게 이어받는 방법입니다.

핵심 구조 이해 (결정 포인트)

  1. Recorder의 연결 키metadata_id
    • states/statistics 본문 테이블은 문자열 entity_id가 아니라 메타 테이블의 정수 키(states_meta.id, statistics_meta.id)로 연결됩니다.
  2. 메타 테이블의 유일성
    • states_meta.entity_idstatistics_meta.statistic_id(=엔티티의 entity_id)는 엔티티당 1행(유일) 입니다.
    • 같은 entity_id를 “정확히 동일하게” 재사용하면, 기존 메타 행을 그대로 재사용 → 같은 metadata_id로 기록이 이어짐.
  3. unique_id레지스트리(.storage) 용도
    • .storage/core.entity_registry에서 엔티티를 영구 식별하는 값.
    • Recorder DB에는 저장되지 않으며, 히스토리 연결 여부는 결국 entity_id(→ 동일 메타 재사용) 로 결정됩니다.

결론: 가능하면 “같은 entity_id”를 재사용하세요. 그러면 상태·통계가 끊기지 않고 이어집니다.

표준 정책(운영 원칙)

  1. 삭제 지양, 동일 entity_id 유지: 센서 교체라도 기존 엔티티는 가능하면 삭제하지 말고 설정만 조정 → 가장 안전하게 히스토리 연속.
  2. 불가피한 삭제 시: 레지스트리 잔존을 깨끗이 제거한 뒤, 새 센서를 이전과 “완전히 동일한 entity_id”로 등록.
  3. 속성 일치: device_class, state_class, unit_of_measurement통계 관련 속성은 가급적 동일하게 맞춰 경고/보정 이슈 방지.
  4. 백업·점검 우선: DB 작업 전 전체 백업. 작업 후 메타·데이터 무결성 확인(아래 SQL).
  5. 필터·보존정책 병행: 장기적으로 DB 팽창 방지를 위해 recorder exclude/globs + purge + 공간회수를 운영 표준으로.
300x250

절차 A — “가장 안전”: 삭제 없이 이어가기

  1. 이전 엔티티 삭제하지 않음.
  2. 새 하드웨어/통합을 붙이더라도 기존 엔티티의 entity_id를 유지(필요 시 통합 쪽 매핑/옵션만 변경).
  3. 결과: 같은 metadata_id가 계속 쓰이므로 히스토리 무중단.

현실적으로 가장 리스크가 낮습니다.

절차 B — “삭제 후 재등록”이어도 연결하고 싶을 때

전제: 이전과 동일한 entity_id로 재등록할 수 있어야 합니다.

  1. 레지스트리 정리
    • UI에서 이전 엔티티/장치 삭제 후, 동일 entity_id진짜 비어 있는지 확인(레지스트리 잔존 시 동일 ID 재사용 불가).
  2. 새 센서 등록
    • unique_id는 달라도 됨. entity_id를 이전과 완전히 동일하게 지정(예: sensor.livingroom_temp).
  3. 속성 일치 확인
    • device_class/state_class/unit 등을 이전과 동일하게 맞춤(통계 경고 방지).
  4. 검증
    • 아래 SQL로 메타가 1행인지(=기존 메타 재사용)와 metadata_id가 동일한지 확인.

검증 SQL (MySQL)

-- 1) 상태 메타(엔티티당 1행이어야 함)
SELECT id AS metadata_id, entity_id
FROM states_meta
WHERE entity_id = 'sensor.YOUR_ENTITY';

-- 2) 통계 메타(역시 1행)
SELECT id AS metadata_id, statistic_id, unit_of_measurement, has_mean, has_sum, name
FROM statistics_meta
WHERE statistic_id = 'sensor.YOUR_ENTITY';

-- 3) 실제 기록이 같은 metadata_id로 이어지는지 확인(최근 20개)
SELECT s.metadata_id, s.last_updated_ts
FROM states s
JOIN states_meta sm ON s.metadata_id = sm.id
WHERE sm.entity_id = 'sensor.YOUR_ENTITY'
ORDER BY s.last_updated_ts DESC
LIMIT 20;

이 절차가 성공하면 히스토리가 그대로 이어집니다.

절차 C — 이미 끊겼거나 entity_id를 바꿔야 하는 특수 상황(수동 병합)

고급 작업 / 백업 필수 / 점검창(다운타임) 권장

상황

  • 이미 새 엔티티를 다른 entity_id 로 만들었다.
  • 과거와 현재가 서로 다른 metadata_id 로 분리됐다.
  • 또는 이전 통계의 일부만 새 엔티티로 이관/병합하고 싶다.

개념

  • statistics / statistics_short_termmetadata_id를 과거→현재(또는 반대)로 갱신해서 한 줄로 합칩니다.
  • 시간대가 겹치면 복합 유니크 제약(예: (metadata_id,start_ts))에 걸릴 수 있으므로 범위 조절 또는 중복 정리 필요.

절차

  1. 사전 준비: HA 중지 → DB 전체 백업.
  2. ID 채집: 메타 테이블에서 OLD_ID(과거), NEW_ID(현재) 확인
    SELECT id, entity_id FROM states_meta WHERE entity_id IN ('sensor.OLD','sensor.NEW');
    SELECT id, statistic_id FROM statistics_meta WHERE statistic_id IN ('sensor.OLD','sensor.NEW');
  3. 충돌 여부 점검: 병합할 기간/행 미리 샘플링 확인.
  4. 트랜잭션 병합 예시 (개념 예, 필요 시 기간 조건 추가)
    START TRANSACTION;
    
    -- 통계(장기)
    UPDATE statistics
    SET metadata_id = NEW_ID
    WHERE metadata_id = OLD_ID
      AND start_ts < UNIX_TIMESTAMP('2025-09-01 00:00:00'); -- 예시: 겹치지 않게 구간 제한
    
    -- 단기(5분) 통계
    UPDATE statistics_short_term
    SET metadata_id = NEW_ID
    WHERE metadata_id = OLD_ID
      AND start_ts < UNIX_TIMESTAMP('2025-09-01 00:00:00');
    
    COMMIT;
  5. 정리: 필요 시 statistics_meta의 불필요 메타 제거(신중).
  6. ANALYZE/OPTIMIZE 후 HA 기동, 그래프/리포트 확인.

팁: “과거는 OLD_ID, 이후는 NEW_ID”로 기간 분할하면 충돌을 피해 깔끔히 합쳐집니다.

Recorder 보존·성장 억제 정책(장기 운영)

  1. 기록 제외 필터링
    recorder:
      auto_purge: true
      purge_keep_days: 10     # 환경에 맞게
      exclude:
        domains:
          - camera
          - media_player
        entity_globs:
          - sensor.temp_*_raw
          - sensor.debug_*
  2. 정기 Purge + 공간 회수
    • 서비스 호출: recorder.purge (keep_days, apply_filter: true, 필요 시 repack: true)
    • MySQL: OPTIMIZE TABLE ... + ANALYZE TABLE ... 정기 실행(점검창)
  3. MySQL 구조 체크
    • innodb_file_per_table=ON → 테이블별 .ibd 공간 회수 가능
    • 필요 시 ROW_FORMAT=DYNAMIC|COMPRESSED 고려(용량↓)
    • information_schema.tables로 상위 테이블 및 빈공간(data_free) 점검
  4. LTS(장기 통계) 이해
    • statistics는 기본 보존(설계상 장기). 줄이려면 애초에 기록 제외하거나 기간 지정 삭제OPTIMIZE.

운영 체크리스트

  1. 백업 우선: DB 덤프 + HA 스냅샷( .storage 포함 )
  2. 변경 이력: 변경 전후 SQL 결과 캡처(metadata_id, 행 수)
  3. 권한 최소화: DB 작업 계정 최소 권한, 운영 계정 분리
  4. 점검창: 병합/대규모 OPTIMIZE는 다운타임 또는 저부하 시간대
  5. 검증
    • UI 그래프 / 개발자도구 통계 탭
    • 샘플 쿼리로 기간·건수 대조
  6. 롤백 플랜: 오류 시 즉시 백업 복구 절차 준비

자주 겪는 트러블슈팅

  • 동일 entity_id로 만들었는데도 안 이어져 보인다
    → 레지스트리 잔존으로 인해 실제로는 다른 ID로 생성되었거나, 속성 불일치(단위/클래스 변경)로 통계에서 경고/비가시. SQL로 metadata_id 동일성 먼저 확인.
  • OPTIMIZE 했는데 용량이 안 줄고 더 커졌다
    → InnoDB 재작성 특성/채움비율 영향. file_per_table=ON 확인, 불필요 인덱스/행포맷/압축 검토, 필요 시 덤프→리스토어 전략.
  • 히스토리 일부만 새 센서로 합치고 싶다
    → 절차 C처럼 기간 분할 UPDATE로 충돌 없이 이관.

최종 실행 체크

  1. 가능한 한 삭제하지 말고 동일 entity_id 유지
  2. 불가피한 삭제라면 레지스트리 클린업 → 동일 entity_id 재등록 → 속성 일치
  3. SQL로 메타 1행·metadata_id 연속성 확인
  4. 이미 끊겼다면 기간 분할 병합(수동)
  5. 필터·purge·공간 회수를 정례화
728x90
그리드형(광고전용)

댓글