UNPKG

energy-manager-iot

Version:

Library for energy management in IoT devices via MQTT protocol. Documentation: https://jonhvmp.github.io/energy-manager-iot-docs/

208 lines (207 loc) 7.77 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); const index_1 = require("../../index"); const mqtt = __importStar(require("mqtt")); /** * Integration tests for MQTT communication * * These tests require a local MQTT broker running on port 1883. * Tests will be skipped if the broker is not available. * * @group integration */ // This test requires a local MQTT broker running on port 1883 // Skip if not available const localBrokerAvailable = async () => { let client = undefined; let timeoutHandle = null; try { return new Promise((resolve) => { // Create timeout to avoid test hanging waiting for connection timeoutHandle = setTimeout(() => { if (client) { client.removeAllListeners(); client.end(true, {}, () => resolve(false)); } else { resolve(false); } }, 1000); // Try to connect client = mqtt.connect('mqtt://localhost:1883', { connectTimeout: 1000, reconnectPeriod: 0 }); client.on('connect', () => { if (timeoutHandle) clearTimeout(timeoutHandle); client?.end(true, {}, () => resolve(true)); }); client.on('error', () => { if (timeoutHandle) clearTimeout(timeoutHandle); client?.removeAllListeners(); client?.end(true, {}, () => resolve(false)); }); }); } catch (e) { if (timeoutHandle) clearTimeout(timeoutHandle); // Fix type error using explicit type check // and a non-null assertion to ensure TypeScript recognizes client if (client) { const mqttClient = client; mqttClient.removeAllListeners(); mqttClient.end(true, {}); } return false; } }; describe('MQTT Integration', () => { let energyManager; let testClient; let brokerAvailable = false; // Check if broker is available before tests beforeAll(async () => { try { brokerAvailable = await localBrokerAvailable(); if (!brokerAvailable) { console.warn('Local MQTT broker not available. Integration tests will be skipped.'); } } catch (error) { console.error('Error checking broker availability:', error); brokerAvailable = false; } }); beforeEach(async () => { if (!brokerAvailable) { return; } // Create manager instance energyManager = new index_1.EnergyManager({ topicPrefix: 'test/devices/' }); // Connect to broker await energyManager.connect('mqtt://localhost:1883'); // Test client to simulate devices testClient = mqtt.connect('mqtt://localhost:1883', { clientId: `test-client-${Date.now()}` }); // Wait for test client to connect await new Promise((resolve) => { testClient.on('connect', () => resolve()); }); }); afterEach(async () => { if (!brokerAvailable) { return; } // Clean up resources if (energyManager) { await energyManager.disconnect(); } if (testClient) { await new Promise((resolve) => { testClient.end(false, {}, () => resolve()); }); } }); test('should update status when receiving message from device', async () => { if (!brokerAvailable) { return; } // Register device energyManager.registerDevice('sensor1', 'Test Sensor', index_1.DeviceType.SENSOR); // Set up status listener const statusUpdatePromise = new Promise((resolve) => { energyManager.on('statusUpdate', (deviceId, status) => { if (deviceId === 'sensor1' && status.batteryLevel === 85) { resolve(); } }); }); // Publish status message simulating the device testClient.publish('test/devices/sensor1/status', JSON.stringify({ batteryLevel: 85, powerMode: index_1.PowerMode.NORMAL, connectionStatus: index_1.ConnectionStatus.ONLINE })); // Wait for status update await statusUpdatePromise; // Verify status was updated const device = energyManager.getDevice('sensor1'); expect(device.status).toBeDefined(); expect(device.status?.batteryLevel).toBe(85); expect(device.status?.powerMode).toBe(index_1.PowerMode.NORMAL); }, 5000); // 5 second timeout test('should send command to device', async () => { if (!brokerAvailable) { return; } // Register device energyManager.registerDevice('sensor1', 'Test Sensor', index_1.DeviceType.SENSOR); // Promise to verify command reception const commandReceivedPromise = new Promise((resolve) => { testClient.subscribe('test/devices/sensor1/command', (err) => { if (err) { console.error('Error subscribing to command topic:', err); } }); testClient.on('message', (topic, message) => { if (topic === 'test/devices/sensor1/command') { try { const command = JSON.parse(message.toString()); resolve(command); } catch (e) { console.error('Error parsing command:', e); } } }); }); // Fixed: Using CommandType enum instead of string literal await energyManager.sendCommand('sensor1', index_1.CommandType.SLEEP, { duration: 300 }); // Wait for command reception const command = await commandReceivedPromise; // Verify command expect(command).toBeDefined(); expect(command.type).toBe(index_1.CommandType.SLEEP); expect(command.payload).toEqual({ duration: 300 }); expect(command.requestId).toBeDefined(); }, 5000); // 5 second timeout });