const WeatherApp = { cachedHistoryData: [], cachedForecastData: [], currentPage: 1, itemsPerPage: 10, filteredDevices: [], init() { WeatherUtils.initializeDateInputs(); WeatherMap.init(window.TIANDITU_KEY || ''); WeatherMap.loadStations(); setInterval(() => this.updateOnlineDevices(), 30000); this.bindUI(); window.addEventListener('query-history-data', () => this.queryHistoryData()); }, bindUI() { const stationInput = document.getElementById('stationInput'); if (stationInput) { stationInput.addEventListener('input', function() { this.value = this.value.toUpperCase().replace(/[^0-9A-F]/g, ''); }); stationInput.addEventListener('change', function() { const value = this.value.trim(); if (!value) return; if (/^[0-9A-F]+$/i.test(value)) { if (value.length <= 6) this.value = WeatherUtils.hexToDecimal(value); } else { const num = parseInt(value); if (!isNaN(num)) this.value = num.toString(); } }); } const showDeviceListBtn = document.getElementById('showDeviceList'); const modal = document.getElementById('deviceModal'); const closeBtn = document.querySelector('.close-modal'); const prevPageBtn = document.getElementById('prevPage'); const nextPageBtn = document.getElementById('nextPage'); const deviceListEl = document.getElementById('deviceList'); if (deviceListEl && modal) { deviceListEl.addEventListener('click', (e) => { const deviceItem = e.target.closest('.device-item'); if (!deviceItem) return; const decimalId = deviceItem.getAttribute('data-decimal-id'); const input = document.getElementById('stationInput'); if (input) input.value = decimalId; window.dispatchEvent(new CustomEvent('close-device-modal')); this.queryHistoryData(); }); } const showPastForecast = document.getElementById('showPastForecast'); if (showPastForecast) { showPastForecast.addEventListener('change', () => { WeatherTable.display(this.cachedHistoryData, this.cachedForecastData); }); } const legendMode = document.getElementById('legendMode'); if (legendMode) { legendMode.addEventListener('change', (e) => { const mode = e.target.value; if (window.WeatherChart && typeof window.WeatherChart.applyLegendMode === 'function') { window.WeatherChart.applyLegendMode(mode); } }); } window.switchLayer = (type) => WeatherMap.switchLayer(type); window.toggleMap = () => WeatherMap.toggleMap(); window.queryHistoryData = () => this.queryHistoryData(); }, updateDeviceList(page = 1) { const deviceListContainer = document.getElementById('deviceList'); if (!deviceListContainer) return; deviceListContainer.innerHTML = ''; this.filteredDevices = (WeatherMap.stations || []) .filter(station => station.device_type === 'WH65LP') .sort((a, b) => { const aOnline = WeatherUtils.isDeviceOnline(a.last_update); const bOnline = WeatherUtils.isDeviceOnline(b.last_update); if (aOnline === bOnline) return 0; return aOnline ? -1 : 1; }); const totalPages = Math.ceil(this.filteredDevices.length / this.itemsPerPage) || 1; this.currentPage = Math.min(Math.max(1, page), totalPages); const currentPageEl = document.getElementById('currentPage'); const totalPagesEl = document.getElementById('totalPages'); const prevBtn = document.getElementById('prevPage'); const nextBtn = document.getElementById('nextPage'); if (currentPageEl) currentPageEl.textContent = this.currentPage; if (totalPagesEl) totalPagesEl.textContent = totalPages; if (prevBtn) prevBtn.disabled = this.currentPage <= 1; if (nextBtn) nextBtn.disabled = this.currentPage >= totalPages; const startIndex = (this.currentPage - 1) * this.itemsPerPage; const endIndex = startIndex + this.itemsPerPage; const currentDevices = this.filteredDevices.slice(startIndex, endIndex); currentDevices.forEach(device => { const isOnline = WeatherUtils.isDeviceOnline(device.last_update); const deviceItem = document.createElement('div'); deviceItem.className = 'device-item'; deviceItem.setAttribute('data-decimal-id', device.decimal_id); deviceItem.innerHTML = `