node-libcec 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,422 @@
1
+ import {
2
+ CECAdapter,
3
+ LogicalAddress,
4
+ DeviceType,
5
+ PowerStatus,
6
+ UserControlCode,
7
+ DisplayControl,
8
+ Opcode,
9
+ Version
10
+ } from '../lib/index.js';
11
+ import readline from 'readline';
12
+
13
+ /**
14
+ * Advanced example demonstrating more libcec features
15
+ */
16
+
17
+ class CECController {
18
+ constructor() {
19
+ this.cec = new CECAdapter({
20
+ deviceName: 'AdvancedCEC',
21
+ deviceTypes: [DeviceType.PLAYBACK_DEVICE],
22
+ hdmiPort: 1,
23
+ activateSource: false
24
+ });
25
+
26
+ this.devices = new Map();
27
+ this.setupEventHandlers();
28
+ }
29
+
30
+ setupEventHandlers() {
31
+ // Log messages with filtering
32
+ this.cec.on('log', (msg) => {
33
+ // Only show warnings and errors
34
+ if (msg.level <= 2) {
35
+ const level = msg.level === 1 ? 'ERROR' : 'WARN';
36
+ console.log(`[${level}] ${msg.message}`);
37
+ }
38
+ });
39
+
40
+ // Handle remote control keypresses
41
+ this.cec.on('keypress', (key) => {
42
+ if (key.duration === 0) {
43
+ // Key pressed
44
+ this.handleKeyPress(key.keycode);
45
+ } else {
46
+ // Key released (duration > 0 indicates release)
47
+ this.handleKeyRelease(key.keycode, key.duration);
48
+ }
49
+ });
50
+
51
+ // Handle incoming CEC commands
52
+ this.cec.on('command', (cmd) => {
53
+ this.handleCommand(cmd);
54
+ });
55
+
56
+ // Handle source activation changes
57
+ this.cec.on('sourceActivated', (source) => {
58
+ if (source.activated) {
59
+ console.log(`Source activated: device ${source.logicalAddress}`);
60
+ } else {
61
+ console.log(`Source deactivated: device ${source.logicalAddress}`);
62
+ }
63
+ });
64
+
65
+ // Handle alerts
66
+ this.cec.on('alert', (alert) => {
67
+ console.log(`Alert received: type ${alert.type}`);
68
+ });
69
+
70
+ // Handle configuration changes
71
+ this.cec.on('configurationChanged', (config) => {
72
+ console.log('Configuration changed:', config);
73
+ });
74
+ }
75
+
76
+ handleKeyPress(keycode) {
77
+ const keyName = Object.keys(UserControlCode).find(k => UserControlCode[k] === keycode) || keycode;
78
+ console.log(`Key pressed: ${keyName}`);
79
+
80
+ // Example: Handle specific keys
81
+ switch (keycode) {
82
+ case UserControlCode.PLAY:
83
+ console.log(' -> Play action');
84
+ break;
85
+ case UserControlCode.PAUSE:
86
+ console.log(' -> Pause action');
87
+ break;
88
+ case UserControlCode.STOP:
89
+ console.log(' -> Stop action');
90
+ break;
91
+ case UserControlCode.UP:
92
+ case UserControlCode.DOWN:
93
+ case UserControlCode.LEFT:
94
+ case UserControlCode.RIGHT:
95
+ console.log(' -> Navigation');
96
+ break;
97
+ case UserControlCode.SELECT:
98
+ console.log(' -> Select/Enter');
99
+ break;
100
+ case UserControlCode.EXIT:
101
+ case UserControlCode.ROOT_MENU:
102
+ console.log(' -> Menu action');
103
+ break;
104
+ }
105
+ }
106
+
107
+ handleKeyRelease(keycode, duration) {
108
+ console.log(`Key released after ${duration}ms`);
109
+ }
110
+
111
+ handleCommand(cmd) {
112
+ const opcodeName = Object.keys(Opcode).find(k => Opcode[k] === cmd.opcode) || `0x${cmd.opcode.toString(16)}`;
113
+ console.log(`Command: ${opcodeName} from ${cmd.initiator} to ${cmd.destination}`);
114
+
115
+ // Handle specific commands
116
+ switch (cmd.opcode) {
117
+ case Opcode.STANDBY:
118
+ console.log(' -> Standby requested');
119
+ break;
120
+ case Opcode.GIVE_DEVICE_POWER_STATUS:
121
+ console.log(' -> Power status requested');
122
+ break;
123
+ case Opcode.REQUEST_ACTIVE_SOURCE:
124
+ console.log(' -> Active source requested');
125
+ break;
126
+ case Opcode.SET_STREAM_PATH:
127
+ if (cmd.parameters.length >= 2) {
128
+ const physAddr = (cmd.parameters[0] << 8) | cmd.parameters[1];
129
+ console.log(` -> Stream path set to ${formatPhysicalAddress(physAddr)}`);
130
+ }
131
+ break;
132
+ }
133
+ }
134
+
135
+ connect() {
136
+ const adapters = CECAdapter.detectAdapters();
137
+ if (adapters.length === 0) {
138
+ throw new Error('No CEC adapters found');
139
+ }
140
+
141
+ console.log('Detected adapters:');
142
+ adapters.forEach((a, i) => {
143
+ console.log(` ${i}: ${a.comName} (${a.comPath})`);
144
+ console.log(` Vendor: 0x${a.vendorId.toString(16)}, Product: 0x${a.productId.toString(16)}`);
145
+ console.log(` Firmware: v${a.firmwareVersion}`);
146
+ });
147
+
148
+ if (!this.cec.open()) {
149
+ throw new Error('Failed to open CEC adapter');
150
+ }
151
+
152
+ console.log('\nConnected to CEC adapter');
153
+ console.log('Library info:', this.cec.getLibInfo());
154
+ }
155
+
156
+ async scanDevices() {
157
+ console.log('\nScanning CEC bus...');
158
+ this.cec.rescanActiveDevices();
159
+
160
+ // Small delay to let scan complete
161
+ await sleep(1000);
162
+
163
+ const activeDevices = this.cec.getActiveDevices();
164
+ console.log(`Found ${activeDevices.length} devices\n`);
165
+
166
+ for (const addr of activeDevices) {
167
+ const device = {
168
+ address: addr,
169
+ name: this.cec.getDeviceOSDName(addr),
170
+ vendorId: this.cec.getDeviceVendorId(addr),
171
+ physicalAddress: this.cec.getDevicePhysicalAddress(addr),
172
+ cecVersion: this.cec.getDeviceCecVersion(addr),
173
+ powerStatus: this.cec.getDevicePowerStatus(addr),
174
+ language: this.cec.getDeviceMenuLanguage(addr),
175
+ isActiveSource: this.cec.isActiveSource(addr)
176
+ };
177
+
178
+ this.devices.set(addr, device);
179
+ this.printDeviceInfo(device);
180
+ }
181
+ }
182
+
183
+ printDeviceInfo(device) {
184
+ const addrName = Object.keys(LogicalAddress).find(k => LogicalAddress[k] === device.address) || device.address;
185
+ const powerName = Object.keys(PowerStatus).find(k => PowerStatus[k] === device.powerStatus) || device.powerStatus;
186
+ const versionName = Object.keys(Version).find(k => Version[k] === device.cecVersion) || device.cecVersion;
187
+
188
+ console.log(`Device: ${addrName} (${device.address})`);
189
+ console.log(` OSD Name: ${device.name || '(unknown)'}`);
190
+ console.log(` Physical Address: ${formatPhysicalAddress(device.physicalAddress)}`);
191
+ console.log(` Vendor: ${formatVendorId(device.vendorId)}`);
192
+ console.log(` CEC Version: ${versionName}`);
193
+ console.log(` Power Status: ${powerName}`);
194
+ console.log(` Menu Language: ${device.language || '(unknown)'}`);
195
+ console.log(` Active Source: ${device.isActiveSource ? 'Yes' : 'No'}`);
196
+ console.log();
197
+ }
198
+
199
+ // Power control
200
+ async powerOn(address = LogicalAddress.TV) {
201
+ console.log(`Powering on device ${address}...`);
202
+ return this.cec.powerOnDevices(address);
203
+ }
204
+
205
+ async powerOff(address = LogicalAddress.BROADCAST) {
206
+ console.log(`Putting device ${address} into standby...`);
207
+ return this.cec.standbyDevices(address);
208
+ }
209
+
210
+ // Source control
211
+ becomeActiveSource() {
212
+ console.log('Becoming active source...');
213
+ return this.cec.setActiveSource();
214
+ }
215
+
216
+ becomeInactive() {
217
+ console.log('Becoming inactive...');
218
+ return this.cec.setInactiveView();
219
+ }
220
+
221
+ // Volume control
222
+ async adjustVolume(direction, steps = 1) {
223
+ for (let i = 0; i < steps; i++) {
224
+ if (direction === 'up') {
225
+ this.cec.volumeUp();
226
+ } else {
227
+ this.cec.volumeDown();
228
+ }
229
+ await sleep(100);
230
+ }
231
+ }
232
+
233
+ toggleMute() {
234
+ return this.cec.audioToggleMute();
235
+ }
236
+
237
+ getAudioStatus() {
238
+ const status = this.cec.audioStatus();
239
+ const muted = (status & 0x80) !== 0;
240
+ const volume = status & 0x7F;
241
+ return { muted, volume };
242
+ }
243
+
244
+ // Display message on TV
245
+ showMessage(message, address = LogicalAddress.TV) {
246
+ console.log(`Showing message on device ${address}: "${message}"`);
247
+ return this.cec.setOSDString(address, DisplayControl.DISPLAY_FOR_DEFAULT_TIME, message);
248
+ }
249
+
250
+ // Send raw CEC command
251
+ sendCommand(initiator, destination, opcode, parameters = []) {
252
+ return this.cec.transmit({
253
+ initiator,
254
+ destination,
255
+ opcode,
256
+ parameters
257
+ });
258
+ }
259
+
260
+ // Simulate remote control
261
+ pressButton(address, button) {
262
+ this.cec.sendKeypress(address, button);
263
+ return sleep(100).then(() => this.cec.sendKeyRelease(address));
264
+ }
265
+
266
+ close() {
267
+ console.log('Closing CEC connection...');
268
+ this.cec.close();
269
+ }
270
+ }
271
+
272
+ // Helper functions
273
+ function formatPhysicalAddress(addr) {
274
+ return `${(addr >> 12) & 0xF}.${(addr >> 8) & 0xF}.${(addr >> 4) & 0xF}.${addr & 0xF}`;
275
+ }
276
+
277
+ function formatVendorId(id) {
278
+ const vendors = {
279
+ 0x000039: 'Toshiba',
280
+ 0x0000F0: 'Samsung',
281
+ 0x0005CD: 'Denon',
282
+ 0x000678: 'Marantz',
283
+ 0x000982: 'Loewe',
284
+ 0x0009B0: 'Onkyo',
285
+ 0x001582: 'Pulse-Eight',
286
+ 0x001950: 'Harman Kardon',
287
+ 0x001A11: 'Google',
288
+ 0x00903E: 'Philips',
289
+ 0x009053: 'Daewoo',
290
+ 0x00A0DE: 'Yamaha',
291
+ 0x00D0D5: 'Pioneer',
292
+ 0x00E036: 'Sharp',
293
+ 0x00E091: 'LG',
294
+ 0x080046: 'Sony',
295
+ 0x18C086: 'Broadcom',
296
+ 0x6B746D: 'Vizio',
297
+ 0x8065E9: 'Benq'
298
+ };
299
+ return vendors[id] || `0x${id.toString(16).padStart(6, '0')}`;
300
+ }
301
+
302
+ function sleep(ms) {
303
+ return new Promise(resolve => setTimeout(resolve, ms));
304
+ }
305
+
306
+ // Interactive CLI
307
+ async function interactiveMode(controller) {
308
+ const rl = readline.createInterface({
309
+ input: process.stdin,
310
+ output: process.stdout
311
+ });
312
+
313
+ const prompt = () => {
314
+ rl.question('\ncec> ', async (input) => {
315
+ const [cmd, ...args] = input.trim().split(' ');
316
+
317
+ try {
318
+ switch (cmd) {
319
+ case 'scan':
320
+ await controller.scanDevices();
321
+ break;
322
+ case 'on':
323
+ await controller.powerOn(parseInt(args[0]) || LogicalAddress.TV);
324
+ break;
325
+ case 'off':
326
+ case 'standby':
327
+ await controller.powerOff(parseInt(args[0]) || LogicalAddress.BROADCAST);
328
+ break;
329
+ case 'active':
330
+ controller.becomeActiveSource();
331
+ break;
332
+ case 'inactive':
333
+ controller.becomeInactive();
334
+ break;
335
+ case 'vol+':
336
+ await controller.adjustVolume('up', parseInt(args[0]) || 1);
337
+ break;
338
+ case 'vol-':
339
+ await controller.adjustVolume('down', parseInt(args[0]) || 1);
340
+ break;
341
+ case 'mute':
342
+ controller.toggleMute();
343
+ break;
344
+ case 'audio':
345
+ const audio = controller.getAudioStatus();
346
+ console.log(`Volume: ${audio.volume}%, Muted: ${audio.muted}`);
347
+ break;
348
+ case 'msg':
349
+ controller.showMessage(args.join(' ') || 'Hello from Node.js!');
350
+ break;
351
+ case 'status':
352
+ const addr = parseInt(args[0]) || LogicalAddress.TV;
353
+ const power = controller.cec.getDevicePowerStatus(addr);
354
+ const powerName = Object.keys(PowerStatus).find(k => PowerStatus[k] === power);
355
+ console.log(`Device ${addr} power status: ${powerName}`);
356
+ break;
357
+ case 'config':
358
+ console.log(controller.cec.getCurrentConfiguration());
359
+ break;
360
+ case 'help':
361
+ console.log(`
362
+ Commands:
363
+ scan - Scan for CEC devices
364
+ on [addr] - Power on device (default: TV)
365
+ off [addr] - Standby device (default: all)
366
+ active - Become active source
367
+ inactive - Become inactive
368
+ vol+ [steps] - Volume up
369
+ vol- [steps] - Volume down
370
+ mute - Toggle mute
371
+ audio - Show audio status
372
+ msg <text> - Display message on TV
373
+ status [addr] - Get device power status
374
+ config - Show current configuration
375
+ quit - Exit
376
+ `);
377
+ break;
378
+ case 'quit':
379
+ case 'exit':
380
+ controller.close();
381
+ rl.close();
382
+ process.exit(0);
383
+ break;
384
+ case '':
385
+ break;
386
+ default:
387
+ console.log(`Unknown command: ${cmd}. Type 'help' for commands.`);
388
+ }
389
+ } catch (err) {
390
+ console.error('Error:', err.message);
391
+ }
392
+
393
+ prompt();
394
+ });
395
+ };
396
+
397
+ prompt();
398
+ }
399
+
400
+ // Main
401
+ async function main() {
402
+ const controller = new CECController();
403
+
404
+ process.on('SIGINT', () => {
405
+ console.log('\nInterrupted');
406
+ controller.close();
407
+ process.exit(0);
408
+ });
409
+
410
+ try {
411
+ controller.connect();
412
+ await controller.scanDevices();
413
+
414
+ console.log("Type 'help' for available commands\n");
415
+ await interactiveMode(controller);
416
+ } catch (err) {
417
+ console.error('Error:', err.message);
418
+ process.exit(1);
419
+ }
420
+ }
421
+
422
+ main();
@@ -0,0 +1,98 @@
1
+ import {
2
+ CECAdapter,
3
+ LogicalAddress,
4
+ DeviceType,
5
+ PowerStatus,
6
+ UserControlCode,
7
+ DisplayControl
8
+ } from '../lib/index.js';
9
+
10
+ async function main() {
11
+ // Detect available adapters
12
+ const adapters = CECAdapter.detectAdapters();
13
+ console.log('Found adapters:', adapters);
14
+
15
+ if (adapters.length === 0) {
16
+ console.log('No CEC adapters found');
17
+ return;
18
+ }
19
+
20
+ // Create adapter instance
21
+ const cec = new CECAdapter({
22
+ deviceName: 'NodeCEC',
23
+ deviceTypes: [DeviceType.RECORDING_DEVICE],
24
+ activateSource: false
25
+ });
26
+
27
+ // Set up event listeners
28
+ cec.on('log', (msg) => {
29
+ console.log(`[LOG ${msg.level}] ${msg.message}`);
30
+ });
31
+
32
+ cec.on('keypress', (key) => {
33
+ console.log(`Key pressed: ${key.keycode} (duration: ${key.duration}ms)`);
34
+ });
35
+
36
+ cec.on('command', (cmd) => {
37
+ console.log(`Command received:`, cmd);
38
+ });
39
+
40
+ cec.on('sourceActivated', (source) => {
41
+ console.log(`Source ${source.logicalAddress} activated: ${source.activated}`);
42
+ });
43
+
44
+ // Open connection (auto-detect port)
45
+ console.log('Opening connection...');
46
+ if (!cec.open()) {
47
+ console.error('Failed to open CEC adapter');
48
+ return;
49
+ }
50
+ console.log('Connected!');
51
+
52
+ // Get library info
53
+ console.log('Library:', cec.getLibInfo());
54
+
55
+ // Scan for active devices
56
+ console.log('\nScanning for devices...');
57
+ const devices = cec.getActiveDevices();
58
+ console.log('Active devices:', devices);
59
+
60
+ // Get info about each device
61
+ for (const addr of devices) {
62
+ const name = cec.getDeviceOSDName(addr);
63
+ const vendor = cec.getDeviceVendorId(addr);
64
+ const power = cec.getDevicePowerStatus(addr);
65
+ const physical = cec.getDevicePhysicalAddress(addr);
66
+
67
+ console.log(`\nDevice ${addr}:`);
68
+ console.log(` Name: ${name}`);
69
+ console.log(` Vendor ID: 0x${vendor.toString(16)}`);
70
+ console.log(` Power: ${PowerStatus[Object.keys(PowerStatus).find(k => PowerStatus[k] === power)] || power}`);
71
+ console.log(` Physical Address: ${(physical >> 12) & 0xF}.${(physical >> 8) & 0xF}.${(physical >> 4) & 0xF}.${physical & 0xF}`);
72
+ }
73
+
74
+ // Example: Power on the TV
75
+ // console.log('\nPowering on TV...');
76
+ // cec.powerOnDevices(LogicalAddress.TV);
77
+
78
+ // Example: Set as active source
79
+ // console.log('Setting as active source...');
80
+ // cec.setActiveSource();
81
+
82
+ // Example: Display message on TV
83
+ // cec.setOSDString(LogicalAddress.TV, DisplayControl.DISPLAY_FOR_DEFAULT_TIME, 'Hello from Node!');
84
+
85
+ // Example: Send remote button press
86
+ // cec.sendKeypress(LogicalAddress.TV, UserControlCode.VOLUME_UP);
87
+
88
+ // Keep running to receive events
89
+ console.log('\nListening for CEC events (Ctrl+C to exit)...');
90
+
91
+ process.on('SIGINT', () => {
92
+ console.log('\nClosing...');
93
+ cec.close();
94
+ process.exit(0);
95
+ });
96
+ }
97
+
98
+ main().catch(console.error);
@@ -0,0 +1,148 @@
1
+ import { createRequire } from 'module';
2
+ import { fileURLToPath } from 'url';
3
+ import { dirname, join } from 'path';
4
+
5
+ const require = createRequire(import.meta.url);
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+
8
+ console.log('=== node-libcec Diagnostic Script ===\n');
9
+ console.log('Step 1: Loading native module...');
10
+
11
+ let native;
12
+ try {
13
+ native = require(join(__dirname, '../build/Release/cec.node'));
14
+ console.log(' OK: Loaded Release build');
15
+ } catch (e) {
16
+ try {
17
+ native = require(join(__dirname, '../build/Debug/cec.node'));
18
+ console.log(' OK: Loaded Debug build');
19
+ } catch (e2) {
20
+ console.error(' FAILED: Could not load native module');
21
+ console.error(' Error:', e2.message);
22
+ process.exit(1);
23
+ }
24
+ }
25
+
26
+ console.log(' Native module exports:', Object.keys(native));
27
+
28
+ console.log('\nStep 2: Detecting adapters (static method, no instance)...');
29
+ const detectStart = Date.now();
30
+ try {
31
+ const adapters = native.CECAdapter.detectAdapters();
32
+ console.log(` OK: Found ${adapters.length} adapter(s) in ${Date.now() - detectStart}ms`);
33
+ adapters.forEach((a, i) => {
34
+ console.log(` Adapter ${i}: ${a.comName} @ ${a.comPath}`);
35
+ });
36
+
37
+ if (adapters.length === 0) {
38
+ console.log('\n No adapters found. Make sure your CEC adapter is connected.');
39
+ console.log(' Try: ls -la /dev/ttyACM* /dev/ttyUSB*');
40
+ process.exit(0);
41
+ }
42
+ } catch (e) {
43
+ console.error(' FAILED:', e.message);
44
+ process.exit(1);
45
+ }
46
+
47
+ console.log('\nStep 3: Creating CECAdapter instance (no callbacks)...');
48
+ const createStart = Date.now();
49
+ let adapter;
50
+ try {
51
+ adapter = new native.CECAdapter({
52
+ deviceName: 'Diagnose',
53
+ deviceTypes: [1], // RECORDING_DEVICE
54
+ activateSource: false
55
+ });
56
+ console.log(` OK: Instance created in ${Date.now() - createStart}ms`);
57
+ } catch (e) {
58
+ console.error(' FAILED:', e.message);
59
+ process.exit(1);
60
+ }
61
+
62
+ console.log('\nStep 4: Setting up callbacks...');
63
+ const cbStart = Date.now();
64
+ try {
65
+ adapter.setCallbacks({
66
+ onLogMessage: (msg) => {
67
+ console.log(` [LOG] level=${msg.level}: ${msg.message}`);
68
+ },
69
+ onKeyPress: (key) => {
70
+ console.log(` [KEY] keycode=${key.keycode} duration=${key.duration}`);
71
+ },
72
+ onCommand: (cmd) => {
73
+ console.log(` [CMD] opcode=${cmd.opcode} from=${cmd.initiator} to=${cmd.destination}`);
74
+ },
75
+ onAlert: (alert) => {
76
+ console.log(` [ALERT] type=${alert.type}`);
77
+ },
78
+ onSourceActivated: (src) => {
79
+ console.log(` [SRC] address=${src.logicalAddress} activated=${src.activated}`);
80
+ },
81
+ onConfigurationChanged: (cfg) => {
82
+ console.log(` [CFG] changed`);
83
+ }
84
+ });
85
+ console.log(` OK: Callbacks set in ${Date.now() - cbStart}ms`);
86
+ } catch (e) {
87
+ console.error(' FAILED:', e.message);
88
+ process.exit(1);
89
+ }
90
+
91
+ console.log('\nStep 5: Opening connection (this is where it might hang)...');
92
+ console.log(' Starting open() - will timeout after 30 seconds...');
93
+ const openStart = Date.now();
94
+
95
+ // Set a timeout to detect hang
96
+ const timeout = setTimeout(() => {
97
+ console.error(`\n TIMEOUT: open() has been running for 30 seconds`);
98
+ console.error(' This indicates a deadlock in the native code.');
99
+ console.error(' The callbacks are likely using BlockingCall instead of NonBlockingCall.');
100
+ process.exit(1);
101
+ }, 30000);
102
+
103
+ let opened = false;
104
+ try {
105
+ opened = adapter.open();
106
+ clearTimeout(timeout);
107
+ console.log(` OK: open() returned ${opened} in ${Date.now() - openStart}ms`);
108
+ } catch (e) {
109
+ clearTimeout(timeout);
110
+ console.error(` FAILED: open() threw after ${Date.now() - openStart}ms`);
111
+ console.error(' Error:', e.message);
112
+ process.exit(1);
113
+ }
114
+
115
+ if (!opened) {
116
+ console.log('\n open() returned false - adapter could not be opened');
117
+ console.log(' Check permissions: ls -la /dev/ttyACM*');
118
+ console.log(' You may need: sudo usermod -a -G dialout $USER');
119
+ process.exit(1);
120
+ }
121
+
122
+ console.log('\nStep 6: Getting library info...');
123
+ try {
124
+ const info = adapter.getLibInfo();
125
+ console.log(' OK:', info);
126
+ } catch (e) {
127
+ console.error(' FAILED:', e.message);
128
+ }
129
+
130
+ console.log('\nStep 7: Getting active devices...');
131
+ try {
132
+ const devices = adapter.getActiveDevices();
133
+ console.log(` OK: Found ${devices.length} active device(s):`, devices);
134
+ } catch (e) {
135
+ console.error(' FAILED:', e.message);
136
+ }
137
+
138
+ console.log('\nStep 8: Closing connection...');
139
+ try {
140
+ adapter.close();
141
+ console.log(' OK: Closed');
142
+ } catch (e) {
143
+ console.error(' FAILED:', e.message);
144
+ }
145
+
146
+ console.log('\n=== Diagnostic Complete ===');
147
+ console.log('If you see this message, the basic operations are working.');
148
+ process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-libcec",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Node.js bindings for libcec - control CEC devices over HDMI",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -41,6 +41,7 @@
41
41
  "files": [
42
42
  "lib/",
43
43
  "src/",
44
+ "examples/",
44
45
  "binding.gyp"
45
46
  ],
46
47
  "dependencies": {