Spaces:
Running
Running
/** | |
* 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 = ` | |
<div class="loading-message"> | |
${AppUtils.createLoadingSpinner()} ํ๋ก๊ทธ๋จ ๋ชฉ๋ก ๋ก๋ ์ค... | |
</div> | |
`; | |
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 = ` | |
<div class="no-programs-message"> | |
<i class="fas fa-info-circle"></i> ๋ฑ๋ก๋ ํ๋ก๊ทธ๋จ์ด ์์ต๋๋ค. | |
</div> | |
`; | |
return; | |
} | |
// ํ ์ด๋ธ ํํ๋ก ํ๋ก๊ทธ๋จ ๋ชฉ๋ก ํ์ | |
let html = ` | |
<table class="program-list"> | |
<thead> | |
<tr> | |
<th>์ด๋ฆ</th> | |
<th>์ค๋ช </th> | |
<th>๊ฒฝ๋ก</th> | |
</tr> | |
</thead> | |
<tbody> | |
`; | |
// ํ๋ก๊ทธ๋จ ํญ๋ชฉ ์์ฑ | |
this.programsList.forEach(program => { | |
html += ` | |
<tr> | |
<td>${AppUtils.escapeHtml(program.name || '์ ์ ์์')}</td> | |
<td>${AppUtils.escapeHtml(program.description || '-')}</td> | |
<td>${AppUtils.escapeHtml(program.path || '-')}</td> | |
</tr> | |
`; | |
}); | |
html += ` | |
</tbody> | |
</table> | |
<div style="margin-top: 10px; font-size: 0.9em; color: #666;"> | |
์ด ${this.programsList.length}๊ฐ ํ๋ก๊ทธ๋จ | |
</div> | |
`; | |
programsListElement.innerHTML = html; | |
}, | |
// ํ๋ก๊ทธ๋จ ๋๋กญ๋ค์ด ์ ๋ฐ์ดํธ | |
updateProgramsDropdown: function() { | |
const dropdown = this.elements.programSelectDropdown; | |
// ๊ธฐ์กด ์ต์ ์ ๊ฑฐ | |
dropdown.innerHTML = ''; | |
// ๊ธฐ๋ณธ ์ต์ ์ถ๊ฐ | |
const defaultOption = document.createElement('option'); | |
defaultOption.value = ''; | |
defaultOption.textContent = this.programsList.length > 0 | |
? '-- ์คํํ ํ๋ก๊ทธ๋จ ์ ํ --' | |
: '-- ํ๋ก๊ทธ๋จ ์์ --'; | |
dropdown.appendChild(defaultOption); | |
// ํ๋ก๊ทธ๋จ ์ต์ ์ถ๊ฐ | |
this.programsList.forEach(program => { | |
const option = document.createElement('option'); | |
option.value = program.id || ''; | |
option.textContent = program.name || '์ ์ ์์'; | |
// ์ค๋ช ์ด ์์ผ๋ฉด ๊ดํธ๋ก ์ถ๊ฐ | |
if (program.description) { | |
option.textContent += ` (${program.description})`; | |
} | |
dropdown.appendChild(option); | |
}); | |
}, | |
// ์คํ ๋ฒํผ ์ํ ์ ๋ฐ์ดํธ | |
updateExecuteButton: function() { | |
const dropdown = this.elements.programSelectDropdown; | |
const executeBtn = this.elements.executeProgramBtn; | |
// ์ ํ๋ ํ๋ก๊ทธ๋จ์ด ์์ ๋๋ง ๋ฒํผ ํ์ฑํ | |
executeBtn.disabled = !dropdown.value; | |
}, | |
// ํ๋ก๊ทธ๋จ ์คํ | |
executeProgram: async function(programId) { | |
if (!this.isConnected) { | |
this.showExecuteResult('error', '์ค๋ฅ: ๋จผ์ ์๋ฒ์ ์ฐ๊ฒฐํด์ผ ํฉ๋๋ค.'); | |
console.error('ํ๋ก๊ทธ๋จ ์คํ ์๋ ์ค ์ค๋ฅ: ์๋ฒ ์ฐ๊ฒฐ ์๋จ'); | |
return; | |
} | |
if (!programId) { | |
this.showExecuteResult('error', '์ค๋ฅ: ์คํํ ํ๋ก๊ทธ๋จ์ ์ ํํด์ฃผ์ธ์.'); | |
console.error('ํ๋ก๊ทธ๋จ ์คํ ์๋ ์ค ์ค๋ฅ: ํ๋ก๊ทธ๋จ ID ์์'); | |
return; | |
} | |
// ์คํ ์ค UI ์ ๋ฐ์ดํธ | |
this.elements.executeProgramBtn.disabled = true; | |
this.showExecuteResult('loading', 'ํ๋ก๊ทธ๋จ ์คํ ์ค...'); | |
try { | |
console.log(`ํ๋ก๊ทธ๋จ ์คํ ์์ฒญ ์ ์ก: ${programId}`); | |
// ๋ฐฑ์๋ API ํธ์ถ | |
const response = await AppUtils.fetchWithTimeout(`/api/device/programs/${programId}/execute`, { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json' | |
}, | |
body: JSON.stringify({}) | |
}, 15000); // 15์ด ํ์์์ (์คํ์ ์๊ฐ์ด ๋ ๊ฑธ๋ฆด ์ ์์) | |
const data = await response.json(); | |
if (response.ok && data.success) { | |
// ์คํ ์ฑ๊ณต | |
console.log('ํ๋ก๊ทธ๋จ ์คํ ์ฑ๊ณต:', data); | |
this.showExecuteResult('success', `์คํ ์ฑ๊ณต: ${data.message || 'ํ๋ก๊ทธ๋จ์ด ์ฑ๊ณต์ ์ผ๋ก ์คํ๋์์ต๋๋ค.'}`); | |
// ์์คํ ์๋ฆผ | |
AppUtils.addSystemNotification(`ํ๋ก๊ทธ๋จ ์คํ ์ฑ๊ณต: ${this.getSelectedProgramName()}`); | |
} else { | |
// ์คํ ์คํจ | |
console.error('ํ๋ก๊ทธ๋จ ์คํ ์คํจ:', data); | |
this.showExecuteResult('error', `์คํ ์คํจ: ${data.error || '์ ์ ์๋ ์ค๋ฅ'}`); | |
} | |
} catch (error) { | |
// ์์ธ ๋ฐ์ | |
console.error('ํ๋ก๊ทธ๋จ ์คํ ์ค ์ค๋ฅ ๋ฐ์:', error); | |
if (error.message.includes('์๊ฐ์ด ์ด๊ณผ')) { | |
this.showExecuteResult('error', 'ํ๋ก๊ทธ๋จ ์คํ ์์ฒญ ์๊ฐ ์ด๊ณผ. ์๋ฒ ์๋ต์ด ์์ต๋๋ค.'); | |
} else { | |
this.showExecuteResult('error', `ํ๋ก๊ทธ๋จ ์คํ ์ค ์ค๋ฅ ๋ฐ์: ${error.message}`); | |
} | |
} finally { | |
// ๋ฒํผ ๋ค์ ํ์ฑํ | |
this.elements.executeProgramBtn.disabled = false; | |
} | |
}, | |
// ์ ํ๋ ํ๋ก๊ทธ๋จ ์ด๋ฆ ๊ฐ์ ธ์ค๊ธฐ | |
getSelectedProgramName: function() { | |
const dropdown = this.elements.programSelectDropdown; | |
const selectedOption = dropdown.options[dropdown.selectedIndex]; | |
return selectedOption ? selectedOption.textContent : '์ ์ ์๋ ํ๋ก๊ทธ๋จ'; | |
}, | |
// ํ๋ก๊ทธ๋จ ๋ชฉ๋ก ์ค๋ฅ ํ์ | |
showProgramsError: function(errorMessage) { | |
this.elements.programsList.innerHTML = ` | |
<div class="error-message"> | |
<i class="fas fa-exclamation-circle"></i> ${errorMessage} | |
<button class="retry-button" id="retryLoadProgramsBtn"> | |
<i class="fas fa-sync"></i> ๋ค์ ์๋ | |
</button> | |
</div> | |
`; | |
// ์ฌ์๋ ๋ฒํผ ์ด๋ฒคํธ ๋ฆฌ์ค๋ | |
document.getElementById('retryLoadProgramsBtn').addEventListener('click', () => { | |
console.log('ํ๋ก๊ทธ๋จ ๋ชฉ๋ก ์ฌ์๋ ๋ฒํผ ํด๋ฆญ'); | |
this.loadProgramsList(); | |
}); | |
}, | |
// ์คํ ๊ฒฐ๊ณผ ํ์ | |
showExecuteResult: function(status, message) { | |
const resultElement = this.elements.executeResult; | |
// ๋ชจ๋ ์ํ ํด๋์ค ์ ๊ฑฐ | |
resultElement.classList.remove('success', 'error', 'warning'); | |
// ๋ด์ฉ ์ด๊ธฐํ | |
resultElement.innerHTML = ''; | |
// ์ํ์ ๋ฐ๋ผ ์ฒ๋ฆฌ | |
switch (status) { | |
case 'success': | |
resultElement.classList.add('success'); | |
resultElement.innerHTML = `<i class="fas fa-check-circle"></i> ${message}`; | |
break; | |
case 'error': | |
resultElement.classList.add('error'); | |
resultElement.innerHTML = `<i class="fas fa-exclamation-circle"></i> ${message}`; | |
break; | |
case 'warning': | |
resultElement.classList.add('warning'); | |
resultElement.innerHTML = `<i class="fas fa-exclamation-triangle"></i> ${message}`; | |
break; | |
case 'loading': | |
resultElement.innerHTML = `${AppUtils.createLoadingSpinner()} ${message}`; | |
break; | |
default: | |
resultElement.textContent = message; | |
} | |
} | |
}; | |
// ํ์ด์ง ๋ก๋ ์๋ฃ ์ ๋ชจ๋ ์ด๊ธฐํ | |
document.addEventListener('DOMContentLoaded', function() { | |
console.log('์ฅ์น ์ ์ด ๋ชจ๋ ๋ก๋๋จ'); | |
// DOM์ด ์์ ํ ๋ก๋๋ ํ ์ฝ๊ฐ์ ์ง์ฐ์ ๋๊ณ ์ด๊ธฐํ | |
setTimeout(() => { | |
DeviceControl.init(); | |
}, 100); | |
}); | |