@xiboplayer/xmr 0.2.0 → 0.3.0

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.
Files changed (3) hide show
  1. package/README.md +25 -337
  2. package/package.json +2 -2
  3. package/src/index.js +2 -0
package/README.md CHANGED
@@ -1,20 +1,21 @@
1
- # @xiboplayer/xmr Documentation
1
+ # @xiboplayer/xmr
2
2
 
3
- **XMR (Xibo Message Relay) WebSocket client for real-time CMS commands.**
3
+ **XMR WebSocket client for real-time Xibo CMS commands.**
4
4
 
5
5
  ## Overview
6
6
 
7
- The XMR package provides WebSocket integration with Xibo CMS, enabling real-time push commands from CMS to player without polling.
7
+ Listens for push commands from the CMS over WebSocket with automatic reconnection:
8
8
 
9
- ### Key Features
10
-
11
- - **Real-time commands**: Instant content updates via WebSocket
12
- - **Automatic reconnection**: Exponential backoff with max 10 attempts
13
- - **Connection management**: Handles disconnects, errors, and network issues
14
- - **7 CMS commands**: collectNow, screenShot, changeLayout, criteriaUpdate, and more
15
- - **Event-driven**: Clean event-based API for command handling
16
- - **Memory efficient**: Proper cleanup of timers and event listeners
17
- - **Production ready**: Comprehensive test suite with 48 test cases
9
+ - **collectNow** — trigger an immediate collection cycle
10
+ - **screenshot** — request a display screenshot
11
+ - **changeLayout** switch to a specific layout
12
+ - **overlayLayout** show an overlay layout
13
+ - **revertToSchedule** return to the scheduled playlist
14
+ - **purgeAll** clear all cached content
15
+ - **dataUpdate** notify of updated widget data
16
+ - **triggerWebhook** fire a webhook action
17
+ - **commandAction** execute a shell command
18
+ - **criteriaUpdate** — update geo/criteria filters
18
19
 
19
20
  ## Installation
20
21
 
@@ -22,339 +23,26 @@ The XMR package provides WebSocket integration with Xibo CMS, enabling real-time
22
23
  npm install @xiboplayer/xmr
23
24
  ```
24
25
 
25
- ## Quick Start
26
-
27
- ```javascript
28
- import { XmrWrapper } from '@xiboplayer/xmr';
29
-
30
- // Create wrapper
31
- const config = {
32
- cmsAddress: 'https://cms.example.com',
33
- hardwareKey: 'player-hw-key-123',
34
- xmrChannel: 'player-channel' // Optional, defaults to player-{hardwareKey}
35
- };
36
-
37
- const player = {
38
- collect: async () => { /* ... */ },
39
- captureScreenshot: async () => { /* ... */ },
40
- changeLayout: async (layoutId) => { /* ... */ },
41
- reportGeoLocation: async (data) => { /* ... */ },
42
- updateStatus: (status) => { /* ... */ }
43
- };
44
-
45
- const xmr = new XmrWrapper(config, player);
46
-
47
- // Start connection
48
- const connected = await xmr.start('wss://cms.example.com:9505', 'cms-key-123');
49
-
50
- if (connected) {
51
- console.log('XMR connected');
52
- }
53
-
54
- // Check connection status
55
- if (xmr.isConnected()) {
56
- console.log('Currently connected');
57
- }
58
-
59
- // Stop connection
60
- await xmr.stop();
61
- ```
62
-
63
- ## Supported Commands
64
-
65
- ### Core Commands
66
-
67
- | Command | Description | Player Method |
68
- |---------|-------------|---------------|
69
- | `collectNow` | Force immediate XMDS sync | `player.collect()` |
70
- | `screenShot` | Capture screenshot | `player.captureScreenshot()` |
71
- | `changeLayout` | Switch to specific layout | `player.changeLayout(layoutId)` |
72
- | `licenceCheck` | Validate license (no-op for Linux) | None |
73
- | `rekey` | Rotate RSA keys | None (future) |
74
-
75
- ### New in v0.0.6
76
-
77
- | Command | Description | Player Method |
78
- |---------|-------------|---------------|
79
- | `criteriaUpdate` | Update display criteria | `player.collect()` |
80
- | `currentGeoLocation` | Report geo location | `player.reportGeoLocation(data)` |
81
-
82
- See [XMR_COMMANDS.md](./XMR_COMMANDS.md) for complete command reference.
83
-
84
- ## Connection Lifecycle
85
-
86
- ```
87
- ┌──────────┐
88
- │ start() │
89
- └─────┬────┘
90
-
91
-
92
- ┌──────────┐
93
- ┌─────│Connected │◄─────┐
94
- │ └─────┬────┘ │
95
- │ │ │
96
- Network │ │Commands │Auto
97
- Error │ │Flowing │Reconnect
98
- │ │ │
99
- ▼ ▼ │
100
- ┌──────────┐ ┌──────────┐
101
- │Disconnect│────────────│Reconnect │
102
- └─────┬────┘ Backoff └──────────┘
103
-
104
- │stop()
105
-
106
- ┌──────────┐
107
- │ Stopped │
108
- └──────────┘
109
- ```
110
-
111
- ### Reconnection Logic
112
-
113
- - **Exponential backoff**: 5s, 10s, 15s, 20s, 25s, 30s, 35s, 40s, 45s, 50s
114
- - **Max attempts**: 10 (then waits for next collection cycle)
115
- - **Intentional shutdown**: No reconnect when `stop()` is called
116
- - **Connection events**: `connected`, `disconnected`, `error`
117
-
118
- ## API Reference
119
-
120
- ### XmrWrapper
121
-
122
- #### Constructor
123
-
124
- ```javascript
125
- new XmrWrapper(config, player)
126
- ```
127
-
128
- **Parameters**:
129
- - `config` (Object): Player configuration
130
- - `hardwareKey` (string): Player hardware key
131
- - `xmrChannel` (string, optional): Custom channel ID
132
- - `player` (Object): Player instance with command handlers
133
-
134
- #### Methods
135
-
136
- ##### start(xmrUrl, cmsKey)
137
-
138
- Start XMR connection.
139
-
140
- ```javascript
141
- await xmr.start('wss://cms.example.com:9505', 'cms-key-123');
142
- ```
143
-
144
- **Returns**: `Promise<boolean>` - True if connected, false if failed
145
-
146
- ##### stop()
147
-
148
- Stop XMR connection and cancel reconnection.
149
-
150
- ```javascript
151
- await xmr.stop();
152
- ```
153
-
154
- ##### isConnected()
155
-
156
- Check connection status.
157
-
158
- ```javascript
159
- const connected = xmr.isConnected();
160
- ```
161
-
162
- **Returns**: `boolean`
163
-
164
- ##### send(action, data)
165
-
166
- Send message to CMS (for future features).
167
-
168
- ```javascript
169
- await xmr.send('customAction', { key: 'value' });
170
- ```
171
-
172
- **Returns**: `Promise<boolean>` - True if sent successfully
173
-
174
- ### Player Interface
175
-
176
- Your player object should implement these methods:
177
-
178
- ```javascript
179
- {
180
- // Required
181
- collect: async () => Promise<void>,
182
- captureScreenshot: async () => Promise<void>,
183
- changeLayout: async (layoutId) => Promise<void>,
184
-
185
- // Optional
186
- reportGeoLocation: async (data) => Promise<void>,
187
- updateStatus: (status) => void
188
- }
189
- ```
190
-
191
- ## Testing
192
-
193
- ### Run Tests
194
-
195
- ```bash
196
- # Run all tests
197
- npm test
198
-
199
- # Watch mode
200
- npm run test:watch
201
-
202
- # Coverage report
203
- npm run test:coverage
204
- ```
205
-
206
- ### Test Coverage
207
-
208
- - ✅ 48 test cases
209
- - ✅ Constructor and initialization
210
- - ✅ Connection lifecycle (start, stop, reconnect)
211
- - ✅ All 7 CMS commands
212
- - ✅ Error handling and edge cases
213
- - ✅ Memory management and cleanup
214
-
215
- See [XMR_TESTING.md](./XMR_TESTING.md) for comprehensive testing guide.
216
-
217
- ## Configuration
218
-
219
- ### From registerDisplay
220
-
221
- XMR settings are typically received from CMS `registerDisplay` response:
222
-
223
- ```json
224
- {
225
- "settings": {
226
- "xmrWebSocketAddress": "wss://cms.example.com:9505",
227
- "xmrCmsKey": "abcdef123456",
228
- "xmrChannel": "player-hw-key-123"
229
- }
230
- }
231
- ```
232
-
233
- Use these values with `start()`:
234
-
235
- ```javascript
236
- const { xmrWebSocketAddress, xmrCmsKey } = settings;
237
- await xmr.start(xmrWebSocketAddress, xmrCmsKey);
238
- ```
239
-
240
- ### Custom Channel
241
-
242
- Override default channel (player-{hardwareKey}):
26
+ ## Usage
243
27
 
244
28
  ```javascript
245
- const config = {
246
- hardwareKey: 'hw-123',
247
- xmrChannel: 'custom-channel-name' // Use this instead
248
- };
249
- ```
250
-
251
- ## Error Handling
252
-
253
- All command handlers include error handling:
29
+ import { XmrClient } from '@xiboplayer/xmr';
254
30
 
255
- ```javascript
256
- this.xmr.on('collectNow', async () => {
257
- console.log('[XMR] Received collectNow command');
258
- try {
259
- await this.player.collect();
260
- console.log('[XMR] collectNow completed successfully');
261
- } catch (error) {
262
- console.error('[XMR] collectNow failed:', error);
263
- }
31
+ const xmr = new XmrClient({
32
+ wsUrl: 'wss://your-cms.example.com/xmr',
33
+ channel: 'display-channel-key',
34
+ rsaKey: 'display-rsa-key',
264
35
  });
265
- ```
266
-
267
- Errors don't:
268
- - ❌ Crash the player
269
- - ❌ Disconnect XMR
270
- - ❌ Prevent other commands
271
-
272
- They do:
273
- - ✅ Log to console
274
- - ✅ Preserve connection state
275
- - ✅ Continue processing other commands
276
-
277
- ## Troubleshooting
278
-
279
- ### Connection Issues
280
-
281
- **Problem**: XMR won't connect
282
-
283
- **Solution**:
284
- 1. Verify XMR enabled in CMS settings
285
- 2. Check firewall allows port 9505
286
- 3. Verify `xmrWebSocketAddress` from registerDisplay
287
- 4. Check browser console for errors
288
-
289
- ### Commands Not Executing
290
-
291
- **Problem**: collectNow sent but nothing happens
292
-
293
- **Solution**:
294
- 1. Check `xmr.isConnected()` returns true
295
- 2. Verify player methods exist (`player.collect`, etc.)
296
- 3. Check console for command reception logs
297
- 4. Look for errors in command handler
298
-
299
- ### Reconnection Loops
300
-
301
- **Problem**: Keeps reconnecting forever
302
-
303
- **Solution**:
304
- 1. Verify XMR server is running
305
- 2. Check cmsKey is correct
306
- 3. Monitor `reconnectAttempts` counter
307
- 4. Manually stop: `await xmr.stop()`
308
36
 
309
- See [XMR_TESTING.md](./XMR_TESTING.md#troubleshooting) for more.
37
+ xmr.on('collectNow', () => player.collect());
38
+ xmr.on('screenshot', () => captureScreenshot());
39
+ xmr.connect();
40
+ ```
310
41
 
311
42
  ## Dependencies
312
43
 
313
- - `@xibosignage/xibo-communication-framework@^0.0.6` - Official XMR library
314
- - `@xiboplayer/utils` - Logging and utilities
315
-
316
- ## Version History
317
-
318
- ### v0.9.0 (Current)
319
- - ✅ Upgraded to @xibosignage/xibo-communication-framework@0.0.6
320
- - ✅ Added `criteriaUpdate` command
321
- - ✅ Added `currentGeoLocation` command
322
- - ✅ Intentional shutdown flag (no reconnect on stop)
323
- - ✅ Comprehensive test suite (48 tests)
324
- - ✅ Complete documentation
325
-
326
- ### Previous Versions
327
- - Basic XMR integration
328
- - Core commands (collectNow, screenShot, changeLayout)
329
- - Automatic reconnection
330
-
331
- ## Contributing
332
-
333
- When adding new XMR commands:
334
-
335
- 1. Add event handler in `setupEventHandlers()`
336
- 2. Update [XMR_COMMANDS.md](./XMR_COMMANDS.md)
337
- 3. Add tests in `xmr-wrapper.test.js`
338
- 4. Implement player method if needed
339
-
340
- See [XMR_TESTING.md](./XMR_TESTING.md#adding-new-commands) for details.
341
-
342
- ## Related Packages
343
-
344
- - [@xiboplayer/core](../../core/docs/) - Player core orchestration
345
- - [@xiboplayer/xmds](../../xmds/docs/) - XMDS SOAP client
346
- - [@xiboplayer/schedule](../../schedule/docs/) - Schedule engine
347
-
348
- ## Support
349
-
350
- - **GitHub Issues**: https://github.com/xibo/xibo-players/issues
351
- - **Documentation**: [XMR_COMMANDS.md](./XMR_COMMANDS.md), [XMR_TESTING.md](./XMR_TESTING.md)
352
- - **Xibo Community**: https://community.xibo.org.uk
44
+ - `@xiboplayer/utils` logger, events
353
45
 
354
46
  ---
355
47
 
356
- **Package Version**: 0.9.0 | **XMR Library**: 0.0.6
357
-
358
- ## License
359
-
360
- AGPL-3.0-or-later
48
+ **Part of the [XiboPlayer SDK](https://github.com/linuxnow/xiboplayer)**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiboplayer/xmr",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "XMR WebSocket client for real-time Xibo CMS commands",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "dependencies": {
11
11
  "@xibosignage/xibo-communication-framework": "^0.0.6",
12
- "@xiboplayer/utils": "0.2.0"
12
+ "@xiboplayer/utils": "0.3.0"
13
13
  },
14
14
  "devDependencies": {
15
15
  "vitest": "^2.0.0"
package/src/index.js CHANGED
@@ -1,2 +1,4 @@
1
1
  // @xiboplayer/xmr - XMR WebSocket client
2
+ import pkg from '../package.json' with { type: 'json' };
3
+ export const VERSION = pkg.version;
2
4
  export { XmrWrapper } from './xmr-wrapper.js';