/** * RAG 검색 챗봇 장치 제어 JavaScript */ // 장치 제어 모듈 const DeviceControl = { // 장치 제어 상태 isConnected: false, isStatusChecked: false, isLoadingPrograms: false, programsList: [], // DOM 요소들 elements: { // 탭 및 섹션 deviceTab: null, deviceSection: null, // 연결 관련 deviceServerUrlInput: null, connectDeviceServerBtn: null, deviceConnectionStatus: null, // 기본 기능 deviceBasicFunctions: null, checkDeviceStatusBtn: null, deviceStatusResult: null, // 프로그램 실행 deviceProgramControl: null, getProgramsBtn: null, programsList: null, programSelectDropdown: null, executeProgramBtn: null, executeResult: null }, // 모듈 초기화 init: function() { console.log('장치 제어 모듈 초기화 중...'); // DOM 요소 참조 가져오기 this.initElements(); // 이벤트 리스너 등록 this.initEventListeners(); console.log('장치 제어 모듈 초기화 완료'); }, // DOM 요소 참조 초기화 initElements: function() { // 탭 및 섹션 this.elements.deviceTab = document.getElementById('deviceTab'); this.elements.deviceSection = document.getElementById('deviceSection'); // 연결 관련 this.elements.deviceServerUrlInput = document.getElementById('deviceServerUrlInput'); this.elements.connectDeviceServerBtn = document.getElementById('connectDeviceServerBtn'); this.elements.deviceConnectionStatus = document.getElementById('deviceConnectionStatus'); // 기본 기능 this.elements.deviceBasicFunctions = document.getElementById('deviceBasicFunctions'); this.elements.checkDeviceStatusBtn = document.getElementById('checkDeviceStatusBtn'); this.elements.deviceStatusResult = document.getElementById('deviceStatusResult'); // 프로그램 실행 this.elements.deviceProgramControl = document.getElementById('deviceProgramControl'); this.elements.getProgramsBtn = document.getElementById('getProgramsBtn'); this.elements.programsList = document.getElementById('programsList'); this.elements.programSelectDropdown = document.getElementById('programSelectDropdown'); this.elements.executeProgramBtn = document.getElementById('executeProgramBtn'); this.elements.executeResult = document.getElementById('executeResult'); console.log('장치 제어 DOM 요소 참조 초기화 완료'); }, // 이벤트 리스너 등록 initEventListeners: function() { // 탭 전환 if (this.elements.deviceTab) { this.elements.deviceTab.addEventListener('click', () => { console.log('장치 제어 탭 클릭'); this.switchToDeviceTab(); }); } // 서버 연결 if (this.elements.connectDeviceServerBtn) { this.elements.connectDeviceServerBtn.addEventListener('click', () => { console.log('장치 서버 연결 버튼 클릭'); this.connectServer(); }); } // 엔터 키로 연결 if (this.elements.deviceServerUrlInput) { this.elements.deviceServerUrlInput.addEventListener('keydown', (event) => { if (event.key === 'Enter') { console.log('장치 서버 URL 입력 필드에서 엔터 키 감지'); event.preventDefault(); this.connectServer(); } }); } // 장치 상태 확인 if (this.elements.checkDeviceStatusBtn) { this.elements.checkDeviceStatusBtn.addEventListener('click', () => { console.log('장치 상태 확인 버튼 클릭'); this.checkDeviceStatus(); }); } // 프로그램 목록 조회 if (this.elements.getProgramsBtn) { this.elements.getProgramsBtn.addEventListener('click', () => { console.log('프로그램 목록 새로고침 버튼 클릭'); this.loadProgramsList(); }); } // 프로그램 선택 변경 if (this.elements.programSelectDropdown) { this.elements.programSelectDropdown.addEventListener('change', (event) => { console.log(`프로그램 선택 변경: ${event.target.value}`); this.updateExecuteButton(); }); } // 프로그램 실행 if (this.elements.executeProgramBtn) { this.elements.executeProgramBtn.addEventListener('click', () => { const programId = this.elements.programSelectDropdown.value; console.log(`프로그램 실행 버튼 클릭, 선택된 ID: ${programId}`); this.executeProgram(programId); }); } console.log('장치 제어 이벤트 리스너 등록 완료'); }, // 장치 제어 탭으로 전환 switchToDeviceTab: function() { // 모든 탭과 탭 콘텐츠 비활성화 const tabs = document.querySelectorAll('.tab'); const tabContents = document.querySelectorAll('.tab-content'); tabs.forEach(tab => tab.classList.remove('active')); tabContents.forEach(content => content.classList.remove('active')); // 장치 제어 탭 활성화 this.elements.deviceTab.classList.add('active'); this.elements.deviceSection.classList.add('active'); console.log('장치 제어 탭으로 전환 완료'); }, // 서버 연결 함수 connectServer: async function() { // URL 가져오기 (입력된 것이 있으면 백업으로 사용) const inputUrl = this.elements.deviceServerUrlInput.value.trim(); // 연결 시도 중 UI 업데이트 this.elements.connectDeviceServerBtn.disabled = true; this.updateConnectionStatus('connecting', '환경변수에 저장된 서버로 연결 시도 중...'); try { console.log('환경변수에 저장된 장치 서버로 연결 시도'); // 백엔드 API 호출하여 서버 상태 확인 const response = await AppUtils.fetchWithTimeout('/api/device/status', { method: 'GET' }, 10000); // 10초 타임아웃 const data = await response.json(); if (response.ok && data.success) { // 연결 성공 console.log('환경변수 설정 장치 서버 연결 성공:', data); this.isConnected = true; this.updateConnectionStatus('connected', `서버 연결 성공! 상태: ${data.server_status || '정상'}`); // 기능 UI 활성화 this.elements.deviceBasicFunctions.classList.add('active'); this.elements.deviceProgramControl.classList.add('active'); // 장치 상태 자동 체크 this.checkDeviceStatus(); // 프로그램 목록 자동 로드 this.loadProgramsList(); // 시스템 알림 AppUtils.addSystemNotification(`장치 관리 서버 연결 성공! (환경변수 URL)`); } else { // 환경변수 URL 연결 실패, 입력된 URL로 시도 console.warn('환경변수 설정 장치 서버 연결 실패, 입력 URL로 재시도합니다:', data); // 입력 URL이 있는지 확인 if (!inputUrl) { console.error('입력된 URL이 없어 연결 실패'); this.isConnected = false; this.updateConnectionStatus('error', '환경변수 URL 연결 실패 및 입력된 URL이 없습니다. URL을 입력해주세요.'); return; } // 입력 URL로 재시도 this.updateConnectionStatus('connecting', `입력 URL(${inputUrl})로 연결 시도 중...`); console.log(`입력한 URL로 장치 서버 연결 시도: ${inputUrl}`); // 백엔드 API 호출 - 입력 URL 사용 const customUrlResponse = await AppUtils.fetchWithTimeout('/api/device/connect', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url: inputUrl }) }, 10000); const customUrlData = await customUrlResponse.json(); if (customUrlResponse.ok && customUrlData.success) { // 입력 URL 연결 성공 console.log('입력 URL 장치 서버 연결 성공:', customUrlData); this.isConnected = true; this.updateConnectionStatus('connected', `서버 연결 성공! 상태: ${customUrlData.server_status || '정상'}`); // 기능 UI 활성화 this.elements.deviceBasicFunctions.classList.add('active'); this.elements.deviceProgramControl.classList.add('active'); // 장치 상태 자동 체크 this.checkDeviceStatus(); // 프로그램 목록 자동 로드 this.loadProgramsList(); // 시스템 알림 AppUtils.addSystemNotification(`장치 관리 서버 연결 성공! (${inputUrl})`); } else { // 입력 URL 연결 실패 console.error('입력 URL 장치 서버 연결 실패:', customUrlData); this.isConnected = false; this.updateConnectionStatus('error', `서버 연결 실패: ${customUrlData.error || '서버 응답 오류'}`); } } } catch (error) { // 예외 발생 console.error('서버 연결 중 오류 발생:', error); this.isConnected = false; // 환경변수 URL 연결 실패, 입력된 URL로 시도 if (inputUrl) { console.warn('환경변수 URL 연결 시 오류 발생, 입력 URL로 재시도합니다'); try { // 입력 URL로 재시도 this.updateConnectionStatus('connecting', `입력 URL(${inputUrl})로 연결 시도 중...`); console.log(`입력한 URL로 장치 서버 연결 시도: ${inputUrl}`); // 백엔드 API 호출 - 입력 URL 사용 const customUrlResponse = await AppUtils.fetchWithTimeout('/api/device/connect', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url: inputUrl }) }, 10000); const customUrlData = await customUrlResponse.json(); if (customUrlResponse.ok && customUrlData.success) { // 입력 URL 연결 성공 console.log('입력 URL 장치 서버 연결 성공:', customUrlData); this.isConnected = true; this.updateConnectionStatus('connected', `서버 연결 성공! 상태: ${customUrlData.server_status || '정상'}`); // 기능 UI 활성화 this.elements.deviceBasicFunctions.classList.add('active'); this.elements.deviceProgramControl.classList.add('active'); // 장치 상태 자동 체크 this.checkDeviceStatus(); // 프로그램 목록 자동 로드 this.loadProgramsList(); // 시스템 알림 AppUtils.addSystemNotification(`장치 관리 서버 연결 성공! (${inputUrl})`); return; // 성공하면 여기서 종료 } else { // 입력 URL 연결 실패 console.error('입력 URL 장치 서버 연결 실패:', customUrlData); this.updateConnectionStatus('error', `서버 연결 실패: ${customUrlData.error || '서버 응답 오류'}`); } } catch (inputUrlError) { // 입력 URL로 재시도 중 오류 console.error('입력 URL로 재시도 중 오류 발생:', inputUrlError); if (inputUrlError.message.includes('시간이 초과')) { this.updateConnectionStatus('error', '서버 연결 시간 초과. 서버가 실행 중인지 확인해주세요.'); } else { this.updateConnectionStatus('error', `서버 연결 오류: ${inputUrlError.message}`); } } } else { // 텍스트박스에 URL이 없는 경우 if (error.message.includes('시간이 초과')) { this.updateConnectionStatus('error', '환경변수 URL 연결 시간 초과. URL을 입력하여 다시 시도해주세요.'); } else { this.updateConnectionStatus('error', `환경변수 URL 연결 오류. URL을 입력하여 다시 시도해주세요: ${error.message}`); } } } finally { // 버튼 다시 활성화 this.elements.connectDeviceServerBtn.disabled = false; } }, // 연결 상태 업데이트 updateConnectionStatus: function(status, message) { const statusElement = this.elements.deviceConnectionStatus; // 모든 상태 클래스 제거 statusElement.classList.remove('connected', 'disconnected', 'error', 'connecting'); // 상태에 따라 클래스 추가 statusElement.classList.add(status); // 메시지 업데이트 statusElement.textContent = message; console.log(`연결 상태 업데이트: ${status} - ${message}`); }, // 장치 상태 확인 checkDeviceStatus: async function() { if (!this.isConnected) { this.elements.deviceStatusResult.value = '오류: 먼저 서버에 연결해야 합니다.'; console.error('장치 상태 확인 시도 중 오류: 서버 연결 안됨'); return; } // 상태 확인 중 UI 업데이트 this.elements.checkDeviceStatusBtn.disabled = true; this.elements.deviceStatusResult.value = '장치 상태 확인 중...'; try { console.log('장치 상태 확인 요청 전송'); // 백엔드 API 호출 const response = await AppUtils.fetchWithTimeout('/api/device/status', { method: 'GET' }); const data = await response.json(); if (response.ok && data.success) { // 상태 확인 성공 console.log('장치 상태 확인 성공:', data); this.isStatusChecked = true; this.elements.deviceStatusResult.value = JSON.stringify(data, null, 2); } else { // 상태 확인 실패 console.error('장치 상태 확인 실패:', data); this.elements.deviceStatusResult.value = `상태 확인 실패: ${data.error || '알 수 없는 오류'}`; } } catch (error) { // 예외 발생 console.error('장치 상태 확인 중 오류 발생:', error); this.elements.deviceStatusResult.value = `상태 확인 중 오류 발생: ${error.message}`; } finally { // 버튼 다시 활성화 this.elements.checkDeviceStatusBtn.disabled = false; } }, // 프로그램 목록 조회 loadProgramsList: async function() { if (!this.isConnected) { this.showProgramsError('오류: 먼저 서버에 연결해야 합니다.'); console.error('프로그램 목록 조회 시도 중 오류: 서버 연결 안됨'); return; } // 이미 로딩 중이면 중복 요청 방지 if (this.isLoadingPrograms) { console.log('이미 프로그램 목록 로딩 중'); return; } // 로딩 중 UI 업데이트 this.isLoadingPrograms = true; this.elements.getProgramsBtn.disabled = true; this.elements.programsList.innerHTML = `
`; try { console.log('프로그램 목록 조회 요청 전송'); // 백엔드 API 호출 const response = await AppUtils.fetchWithTimeout('/api/device/programs', { method: 'GET' }); const data = await response.json(); if (response.ok && data.success) { // 목록 조회 성공 console.log('프로그램 목록 조회 성공:', data); this.programsList = data.programs || []; // 목록 표시 this.displayProgramsList(); // 드롭다운 업데이트 this.updateProgramsDropdown(); // 실행 버튼 상태 업데이트 this.updateExecuteButton(); } else { // 목록 조회 실패 console.error('프로그램 목록 조회 실패:', data); this.showProgramsError(`프로그램 목록 조회 실패: ${data.error || '알 수 없는 오류'}`); } } catch (error) { // 예외 발생 console.error('프로그램 목록 조회 중 오류 발생:', error); this.showProgramsError(`프로그램 목록 조회 중 오류 발생: ${error.message}`); } finally { // 로딩 상태 및 버튼 상태 복원 this.isLoadingPrograms = false; this.elements.getProgramsBtn.disabled = false; } }, // 프로그램 목록 표시 displayProgramsList: function() { const programsListElement = this.elements.programsList; if (!this.programsList || this.programsList.length === 0) { programsListElement.innerHTML = ` `; return; } // 테이블 형태로 프로그램 목록 표시 let html = `이름 | 설명 | 경로 |
---|---|---|
${AppUtils.escapeHtml(program.name || '알 수 없음')} | ${AppUtils.escapeHtml(program.description || '-')} | ${AppUtils.escapeHtml(program.path || '-')} |