UNPKG

@jaarnio/tripplite-pdu-sdk

Version:

Unified Tripplite PDU SDK with integrated real-time WebSocket server for monitoring and control

214 lines (173 loc) β€’ 8.85 kB
#!/usr/bin/env node /** * Dashboard Client Example * * This example shows how to create a monitoring dashboard that connects to a TripplitePDUServer * and displays real-time load states and allows control actions. */ const TripplitePDUClient = require('@jaarnio/tripplite-pdu-sdk/src/client'); async function createDashboard() { console.log('πŸ“Š Starting PDU Dashboard Client...\n'); // Create client instance with event handlers const client = new TripplitePDUClient({ url: 'ws://localhost:8081', // Connect to your PDU server autoReconnect: true, // Automatically reconnect if disconnected reconnectInterval: 5000, // Reconnect every 5 seconds // Event handlers onConnect: () => { console.log('βœ… Connected to PDU server!'); console.log('πŸ”„ Subscribing to loads...\n'); // Subscribe to loads 1-8 for monitoring client.subscribe([1, 2, 3, 4, 5, 6, 7, 8]); }, onDisconnect: (code, reason) => { console.log(`❌ Disconnected from server: ${code} ${reason}`); console.log('πŸ”„ Will attempt to reconnect...\n'); }, onStateChange: (change) => { const timestamp = new Date().toLocaleTimeString(); const prevState = change.previousState === 'LOAD_STATE_ON' ? '🟒 ON' : 'πŸ”΄ OFF'; const currState = change.currentState === 'LOAD_STATE_ON' ? '🟒 ON' : 'πŸ”΄ OFF'; console.log(`[${timestamp}] πŸ”„ Load ${change.loadId} (${change.load.name}): ${prevState} β†’ ${currState}`); // Update dashboard display displayLoadStates(); }, onActionResult: (result) => { const timestamp = new Date().toLocaleTimeString(); const status = result.success ? 'βœ… SUCCESS' : '❌ FAILED'; console.log(`[${timestamp}] ⚑ Action ${result.action.toUpperCase()} on Load ${result.loadId}: ${status}`); if (!result.success && result.error) { console.log(` Error: ${result.error}`); } }, onError: (error) => { console.error('❌ Client error:', error.message); } }); try { // Connect to server console.log('πŸ”— Connecting to PDU server...'); await client.connect(); // Wait a moment for initial states to be received await new Promise(resolve => setTimeout(resolve, 1000)); // Display initial dashboard displayDashboard(); // Start interactive control startInteractiveControl(client); } catch (error) { console.error('❌ Failed to connect to PDU server:', error.message); console.log('πŸ’‘ Make sure your PDU server is running on ws://localhost:8081'); process.exit(1); } function displayDashboard() { console.clear(); console.log('╔══════════════════════════════════════════════════════════════╗'); console.log('β•‘ PDU DASHBOARD β•‘'); console.log('β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•'); console.log(''); displayLoadStates(); console.log(''); console.log('πŸ“ Commands:'); console.log(' on <load_id> - Turn load ON'); console.log(' off <load_id> - Turn load OFF'); console.log(' cycle <load_id> - Cycle load (OFFβ†’ON or ONβ†’OFF)'); console.log(' status - Show current status'); console.log(' stats - Request server statistics'); console.log(' ping - Ping server'); console.log(' quit - Exit dashboard'); console.log(''); console.log('πŸ’‘ Type a command and press Enter:'); } function displayLoadStates() { const states = client.getAllLoadStates(); const loadIds = Object.keys(states).sort((a, b) => parseInt(a) - parseInt(b)); if (loadIds.length === 0) { console.log('πŸ“­ No load states available yet...'); return; } console.log('πŸ“‹ Current Load States:'); console.log('β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”'); console.log('β”‚ Load ID β”‚ Name β”‚ Status β”‚ Last Updated β”‚'); console.log('β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€'); loadIds.forEach(loadId => { const load = states[loadId]; const status = load.state === 'LOAD_STATE_ON' ? '🟒 ON ' : 'πŸ”΄ OFF '; const name = load.name.padEnd(23); const lastUpdated = new Date(load.lastUpdated).toLocaleTimeString(); console.log(`β”‚ ${loadId} β”‚ ${name} β”‚ ${status} β”‚ ${lastUpdated.padEnd(19)} β”‚`); }); console.log('β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜'); } function startInteractiveControl(client) { const readline = require('readline'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, prompt: '> ' }); rl.prompt(); rl.on('line', (line) => { const [command, ...args] = line.trim().toLowerCase().split(' '); switch (command) { case 'on': case 'off': case 'cycle': if (args.length === 0) { console.log('❌ Please specify a load ID (e.g., "on 1")'); } else { const loadId = args[0]; console.log(`⚑ Sending ${command.toUpperCase()} command to Load ${loadId}...`); client.sendAction(loadId, command); } break; case 'status': displayLoadStates(); break; case 'stats': console.log('πŸ“Š Requesting server statistics...'); client.getStats(); break; case 'ping': console.log('πŸ“ Pinging server...'); client.ping(); break; case 'clear': displayDashboard(); break; case 'quit': case 'exit': console.log('πŸ‘‹ Disconnecting from server...'); client.disconnect(); rl.close(); process.exit(0); break; case 'help': displayDashboard(); break; default: if (command) { console.log(`❓ Unknown command: ${command}. Type 'help' for available commands.`); } } rl.prompt(); }); rl.on('close', () => { console.log('\nπŸ‘‹ Goodbye!'); client.disconnect(); process.exit(0); }); } // Graceful shutdown process.on('SIGINT', () => { console.log('\nπŸ›‘ Shutting down dashboard...'); client.disconnect(); process.exit(0); }); } // Handle unhandled errors process.on('unhandledRejection', (error) => { console.error('❌ Unhandled error:', error.message); process.exit(1); }); // Start the dashboard createDashboard();