@crowsgear/escl-protocol-scanner 1.0.6 → 1.0.8
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.
- package/README.md +232 -230
- package/dist/discovery.d.ts +2 -1
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +3 -2
- package/dist/discovery.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,31 +4,33 @@ A comprehensive TypeScript/Node.js library for discovering and communicating wit
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
7
|
+
- 🔍 **Automatic Scanner Discovery**: Uses mDNS/Bonjour to discover eSCL-compatible scanners on the local network
|
|
8
|
+
- 📡 **HTTP-based Communication**: eSCL protocol built on HTTP for reliable device communication
|
|
9
|
+
- 🎨 **Multiple Color Modes**: Support for Black & White, Grayscale, and Full Color scanning
|
|
10
|
+
- 📊 **Flexible Resolution**: Supports various DPI settings (150, 200, 300, 600 DPI, etc.)
|
|
11
|
+
- 📄 **Multi-source Scanning**: Platen (flatbed) and ADF (Automatic Document Feeder) support
|
|
12
|
+
- 📸 **Image Processing**: Automatic rotation correction and PNG encoding
|
|
13
|
+
- 🔧 **Python Backend**: Uses Python subprocess for reliable mDNS discovery via zeroconf
|
|
14
|
+
- ✨ **Production Ready**: Mature implementation from scanner-net project
|
|
15
15
|
|
|
16
16
|
## Supported Devices
|
|
17
17
|
|
|
18
18
|
Compatible with network scanners from major manufacturers:
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
19
|
+
|
|
20
|
+
- **Canon**: iR-series MFP devices
|
|
21
|
+
- **HP**: LaserJet MFP devices
|
|
22
|
+
- **Xerox**: WorkCentre series
|
|
23
|
+
- **Ricoh**: MP series
|
|
24
|
+
- **Epson**: WorkForce Pro series
|
|
25
|
+
- **And other AirPrint-compatible MFP devices**
|
|
25
26
|
|
|
26
27
|
## Installation
|
|
27
28
|
|
|
28
29
|
### Prerequisites
|
|
29
|
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
30
|
+
|
|
31
|
+
- Node.js ≥ 14.0.0
|
|
32
|
+
- Python 3.6+
|
|
33
|
+
- Python packages: `zeroconf`, `pillow`
|
|
32
34
|
|
|
33
35
|
### Step 1: Install Package
|
|
34
36
|
|
|
@@ -39,6 +41,7 @@ yarn add @escl-protocol/scanner
|
|
|
39
41
|
```
|
|
40
42
|
|
|
41
43
|
The postinstall script will:
|
|
44
|
+
|
|
42
45
|
1. Check for required Python packages (`zeroconf`, `pillow`)
|
|
43
46
|
2. **Interactively ask** if you want to install missing packages
|
|
44
47
|
3. Install to the Python environment specified by `PYTHON_PATH` (or system python3)
|
|
@@ -125,19 +128,19 @@ npm start
|
|
|
125
128
|
import { discoverScanners, ESCLClient } from '@escl-protocol/scanner';
|
|
126
129
|
|
|
127
130
|
async function example() {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
+
// 1. Discover available scanners (5 second discovery window)
|
|
132
|
+
const scanners = await discoverScanners(5000);
|
|
133
|
+
console.log(`Found ${scanners.length} scanners`);
|
|
131
134
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
135
|
+
if (scanners.length === 0) {
|
|
136
|
+
console.log('No scanners found on network');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
136
139
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
140
|
+
// 2. Get scanner info
|
|
141
|
+
const scanner = scanners[0];
|
|
142
|
+
console.log(`Scanner: ${scanner.name}`);
|
|
143
|
+
console.log(`Host: ${scanner.host}:${scanner.port}`);
|
|
141
144
|
}
|
|
142
145
|
|
|
143
146
|
example();
|
|
@@ -151,14 +154,14 @@ import { discoverScanners, ESCLScanner } from '@escl-protocol/scanner';
|
|
|
151
154
|
// Quick discovery
|
|
152
155
|
const scanners = await discoverScanners(5000);
|
|
153
156
|
|
|
154
|
-
scanners.forEach(scanner => {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
157
|
+
scanners.forEach((scanner) => {
|
|
158
|
+
console.log(`${scanner.name} at ${scanner.host}:${scanner.port}`);
|
|
159
|
+
if (scanner.manufacturer) {
|
|
160
|
+
console.log(` Manufacturer: ${scanner.manufacturer}`);
|
|
161
|
+
}
|
|
162
|
+
if (scanner.model) {
|
|
163
|
+
console.log(` Model: ${scanner.model}`);
|
|
164
|
+
}
|
|
162
165
|
});
|
|
163
166
|
```
|
|
164
167
|
|
|
@@ -172,9 +175,9 @@ const client = new ESCLClient();
|
|
|
172
175
|
|
|
173
176
|
const capabilities = await client.getCapabilities(scanners[0]);
|
|
174
177
|
if (capabilities) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
+
console.log('Supported Resolutions:', capabilities.resolutions);
|
|
179
|
+
console.log('Color Modes:', capabilities.colorModes);
|
|
180
|
+
console.log('Scan Sources:', capabilities.sources);
|
|
178
181
|
}
|
|
179
182
|
```
|
|
180
183
|
|
|
@@ -188,15 +191,15 @@ const client = new ESCLClient();
|
|
|
188
191
|
|
|
189
192
|
// Create scan job
|
|
190
193
|
const jobId = await client.createScanJob(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
194
|
+
scanners[0],
|
|
195
|
+
300, // DPI (300 DPI)
|
|
196
|
+
'RGB24', // Color mode (Full Color)
|
|
197
|
+
'Platen' // Source (Flatbed)
|
|
195
198
|
);
|
|
196
199
|
|
|
197
200
|
if (!jobId) {
|
|
198
|
-
|
|
199
|
-
|
|
201
|
+
console.error('Failed to create scan job');
|
|
202
|
+
process.exit(1);
|
|
200
203
|
}
|
|
201
204
|
|
|
202
205
|
// Poll for completion
|
|
@@ -204,31 +207,31 @@ let completed = false;
|
|
|
204
207
|
let attempts = 0;
|
|
205
208
|
|
|
206
209
|
while (!completed && attempts < 30) {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
210
|
+
const status = await client.getScanJobStatus(scanners[0], jobId);
|
|
211
|
+
|
|
212
|
+
if (status.status === 'Completed') {
|
|
213
|
+
// Download images
|
|
214
|
+
for (const imageUrl of status.images) {
|
|
215
|
+
const imageBuffer = await client.downloadImage(scanners[0], imageUrl);
|
|
216
|
+
if (imageBuffer) {
|
|
217
|
+
console.log('Downloaded image:', imageBuffer.length, 'bytes');
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
completed = true;
|
|
221
|
+
} else if (status.status === 'Aborted') {
|
|
222
|
+
console.error('Scan was aborted');
|
|
223
|
+
process.exit(1);
|
|
224
|
+
} else {
|
|
225
|
+
console.log(`Scan progress: ${status.status}`);
|
|
226
|
+
// Wait before next poll
|
|
227
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
228
|
+
attempts++;
|
|
216
229
|
}
|
|
217
|
-
completed = true;
|
|
218
|
-
} else if (status.status === 'Aborted') {
|
|
219
|
-
console.error('Scan was aborted');
|
|
220
|
-
process.exit(1);
|
|
221
|
-
} else {
|
|
222
|
-
console.log(`Scan progress: ${status.status}`);
|
|
223
|
-
// Wait before next poll
|
|
224
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
225
|
-
attempts++;
|
|
226
|
-
}
|
|
227
230
|
}
|
|
228
231
|
|
|
229
232
|
if (!completed) {
|
|
230
|
-
|
|
231
|
-
|
|
233
|
+
console.error('Scan job timeout');
|
|
234
|
+
process.exit(1);
|
|
232
235
|
}
|
|
233
236
|
```
|
|
234
237
|
|
|
@@ -242,16 +245,16 @@ import { discoverScanners, quickScan } from '@escl-protocol/scanner';
|
|
|
242
245
|
const scanners = await discoverScanners(5000);
|
|
243
246
|
|
|
244
247
|
const images = await quickScan({
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
248
|
+
scanner: scanners[0],
|
|
249
|
+
dpi: 300,
|
|
250
|
+
mode: 'color', // 'bw' | 'gray' | 'color'
|
|
251
|
+
source: 'Platen', // 'Platen' | 'Feeder'
|
|
252
|
+
timeout: 30000,
|
|
250
253
|
});
|
|
251
254
|
|
|
252
255
|
if (images) {
|
|
253
|
-
|
|
254
|
-
|
|
256
|
+
console.log(`Scanned ${images.length} images`);
|
|
257
|
+
// images are base64-encoded PNG data
|
|
255
258
|
}
|
|
256
259
|
```
|
|
257
260
|
|
|
@@ -262,59 +265,66 @@ The library provides two different ways to perform scans, each with different us
|
|
|
262
265
|
### Low-Level API: `client.createScanJob()`
|
|
263
266
|
|
|
264
267
|
**Use this when you need:**
|
|
265
|
-
|
|
266
|
-
-
|
|
267
|
-
-
|
|
268
|
-
-
|
|
268
|
+
|
|
269
|
+
- Fine-grained control over the scanning process
|
|
270
|
+
- Custom polling intervals or timeout logic
|
|
271
|
+
- To handle batch scanning with specific error recovery
|
|
272
|
+
- Advanced features like job cancellation
|
|
269
273
|
|
|
270
274
|
**How it works:**
|
|
275
|
+
|
|
271
276
|
1. Create scan job with parameters → returns Job ID
|
|
272
277
|
2. Poll `getScanJobStatus()` to check completion
|
|
273
278
|
3. Download each image with `downloadImage()`
|
|
274
279
|
4. Manually manage job lifecycle
|
|
275
280
|
|
|
276
281
|
**Example:**
|
|
282
|
+
|
|
277
283
|
```typescript
|
|
278
284
|
// Step 1: Create job
|
|
279
285
|
const jobId = await client.createScanJob(scanner, 300, 'RGB24', 'Platen');
|
|
280
286
|
|
|
281
287
|
// Step 2: Poll for completion with custom logic
|
|
282
288
|
while (!completed) {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
289
|
+
const status = await client.getScanJobStatus(scanner, jobId);
|
|
290
|
+
|
|
291
|
+
if (status.status === 'Completed') {
|
|
292
|
+
// Step 3: Download images
|
|
293
|
+
for (const imageUrl of status.images) {
|
|
294
|
+
const buffer = await client.downloadImage(scanner, imageUrl);
|
|
295
|
+
// Custom processing...
|
|
296
|
+
}
|
|
297
|
+
completed = true;
|
|
290
298
|
}
|
|
291
|
-
completed = true;
|
|
292
|
-
}
|
|
293
299
|
|
|
294
|
-
|
|
300
|
+
await new Promise((r) => setTimeout(r, 1000)); // Custom delay
|
|
295
301
|
}
|
|
296
302
|
```
|
|
297
303
|
|
|
298
304
|
**Pros:**
|
|
299
|
-
|
|
300
|
-
-
|
|
301
|
-
-
|
|
302
|
-
-
|
|
305
|
+
|
|
306
|
+
- Maximum flexibility and control
|
|
307
|
+
- Custom error handling strategies
|
|
308
|
+
- Can implement custom polling logic
|
|
309
|
+
- Direct access to job status
|
|
303
310
|
|
|
304
311
|
**Cons:**
|
|
305
|
-
|
|
306
|
-
-
|
|
307
|
-
-
|
|
312
|
+
|
|
313
|
+
- More code to write and maintain
|
|
314
|
+
- More opportunities for bugs
|
|
315
|
+
- Requires manual resource cleanup
|
|
308
316
|
|
|
309
317
|
### High-Level API: `quickScan()`
|
|
310
318
|
|
|
311
319
|
**Use this when you need:**
|
|
312
|
-
|
|
313
|
-
-
|
|
314
|
-
-
|
|
315
|
-
-
|
|
320
|
+
|
|
321
|
+
- Simple one-shot scanning (most common case)
|
|
322
|
+
- Fast implementation without boilerplate
|
|
323
|
+
- Automatic error handling and cleanup
|
|
324
|
+
- Sensible defaults for typical scanning scenarios
|
|
316
325
|
|
|
317
326
|
**How it works:**
|
|
327
|
+
|
|
318
328
|
1. Creates scan job automatically
|
|
319
329
|
2. Waits and polls for completion (~5 second intervals)
|
|
320
330
|
3. Downloads all images
|
|
@@ -322,83 +332,90 @@ while (!completed) {
|
|
|
322
332
|
5. Cleans up job automatically
|
|
323
333
|
|
|
324
334
|
**Example:**
|
|
335
|
+
|
|
325
336
|
```typescript
|
|
326
337
|
const filePaths = await quickScan({
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
338
|
+
scanner: scanners[0],
|
|
339
|
+
dpi: 300,
|
|
340
|
+
mode: 'color', // 'bw' | 'gray' | 'color'
|
|
341
|
+
source: 'Platen', // 'Platen' | 'Feeder'
|
|
342
|
+
savePath: './scans', // optional, defaults to cwd()
|
|
332
343
|
});
|
|
333
344
|
|
|
334
345
|
if (filePaths) {
|
|
335
|
-
|
|
336
|
-
|
|
346
|
+
console.log(`Scanned ${filePaths.length} images`);
|
|
347
|
+
filePaths.forEach((path) => console.log(` - ${path}`));
|
|
337
348
|
}
|
|
338
349
|
```
|
|
339
350
|
|
|
340
351
|
**Pros:**
|
|
341
|
-
|
|
342
|
-
-
|
|
343
|
-
-
|
|
344
|
-
-
|
|
345
|
-
-
|
|
352
|
+
|
|
353
|
+
- Minimal code required
|
|
354
|
+
- Automatic cleanup on success/failure
|
|
355
|
+
- Returns file paths ready for use
|
|
356
|
+
- Built-in error handling
|
|
357
|
+
- Best for simple scanning tasks
|
|
346
358
|
|
|
347
359
|
**Cons:**
|
|
348
|
-
|
|
349
|
-
-
|
|
350
|
-
-
|
|
360
|
+
|
|
361
|
+
- Less control over polling
|
|
362
|
+
- Fixed timeout/retry logic
|
|
363
|
+
- Cannot implement custom scanning workflows
|
|
351
364
|
|
|
352
365
|
### Comparison Table
|
|
353
366
|
|
|
354
|
-
| Feature
|
|
355
|
-
|
|
356
|
-
| **Typical Use**
|
|
357
|
-
| **Code Required**
|
|
358
|
-
| **Control Level**
|
|
359
|
-
| **Error Handling** | Manual
|
|
360
|
-
| **Cleanup**
|
|
361
|
-
| **Polling Logic**
|
|
362
|
-
| **Return Type**
|
|
363
|
-
| **Learning Curve** | Moderate
|
|
364
|
-
| **Best For**
|
|
367
|
+
| Feature | `createScanJob()` | `quickScan()` |
|
|
368
|
+
| ------------------ | -------------------------- | ------------------------ |
|
|
369
|
+
| **Typical Use** | Advanced, custom workflows | Simple one-shot scans |
|
|
370
|
+
| **Code Required** | ~30+ lines | ~10 lines |
|
|
371
|
+
| **Control Level** | Full | Limited |
|
|
372
|
+
| **Error Handling** | Manual | Automatic |
|
|
373
|
+
| **Cleanup** | Manual | Automatic |
|
|
374
|
+
| **Polling Logic** | Custom | Built-in (~5s intervals) |
|
|
375
|
+
| **Return Type** | Job ID (string) | File paths (string[]) |
|
|
376
|
+
| **Learning Curve** | Moderate | Easy |
|
|
377
|
+
| **Best For** | Integrations, batch jobs | Desktop apps, CLI tools |
|
|
365
378
|
|
|
366
379
|
### Recommendation
|
|
367
380
|
|
|
368
381
|
**Choose `quickScan()` unless you have specific reasons not to:**
|
|
369
|
-
|
|
370
|
-
-
|
|
371
|
-
-
|
|
372
|
-
-
|
|
382
|
+
|
|
383
|
+
- It's the recommended approach for most use cases
|
|
384
|
+
- Handles all the complexity automatically
|
|
385
|
+
- Reduces bugs and improves maintainability
|
|
386
|
+
- Perfect for Electron, CLI, and batch applications
|
|
373
387
|
|
|
374
388
|
**Choose `createScanJob()` only if:**
|
|
375
|
-
|
|
376
|
-
-
|
|
377
|
-
-
|
|
378
|
-
-
|
|
389
|
+
|
|
390
|
+
- You need custom polling behavior
|
|
391
|
+
- Implementing a queue system
|
|
392
|
+
- Building advanced scanning workflows
|
|
393
|
+
- Integrating with custom error handling
|
|
379
394
|
|
|
380
395
|
## API Reference
|
|
381
396
|
|
|
382
397
|
### Types
|
|
383
398
|
|
|
384
399
|
#### `ESCLScanner`
|
|
400
|
+
|
|
385
401
|
```typescript
|
|
386
402
|
interface ESCLScanner {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
403
|
+
name: string; // Scanner display name
|
|
404
|
+
host: string; // IP address
|
|
405
|
+
port: number; // HTTP port (usually 80)
|
|
406
|
+
serviceName?: string; // Full mDNS service name
|
|
407
|
+
model?: string; // Device model (if available)
|
|
408
|
+
manufacturer?: string; // Device manufacturer (if available)
|
|
393
409
|
}
|
|
394
410
|
```
|
|
395
411
|
|
|
396
412
|
#### `ESCLCapabilities`
|
|
413
|
+
|
|
397
414
|
```typescript
|
|
398
415
|
interface ESCLCapabilities {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
416
|
+
resolutions: number[]; // Available DPI values
|
|
417
|
+
colorModes: ('BlackAndWhite1' | 'Grayscale8' | 'RGB24')[]; // Available color modes
|
|
418
|
+
sources: ('Platen' | 'Adf' | 'Feeder')[]; // Available scan sources
|
|
402
419
|
}
|
|
403
420
|
```
|
|
404
421
|
|
|
@@ -410,12 +427,12 @@ Main client for communicating with eSCL scanners.
|
|
|
410
427
|
|
|
411
428
|
```typescript
|
|
412
429
|
class ESCLClient {
|
|
413
|
-
|
|
430
|
+
constructor(timeout?: number);
|
|
414
431
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
432
|
+
async getCapabilities(scanner: ESCLScanner): Promise<ESCLCapabilities | null>;
|
|
433
|
+
async createScanJob(scanner: ESCLScanner, dpi: number, colorMode: string, source: string): Promise<string | null>;
|
|
434
|
+
async getScanJobStatus(scanner: ESCLScanner, jobId: string): Promise<{ status: string; images: string[] }>;
|
|
435
|
+
async downloadImage(scanner: ESCLScanner, imageUrl: string): Promise<Buffer | null>;
|
|
419
436
|
}
|
|
420
437
|
```
|
|
421
438
|
|
|
@@ -425,13 +442,13 @@ Scanner discovery service using Python subprocess with zeroconf.
|
|
|
425
442
|
|
|
426
443
|
```typescript
|
|
427
444
|
class ESCLDiscovery {
|
|
428
|
-
|
|
445
|
+
constructor(timeout?: number);
|
|
429
446
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
447
|
+
async startDiscovery(): Promise<ESCLScanner[]>;
|
|
448
|
+
stopDiscovery(): void;
|
|
449
|
+
getScanners(): ESCLScanner[];
|
|
450
|
+
onScannerDiscovered(callback: (scanners: ESCLScanner[]) => void): void;
|
|
451
|
+
offScannerDiscovered(callback: (scanners: ESCLScanner[]) => void): void;
|
|
435
452
|
}
|
|
436
453
|
```
|
|
437
454
|
|
|
@@ -451,11 +468,11 @@ Convenience function for simple scan workflow.
|
|
|
451
468
|
|
|
452
469
|
```typescript
|
|
453
470
|
const images = await quickScan({
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
471
|
+
scanner: device,
|
|
472
|
+
dpi: 300,
|
|
473
|
+
mode: 'color',
|
|
474
|
+
source: 'Platen',
|
|
475
|
+
timeout: 30000,
|
|
459
476
|
});
|
|
460
477
|
```
|
|
461
478
|
|
|
@@ -470,10 +487,10 @@ const images = await quickScan({
|
|
|
470
487
|
|
|
471
488
|
### Design Rationale
|
|
472
489
|
|
|
473
|
-
-
|
|
474
|
-
-
|
|
475
|
-
-
|
|
476
|
-
-
|
|
490
|
+
- **Python for Discovery**: `zeroconf` library is more mature and stable than Node.js alternatives
|
|
491
|
+
- **Subprocess Architecture**: Isolates network scanning from main application
|
|
492
|
+
- **JSON-RPC Protocol**: Simple, reliable IPC between Node.js and Python processes
|
|
493
|
+
- **Image Encoding**: Base64 PNG encoding for safe cross-process transmission
|
|
477
494
|
|
|
478
495
|
## Configuration
|
|
479
496
|
|
|
@@ -490,8 +507,8 @@ export ESCL_DEBUG=1
|
|
|
490
507
|
### Timeouts
|
|
491
508
|
|
|
492
509
|
```typescript
|
|
493
|
-
const client = new ESCLClient(10000);
|
|
494
|
-
const scanners = await discoverScanners(5000);
|
|
510
|
+
const client = new ESCLClient(10000); // 10 second HTTP timeout
|
|
511
|
+
const scanners = await discoverScanners(5000); // 5 second discovery window
|
|
495
512
|
```
|
|
496
513
|
|
|
497
514
|
## Troubleshooting
|
|
@@ -499,21 +516,23 @@ const scanners = await discoverScanners(5000); // 5 second discovery window
|
|
|
499
516
|
### Scanners Not Found
|
|
500
517
|
|
|
501
518
|
1. **Check Python Dependencies**:
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
519
|
+
|
|
520
|
+
```bash
|
|
521
|
+
pip install zeroconf pillow
|
|
522
|
+
```
|
|
505
523
|
|
|
506
524
|
2. **Verify Network**:
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
525
|
+
|
|
526
|
+
- Ensure scanner is on same network as computer
|
|
527
|
+
- Check scanner is powered on and connected
|
|
528
|
+
- Verify network is mDNS-enabled (not blocked by firewall)
|
|
510
529
|
|
|
511
530
|
3. **Enable Debug Output**:
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
531
|
+
```typescript
|
|
532
|
+
import { ESCLDiscovery } from '@escl-protocol/scanner';
|
|
533
|
+
const discovery = new ESCLDiscovery();
|
|
534
|
+
// Check stderr output for Python errors
|
|
535
|
+
```
|
|
517
536
|
|
|
518
537
|
### Connection Refused
|
|
519
538
|
|
|
@@ -524,9 +543,10 @@ const scanners = await discoverScanners(5000); // 5 second discovery window
|
|
|
524
543
|
### Scan Timeouts
|
|
525
544
|
|
|
526
545
|
1. Increase timeout value:
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
546
|
+
|
|
547
|
+
```typescript
|
|
548
|
+
const client = new ESCLClient(30000); // 30 seconds
|
|
549
|
+
```
|
|
530
550
|
|
|
531
551
|
2. Check scanner network latency
|
|
532
552
|
3. Reduce scan resolution for slower networks
|
|
@@ -534,9 +554,10 @@ const scanners = await discoverScanners(5000); // 5 second discovery window
|
|
|
534
554
|
### Image Processing Issues
|
|
535
555
|
|
|
536
556
|
1. Verify `pillow` library is installed:
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
557
|
+
|
|
558
|
+
```bash
|
|
559
|
+
pip install --upgrade pillow
|
|
560
|
+
```
|
|
540
561
|
|
|
541
562
|
2. Check disk space for image temporary files
|
|
542
563
|
3. Verify scanner outputs valid PNG/JPEG images
|
|
@@ -545,56 +566,35 @@ const scanners = await discoverScanners(5000); // 5 second discovery window
|
|
|
545
566
|
|
|
546
567
|
```typescript
|
|
547
568
|
try {
|
|
548
|
-
|
|
569
|
+
const scanners = await discoverScanners(5000);
|
|
549
570
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
571
|
+
if (scanners.length === 0) {
|
|
572
|
+
throw new Error('No scanners found');
|
|
573
|
+
}
|
|
553
574
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
575
|
+
const capabilities = await client.getCapabilities(scanners[0]);
|
|
576
|
+
if (!capabilities) {
|
|
577
|
+
throw new Error('Failed to get capabilities');
|
|
578
|
+
}
|
|
558
579
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
580
|
+
const jobId = await client.createScanJob(scanners[0], 300, 'RGB24', 'Platen');
|
|
581
|
+
if (!jobId) {
|
|
582
|
+
throw new Error('Failed to create scan job');
|
|
583
|
+
}
|
|
563
584
|
} catch (error) {
|
|
564
|
-
|
|
565
|
-
|
|
585
|
+
console.error('eSCL operation failed:', error.message);
|
|
586
|
+
// Handle error appropriately
|
|
566
587
|
}
|
|
567
588
|
```
|
|
568
589
|
|
|
569
590
|
## Performance Considerations
|
|
570
591
|
|
|
571
|
-
-
|
|
572
|
-
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
-
|
|
576
|
-
-
|
|
577
|
-
|
|
578
|
-
## Compatibility
|
|
579
|
-
|
|
580
|
-
### Operating Systems
|
|
581
|
-
- ✅ macOS 10.14+
|
|
582
|
-
- ✅ Linux (Ubuntu 18.04+, CentOS 7+, etc.)
|
|
583
|
-
- ✅ Windows 10+ (with Python 3.6+)
|
|
584
|
-
|
|
585
|
-
### Node.js Versions
|
|
586
|
-
- ✅ Node.js 14.x
|
|
587
|
-
- ✅ Node.js 16.x
|
|
588
|
-
- ✅ Node.js 18.x
|
|
589
|
-
- ✅ Node.js 20.x
|
|
590
|
-
|
|
591
|
-
### Scanner Models
|
|
592
|
-
- ✅ Canon: iR-ADV C series, iR 2500/3000 series
|
|
593
|
-
- ✅ HP: LaserJet Pro M series, MFP devices
|
|
594
|
-
- ✅ Xerox: WorkCentre 5000+ series
|
|
595
|
-
- ✅ Ricoh: MP C series
|
|
596
|
-
- ✅ Epson: WorkForce Pro series
|
|
597
|
-
- ✅ Brother: MFC series (eSCL enabled)
|
|
592
|
+
- **Discovery Time**: ~5 seconds for local network scan
|
|
593
|
+
- **Scan Time**: Varies by document size, DPI, and network latency
|
|
594
|
+
- Single page A4 at 300 DPI: typically 5-10 seconds
|
|
595
|
+
- Large batch jobs: minutes depending on document count
|
|
596
|
+
- **Memory Usage**: Python subprocess uses ~50-100MB when idle
|
|
597
|
+
- **Network**: Requires local network access to scanners (no internet required)
|
|
598
598
|
|
|
599
599
|
## Development
|
|
600
600
|
|
|
@@ -648,16 +648,18 @@ MIT
|
|
|
648
648
|
## Support
|
|
649
649
|
|
|
650
650
|
For issues, questions, or feature requests:
|
|
651
|
-
|
|
652
|
-
-
|
|
653
|
-
-
|
|
654
|
-
-
|
|
651
|
+
|
|
652
|
+
- GitHub Repository: [escl-protocol-scanner](https://github.com/byeong1/escl-protocol-scanner)
|
|
653
|
+
- GitHub Issues: [Report Issues](https://github.com/byeong1/escl-protocol-scanner/issues)
|
|
654
|
+
- npm Package: [@escl-protocol/scanner](https://www.npmjs.com/package/@escl-protocol/scanner)
|
|
655
|
+
- Email: your-email@example.com
|
|
655
656
|
|
|
656
657
|
## Changelog
|
|
657
658
|
|
|
658
659
|
### Version 1.0.0 (Initial Release)
|
|
659
|
-
|
|
660
|
-
-
|
|
661
|
-
-
|
|
662
|
-
-
|
|
663
|
-
-
|
|
660
|
+
|
|
661
|
+
- Basic eSCL protocol support
|
|
662
|
+
- Scanner discovery via mDNS
|
|
663
|
+
- Single and batch scanning
|
|
664
|
+
- Image rotation and encoding
|
|
665
|
+
- Support for multiple manufacturers
|
package/dist/discovery.d.ts
CHANGED
|
@@ -65,7 +65,8 @@ export declare class ESCLDiscovery {
|
|
|
65
65
|
/**
|
|
66
66
|
* Convenience function for quick scanner discovery
|
|
67
67
|
* @param timeout Discovery timeout in milliseconds (default: 5000)
|
|
68
|
+
* @param options Discovery options including pythonPath
|
|
68
69
|
* @returns Discovery response with success status and scanner data
|
|
69
70
|
*/
|
|
70
|
-
export declare function discoverScanners(timeout?: number): Promise<DiscoveryResponse>;
|
|
71
|
+
export declare function discoverScanners(timeout?: number, options?: ESCLDiscoveryOptions): Promise<DiscoveryResponse>;
|
|
71
72
|
//# sourceMappingURL=discovery.d.ts.map
|
package/dist/discovery.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,WAAW,EAA6B,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEpF;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,UAAU,CAAuC;IACzD,OAAO,CAAC,SAAS,CAAqD;IACtE,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,UAAU,CAAqB;gBAE3B,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB;IAS5D;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAuB1B;;;;OAIG;IACG,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAoDlE;;OAEG;IACH,aAAa,IAAI,IAAI;IAIrB;;OAEG;IACH,WAAW,IAAI,WAAW,EAAE;IAI5B;;OAEG;IACH,mBAAmB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,IAAI,GAAG,IAAI;IAItE;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,IAAI,GAAG,IAAI;IAIvE;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA6D1B;;OAEG;IACH,OAAO,CAAC,OAAO;IA2Bf;;OAEG;IACH,OAAO,CAAC,eAAe;CAMxB;AAED
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,WAAW,EAA6B,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEpF;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,UAAU,CAAuC;IACzD,OAAO,CAAC,SAAS,CAAqD;IACtE,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,UAAU,CAAqB;gBAE3B,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB;IAS5D;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAuB1B;;;;OAIG;IACG,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAoDlE;;OAEG;IACH,aAAa,IAAI,IAAI;IAIrB;;OAEG;IACH,WAAW,IAAI,WAAW,EAAE;IAI5B;;OAEG;IACH,mBAAmB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,IAAI,GAAG,IAAI;IAItE;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,IAAI,GAAG,IAAI;IAIvE;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA6D1B;;OAEG;IACH,OAAO,CAAC,OAAO;IA2Bf;;OAEG;IACH,OAAO,CAAC,eAAe;CAMxB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,MAAa,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAGzH"}
|
package/dist/discovery.js
CHANGED
|
@@ -260,10 +260,11 @@ exports.ESCLDiscovery = ESCLDiscovery;
|
|
|
260
260
|
/**
|
|
261
261
|
* Convenience function for quick scanner discovery
|
|
262
262
|
* @param timeout Discovery timeout in milliseconds (default: 5000)
|
|
263
|
+
* @param options Discovery options including pythonPath
|
|
263
264
|
* @returns Discovery response with success status and scanner data
|
|
264
265
|
*/
|
|
265
|
-
async function discoverScanners(timeout = 5000) {
|
|
266
|
-
const discovery = new ESCLDiscovery(timeout);
|
|
266
|
+
async function discoverScanners(timeout = 5000, options) {
|
|
267
|
+
const discovery = new ESCLDiscovery(timeout, options);
|
|
267
268
|
return discovery.startDiscovery(timeout);
|
|
268
269
|
}
|
|
269
270
|
//# sourceMappingURL=discovery.js.map
|
package/dist/discovery.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED