λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
개발 일지 πŸ‘©‍πŸ’»

Alarm Popup μ‹œμŠ€ν…œ μ—°κ΅¬λ…ΈνŠΈ

by chuyj15 2025. 9. 22.
728x90
λ°˜μ‘ν˜•
SMALL

Alarm Popup μ‹œμŠ€ν…œ μ—°κ΅¬λ…ΈνŠΈ

πŸ“‹ κ°œμš”

alarm-popup.jsλŠ” μ‹€μ‹œκ°„ μ•ŒλžŒ νŒμ—… μ‹œμŠ€ν…œμ„ κ΅¬ν˜„ν•œ JavaScript λͺ¨λ“ˆμž…λ‹ˆλ‹€. ν™”μž¬, κ°€μŠ€, μΉ¨μž… λ“±μ˜ λ³΄μ•ˆ μ•ŒλžŒμ„ μ‹€μ‹œκ°„μœΌλ‘œ λͺ¨λ‹ˆν„°λ§ν•˜κ³  μ‚¬μš©μžμ—κ²Œ νŒμ—… ν˜•νƒœλ‘œ μ•Œλ¦Όμ„ μ œκ³΅ν•©λ‹ˆλ‹€.

πŸ—οΈ μ‹œμŠ€ν…œ μ•„ν‚€ν…μ²˜

μ£Όμš” 클래슀 ꡬ쑰

1. PopupDB 클래슀

  • λͺ©μ : IndexedDBλ₯Ό ν™œμš©ν•œ μ•ŒλžŒ 데이터 영ꡬ μ €μž₯
  • νŠΉμ§•:
    • λΈŒλΌμš°μ € μž¬μ‹œμž‘ μ‹œμ—λ„ μ•ŒλžŒ μƒνƒœ 볡원
    • 비동기 처리둜 μ„±λŠ₯ μ΅œμ ν™”
    • μ—λŸ¬ 처리 및 폴백 λ©”μ»€λ‹ˆμ¦˜
class PopupDB {
    constructor() {
        this.dbName = 'AlarmPopupDB';
        this.version = 1;
        this.storeName = 'popups';
    }
}

2. AlarmPopupManager 클래슀

  • λͺ©μ : μ•ŒλžŒ νŒμ—… μ‹œμŠ€ν…œμ˜ 전체 관리
  • 핡심 κΈ°λŠ₯:
    • μ‹€μ‹œκ°„ μ•ŒλžŒ 폴링 (4초 간격)
    • μ•ŒλžŒ κ·Έλ£Ήν•‘ 및 λΆ„λ₯˜
    • νŒμ—… UI 생성 및 관리
    • μ•Œλ¦ΌμŒ μž¬μƒ
    • λ“œλž˜κ·Έ μ•€ λ“œλ‘­ κΈ°λŠ₯

πŸ”„ 핡심 μ›Œν¬ν”Œλ‘œμš°

1. μ΄ˆκΈ°ν™” κ³Όμ •

μ‹œμŠ€ν…œ μ‹œμž‘ β†’ IndexedDB μ΄ˆκΈ°ν™” β†’ μ €μž₯된 νŒμ—… 볡원 β†’ 폴링 μ‹œμž‘

2. μ•ŒλžŒ 처리 κ³Όμ •

API 폴링 β†’ μƒˆ μ•ŒλžŒ μˆ˜μ‹  β†’ μ•ŒλžŒ κ·Έλ£Ήν•‘ β†’ νŒμ—… 생성/μ—…λ°μ΄νŠΈ β†’ μ•Œλ¦ΌμŒ μž¬μƒ

3. μ•ŒλžŒ κ·Έλ£Ήν•‘ 둜직

  • ν™”μž¬/κ°€μŠ€/μΉ¨μž… μ•ŒλžŒ: alarmType_deviceGroupId ν˜•νƒœλ‘œ κ·Έλ£Ήν•‘
  • 기타 μ•ŒλžŒ: alarmType만으둜 κ·Έλ£Ήν•‘
  • μ•ŒλžŒ νƒ€μž… μ •κ·œν™”:
    • 17, 193 β†’ 1 (ν™”μž¬)
    • 18 β†’ 2 (κ°€μŠ€)
    • 19 β†’ 3 (μΉ¨μž…)

🎡 μ•Œλ¦ΌμŒ μ‹œμŠ€ν…œ

μ•Œλ¦ΌμŒ λ‘œλ“œ 및 μž¬μƒ

async loadNotificationSound() {
    const soundSetting = localStorage.getItem('clientNotificationSound');
    if (soundSetting) {
        this.notificationSoundPath = soundSetting;
    }
}

playNotificationSound() {
    const audio = new Audio(this.notificationSoundPath);
    audio.volume = 1;
    audio.play().catch(error => {
        console.warn('μ•Œλ¦ΌμŒ μž¬μƒ μ‹€νŒ¨:', error);
    });
}

πŸ’Ύ 데이터 μ˜μ†μ„±

IndexedDB ν™œμš©

  • μ €μž₯μ†Œ 이름: AlarmPopupDB
  • μŠ€ν† μ–΄ 이름: popups
  • ν‚€ ꡬ쑰: alarmType_deviceGroupId λ˜λŠ” alarmType
  • 데이터 ꡬ쑰:
    {
        key: string,
        data: {
            alarmType: string,
            alarmTypeName: string,
            deviceGroupId: string,
            deviceGroupName: string,
            alarmList: Array,
            timestamp: number
        }
    }

🎨 UI/UX κΈ°λŠ₯

νŒμ—… UI νŠΉμ§•

  • 동적 μœ„μΉ˜ μ‘°μ •: κΈ°μ‘΄ νŒμ—…κ³Ό κ²ΉμΉ˜μ§€ μ•Šλ„λ‘ μžλ™ 배치
  • λ“œλž˜κ·Έ μ•€ λ“œλ‘­: μ‚¬μš©μžκ°€ νŒμ—… μœ„μΉ˜ μ‘°μ • κ°€λŠ₯
  • 색상 μ½”λ”©: μ•ŒλžŒ νƒ€μž…λ³„ ꡬ뢄 (CSS 클래슀: color-{alarmType})
  • λ°˜μ‘ν˜• ν…Œμ΄λΈ”: μ•ŒλžŒ 정보λ₯Ό ν…Œμ΄λΈ” ν˜•νƒœλ‘œ ν‘œμ‹œ

λ“œλž˜κ·Έ κΈ°λŠ₯ κ΅¬ν˜„

const onMouseDown = (e) => {
    isDragging = true;
    const rect = popup.getBoundingClientRect();
    startX = e.clientX - rect.left;
    startY = e.clientY - rect.top;
    // 이벀트 λ¦¬μŠ€λ„ˆ 등둝
};

πŸ”§ μ£Όμš” κΈ°λŠ₯ 뢄석

1. μ‹€μ‹œκ°„ 폴링 μ‹œμŠ€ν…œ

  • 폴링 간격: 4초
  • API μ—”λ“œν¬μΈνŠΈ: /api/monitoring/select-alarm-popup-message
  • λ§ˆμ§€λ§‰ μˆ˜μ‹  μ•ŒλžŒ ID 좔적: 쀑볡 μ•ŒλžŒ λ°©μ§€

2. μ•ŒλžŒ λΆ„λ₯˜ 및 처리

function normalizeAlarmType(type) {
    if (type === '17' || type === '193') return '1';
    if (type === '18') return '2';
    if (type === '19') return '3';
    return type;
}

3. κ·Έλ£Ή ν•΄μ œ κΈ°λŠ₯

  • ν™”μž¬ μ•ŒλžŒ: μ„Όμ„œ 볡ꡬ/ν™”μž¬ ν•΄μ œ μ•Œλ¦Ό ν›„ ν•΄μ œ κ°€λŠ₯
  • API 호좜: /api/monitoring/group-send-wave-alarm
  • νŒŒλΌλ―Έν„°: deviceGroupIds, alarmSetting

πŸ“Š μ„±λŠ₯ μ΅œμ ν™”

λ©”λͺ¨λ¦¬ 관리

  • λ©”λͺ¨λ¦¬ μΊμ‹œ: Map 객체둜 μ—΄λ¦° νŒμ—… 관리
  • 쀑볡 제거: alarmId κΈ°μ€€μœΌλ‘œ 쀑볡 μ•ŒλžŒ 필터링
  • 비동기 μ €μž₯: IndexedDB μ €μž₯ μ‹œ 메인 μŠ€λ ˆλ“œ λΈ”λ‘œν‚Ή λ°©μ§€

μ—λŸ¬ 처리

  • IndexedDB μ‹€νŒ¨ μ‹œ: λ©”λͺ¨λ¦¬ λͺ¨λ“œλ‘œ 폴백
  • μ•Œλ¦ΌμŒ μž¬μƒ μ‹€νŒ¨: μ‚¬μš©μž μƒν˜Έμž‘μš© ν•„μš” λ©”μ‹œμ§€ ν‘œμ‹œ
  • API 호좜 μ‹€νŒ¨: μ½˜μ†” 둜그 및 계속 폴링

πŸ“œ νžˆμŠ€ν† λ¦¬ κΈ°λŠ₯

24μ‹œκ°„ μ•ŒλžŒ νžˆμŠ€ν† λ¦¬

  • κΈ°λŠ₯: μ§€λ‚œ 24μ‹œκ°„ λ™μ•ˆμ˜ λͺ¨λ“  μ•ŒλžŒ 쑰회
  • API: /api/monitoring/select-alarm-popup-message-history
  • UI: 별도 νŒμ—…μœΌλ‘œ μ•ŒλžŒ λͺ©λ‘ ν‘œμ‹œ
window.showAlarmPopupHistory = function() {
    const now = new Date();
    const yesterday = new Date(now.getTime() - (24 * 60 * 60 * 1000));
    // API 호좜 및 UI 생성
}

πŸ” λ³΄μ•ˆ 고렀사항

μ•ŒλžŒ νƒ€μž…λ³„ μ œμ•½

  • ν™”μž¬ μ•ŒλžŒ (νƒ€μž… 1):
    • νŒμ—… κ°•μ œ λ‹«κΈ° λ°©μ§€
    • μ„Όμ„œ 볡ꡬ μ•Œλ¦Ό ν›„μ—λ§Œ ν•΄μ œ κ°€λŠ₯
    • κ·Έλ£Ή ν•΄μ œ κΈ°λŠ₯ μ œν•œ

데이터 검증

  • μ•ŒλžŒ 데이터 μœ νš¨μ„± 검사
  • deviceGroupId 쑴재 μ—¬λΆ€ 확인
  • μ‚¬μš©μž κΆŒν•œ 확인 (κ·Έλ£Ή ν•΄μ œ μ‹œ)

🌐 λΈŒλΌμš°μ € ν˜Έν™˜μ„±

지원 기술

  • IndexedDB: λͺ¨λ“  λͺ¨λ˜ λΈŒλΌμš°μ € 지원
  • Web Audio API: μ•Œλ¦ΌμŒ μž¬μƒ
  • localStorage: μ„€μ • μ €μž₯
  • Fetch API: μ„œλ²„ 톡신

폴백 λ©”μ»€λ‹ˆμ¦˜

  • IndexedDB μ‹€νŒ¨ μ‹œ λ©”λͺ¨λ¦¬ μ €μž₯μ†Œ μ‚¬μš©
  • μ•Œλ¦ΌμŒ μž¬μƒ μ‹€νŒ¨ μ‹œ 쑰용히 μ‹€νŒ¨ 처리

🎯 μ‚¬μš© μ‹œλ‚˜λ¦¬μ˜€

일반적인 μ‚¬μš© 흐름

  1. νŽ˜μ΄μ§€ λ‘œλ“œ: μ‹œμŠ€ν…œ μ΄ˆκΈ°ν™” 및 μ €μž₯된 νŒμ—… 볡원
  2. μ‹€μ‹œκ°„ λͺ¨λ‹ˆν„°λ§: 4μ΄ˆλ§ˆλ‹€ μƒˆλ‘œμš΄ μ•ŒλžŒ 확인
  3. μ•ŒλžŒ μˆ˜μ‹ : νŒμ—… 생성 및 μ•Œλ¦ΌμŒ μž¬μƒ
  4. μ‚¬μš©μž μƒν˜Έμž‘μš©: νŒμ—… 이동, κ·Έλ£Ή ν•΄μ œ, λ‹«κΈ°
  5. νžˆμŠ€ν† λ¦¬ 쑰회: κ³Όκ±° μ•ŒλžŒ λ‚΄μ—­ 확인

특수 상황 처리

  • λΈŒλΌμš°μ € μž¬μ‹œμž‘: IndexedDBμ—μ„œ νŒμ—… μƒνƒœ 볡원
  • 닀쀑 νƒ­: localStorageλ₯Ό ν†΅ν•œ 동기화
  • λ„€νŠΈμ›Œν¬ 였λ₯˜: 폴링 계속 μ‹œλ„

πŸ”§ μ„€μ • 및 μ»€μŠ€ν„°λ§ˆμ΄μ§•

μ£Όμš” μ„€μ •κ°’

this.pollInterval = 4000; // 폴링 간격 (4초)
this.warningMs = 30 * 1000; // κ²½κ³  μ‹œκ°„ (30초)
this.timeoutSidebarMs = 10 * 60 * 1000; // μ‚¬μ΄λ“œλ°” ν‘œμ‹œ μ‹œκ°„ (10λΆ„)

μ»€μŠ€ν„°λ§ˆμ΄μ§• 포인트

  • 폴링 간격 μ‘°μ •: μ„œλ²„ λΆ€ν•˜μ™€ μ‹€μ‹œκ°„μ„± κ· ν˜•
  • μ•Œλ¦ΌμŒ μ„€μ •: localStorageμ—μ„œ μ‚¬μš©μž μ •μ˜ μ‚¬μš΄λ“œ
  • UI ν…Œλ§ˆ: CSS 클래슀λ₯Ό ν†΅ν•œ μ•ŒλžŒ νƒ€μž…λ³„ μŠ€νƒ€μΌλ§

πŸ“ˆ λͺ¨λ‹ˆν„°λ§ 및 λ‘œκΉ…

둜그 레벨

  • INFO: 정상적인 μ•ŒλžŒ 처리 κ³Όμ •
  • WARN: 볡ꡬ κ°€λŠ₯ν•œ 였λ₯˜ (IndexedDB μ‹€νŒ¨ λ“±)
  • ERROR: μ€‘μš”ν•œ 였λ₯˜ (API 호좜 μ‹€νŒ¨ λ“±)

μ„±λŠ₯ λ©”νŠΈλ¦­

  • νŒμ—… 볡원 μ‹œκ°„: IndexedDBμ—μ„œ 데이터 λ‘œλ“œ μ‹œκ°„
  • 폴링 응닡 μ‹œκ°„: API 호좜 응닡 μ‹œκ°„
  • λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰: μ—΄λ¦° νŒμ—… μˆ˜μ™€ λ©”λͺ¨λ¦¬ μΊμ‹œ 크기

πŸš€ ν–₯ν›„ κ°œμ„  λ°©μ•ˆ

μ„±λŠ₯ μ΅œμ ν™”

  • WebSocket μ—°κ²°: 폴링 λŒ€μ‹  μ‹€μ‹œκ°„ ν‘Έμ‹œ μ•Œλ¦Ό
  • 가상화: λŒ€λŸ‰μ˜ μ•ŒλžŒ 데이터 효율적 λ Œλ”λ§
  • Service Worker: λ°±κ·ΈλΌμš΄λ“œμ—μ„œ μ•ŒλžŒ 처리

κΈ°λŠ₯ ν™•μž₯

  • μ•ŒλžŒ 필터링: μ‚¬μš©μž μ •μ˜ ν•„ν„° μ˜΅μ…˜
  • μ•ŒλžŒ μš°μ„ μˆœμœ„: μ€‘μš”λ„λ³„ νŒμ—… μŠ€νƒ€μΌλ§
  • λͺ¨λ°”일 μ΅œμ ν™”: ν„°μΉ˜ μΈν„°νŽ˜μ΄μŠ€ 지원

μ‚¬μš©μž κ²½ν—˜ κ°œμ„ 

  • ν‚€λ³΄λ“œ 단좕킀: νŒμ—… μ œμ–΄λ₯Ό μœ„ν•œ 단좕킀
  • μ ‘κ·Όμ„±: 슀크린 리더 지원
  • λ‹€κ΅­μ–΄: κ΅­μ œν™” 지원
728x90
λ°˜μ‘ν˜•
LIST