class Telescope { constructor(socketUrl) { // Verhindere mehrfache Instanzen if (window.activeTelescopeInstance) { console.warn('Telescope instance already exists! Stopping old one...'); window.activeTelescopeInstance.stop(); } this.angle = 0; // Grad this.rotationSpeed = 6; // Grad pro Sekunde (1 Umdrehung = 360° pro Minute = 6°/sec) this.socket = io(socketUrl); this.isRunning = false; // Registriere als aktive Instanz window.activeTelescopeInstance = this; this.setupSocketListeners(); this.start(); } setupSocketListeners() { this.socket.on('connect', () => { console.log('Telescope connected to server'); }); this.socket.on('telescope-control', (data) => { this.handleControl(data); }); } start() { this.isRunning = true; // Kontinuierliche Rotation (1 U/min = 6°/sec) // Vernünftige Frequenz für gleichmäßige aber nicht chaotische Bewegung this.rotationInterval = setInterval(() => { if (this.isRunning) { this.angle = (this.angle + this.rotationSpeed / 60) % 360; // Update 60x pro Sekunde } }, 1000 / 60); // 60 FPS - das ist völlig ausreichend // Position senden (1x pro Sekunde - Visualisierung interpoliert lokal) this.broadcastInterval = setInterval(() => { if (this.isRunning) { this.broadcastPosition(); } }, 1000); // Zurück zu 1 Sekunde } stop() { this.isRunning = false; if (this.rotationInterval) clearInterval(this.rotationInterval); if (this.broadcastInterval) clearInterval(this.broadcastInterval); // Entferne Referenz als aktive Instanz if (window.activeTelescopeInstance === this) { window.activeTelescopeInstance = null; } } broadcastPosition() { const data = { angle: this.angle, timestamp: Date.now() }; this.socket.emit('telescope-position', data); console.log(`[Telescope] Broadcasting position: ${this.angle.toFixed(1)}°`); } handleControl(data) { switch (data.command) { case 'adjust': this.adjustPosition(data.degrees); break; case 'stop': this.stop(); break; case 'start': this.start(); break; } } adjustPosition(degrees) { this.angle = (this.angle + degrees + 360) % 360; console.log(`Telescope adjusted by ${degrees}°, new position: ${this.angle.toFixed(1)}°`); this.broadcastPosition(); // Sofort neue Position senden } // Manuelle Steuerung für Testing adjustBy15CW() { this.adjustPosition(15); } adjustBy15CCW() { this.adjustPosition(-15); } adjustBy45CW() { this.adjustPosition(45); } adjustBy45CCW() { this.adjustPosition(-45); } } // Wenn wir in einem Browser sind, NICHT automatisch initialisieren // Die Visualisierung wird das Teleskop kontrollieren if (typeof window !== 'undefined') { // Nur die Klasse verfügbar machen, aber noch nicht instanziieren window.Telescope = Telescope; } // Node.js Export für separate Prozesse if (typeof module !== 'undefined' && module.exports) { module.exports = Telescope; }