epson-printer-status
Version:
EPSON打印机状态监控 - Node.js原生模块,支持实时状态回调和完整ASB状态解析
285 lines (252 loc) • 10.7 kB
JavaScript
/**
* EPSON打印机状态监控 Node.js原生模块
*
* 提供实时打印机状态监控、ASB状态解析和事件回调功能
*
* @author EDY
* @version 1.0.0
*/
const path = require('path');
const epsonAddon = require(path.join(__dirname, 'build/Release/epson_addon.node'));
/**
* ASB状态位定义
*/
const ASB_STATUS_BITS = {
ASB_NO_RESPONSE: 0x00000001,
ASB_PRINT_SUCCESS: 0x00000002,
ASB_DRAWER_KICK: 0x00000004,
ASB_OFF_LINE: 0x00000008,
ASB_COVER_OPEN: 0x00000020,
ASB_PAPER_FEED: 0x00000040,
ASB_AUTOCUTTER_ERR: 0x00000800,
ASB_UNRECOVER_ERR: 0x00002000,
ASB_AUTORECOVER_ERR: 0x00004000,
ASB_RECEIPT_NEAR_END: 0x00020000,
ASB_RECEIPT_END: 0x00080000,
ASB_SPOOLER_IS_STOPPED: 0x80000000
};
/**
* 错误码定义
*/
const ERROR_CODES = {
SUCCESS: 0,
ERR_TYPE: -10,
ERR_OPENED: -20,
ERR_NO_PRINTER: -30,
ERR_NO_TARGET: -40,
ERR_NO_MEMORY: -50,
ERR_HANDLE: -60,
ERR_TIMEOUT: -70,
ERR_ACCESS: -80,
ERR_PARAM: -90,
ERR_NOT_SUPPORT: -100,
ERR_OFFLINE: -110,
ERR_NOT_EPSON: -120,
ERR_WITHOUT_CB: -130,
ERR_LOCKED: -1000
};
/**
* EPSON打印机状态监控器类
*/
class EpsonPrinterMonitor {
constructor() {
this.isConnected = false;
this.printerHandle = null;
this.statusCallback = null;
this.printerName = null;
}
/**
* 连接到打印机
* @param {string} printerName 打印机名称
* @returns {Promise<number>} 返回打印机句柄,失败时返回错误码
*/
async connect(printerName) {
if (this.isConnected) {
throw new Error('已连接到打印机,请先断开连接');
}
try {
const result = epsonAddon.connect(printerName);
if (result > 0) {
this.isConnected = true;
this.printerHandle = result;
this.printerName = printerName;
return result;
} else {
throw new Error(`连接打印机失败,错误码: ${result} (${this.getErrorMessage(result)})`);
}
} catch (error) {
throw new Error(`连接打印机时发生错误: ${error.message}`);
}
}
/**
* 断开打印机连接
* @returns {Promise<number>} 返回操作结果
*/
async disconnect() {
if (!this.isConnected) {
return ERROR_CODES.SUCCESS;
}
try {
const result = epsonAddon.disconnect();
this.isConnected = false;
this.printerHandle = null;
this.printerName = null;
this.statusCallback = null;
return result;
} catch (error) {
throw new Error(`断开连接时发生错误: ${error.message}`);
}
}
/**
* 设置状态变化回调函数
* @param {Function} callback 回调函数,接收状态对象参数
* @returns {Promise<number>} 返回设置结果
*/
async setStatusCallback(callback) {
if (!this.isConnected) {
throw new Error('未连接到打印机');
}
if (typeof callback !== 'function') {
throw new Error('回调函数参数无效');
}
try {
this.statusCallback = callback;
const result = epsonAddon.setStatusCallback((status) => {
// 添加状态描述
const statusWithDescription = {
...status,
description: this.getStatusDescription(status),
timestamp: new Date().toISOString(),
printer: this.printerName
};
callback(statusWithDescription);
});
if (result !== ERROR_CODES.SUCCESS) {
throw new Error(`设置状态回调失败,错误码: ${result} (${this.getErrorMessage(result)})`);
}
return result;
} catch (error) {
throw new Error(`设置状态回调时发生错误: ${error.message}`);
}
}
/**
* 获取当前打印机状态
* @returns {Promise<object>} 返回状态对象
*/
async getStatus() {
if (!this.isConnected) {
throw new Error('未连接到打印机');
}
try {
const status = epsonAddon.getStatus();
if (status.result !== ERROR_CODES.SUCCESS) {
throw new Error(`获取状态失败,错误码: ${status.result} (${this.getErrorMessage(status.result)})`);
}
return {
...status,
description: this.getStatusDescription(status),
timestamp: new Date().toISOString(),
printer: this.printerName
};
} catch (error) {
throw new Error(`获取状态时发生错误: ${error.message}`);
}
}
/**
* 获取状态描述信息
* @param {object} status 状态对象
* @returns {object} 状态描述
*/
getStatusDescription(status) {
const descriptions = {
chinese: {},
english: {}
};
const bits = status.bits;
// 中文描述
descriptions.chinese.ASB_NO_RESPONSE = bits.ASB_NO_RESPONSE ? '无打印机回应' : '打印机回应';
descriptions.chinese.ASB_PRINT_SUCCESS = bits.ASB_PRINT_SUCCESS ? '打印完成' : '-';
descriptions.chinese.ASB_DRAWER_KICK = bits.ASB_DRAWER_KICK ?
'3号货币纸盒开启连接器插针的状态 = "H"' : '3号货币纸盒开启连接器插针的状态 = "L"';
descriptions.chinese.ASB_OFF_LINE = bits.ASB_OFF_LINE ? '脱机状态' : '联机状态';
descriptions.chinese.ASB_COVER_OPEN = bits.ASB_COVER_OPEN ? '盖板打开' : '盖板关闭';
descriptions.chinese.ASB_PAPER_FEED = bits.ASB_PAPER_FEED ? '进纸器开关正在进纸' : '进纸器开关停止进纸';
descriptions.chinese.ASB_AUTOCUTTER_ERR = bits.ASB_AUTOCUTTER_ERR ? '发生自动裁纸器错误' : '未发生自动裁纸器错误';
descriptions.chinese.ASB_UNRECOVER_ERR = bits.ASB_UNRECOVER_ERR ? '发生不可恢复的错误' : '未发生不可恢复的错误';
descriptions.chinese.ASB_AUTORECOVER_ERR = bits.ASB_AUTORECOVER_ERR ? '发生自动恢复的错误' : '未发生自动恢复的错误';
descriptions.chinese.ASB_RECEIPT_NEAR_END = bits.ASB_RECEIPT_NEAR_END ? '接近卷纸末端传感器监测到无纸' : '接近卷纸末端传感器监测到仍有纸';
descriptions.chinese.ASB_RECEIPT_END = bits.ASB_RECEIPT_END ? '卷纸末端传感器监测到无纸' : '卷纸末端传感器监测到仍有纸';
descriptions.chinese.ASB_SPOOLER_IS_STOPPED = bits.ASB_SPOOLER_IS_STOPPED ? '停止卷轴' : '操作卷轴';
// 英文描述
descriptions.english.ASB_NO_RESPONSE = bits.ASB_NO_RESPONSE ? 'No printer response' : 'Printer response normal';
descriptions.english.ASB_PRINT_SUCCESS = bits.ASB_PRINT_SUCCESS ? 'Print completed' : '-';
descriptions.english.ASB_DRAWER_KICK = bits.ASB_DRAWER_KICK ?
'Cash drawer #3 connector pin status = H' : 'Cash drawer #3 connector pin status = L';
descriptions.english.ASB_OFF_LINE = bits.ASB_OFF_LINE ? 'Offline status' : 'Online status';
descriptions.english.ASB_COVER_OPEN = bits.ASB_COVER_OPEN ? 'Cover open' : 'Cover closed';
descriptions.english.ASB_PAPER_FEED = bits.ASB_PAPER_FEED ? 'Paper feeder switch is feeding paper' : 'Paper feeder switch stopped feeding';
descriptions.english.ASB_AUTOCUTTER_ERR = bits.ASB_AUTOCUTTER_ERR ? 'Auto-cutter error occurred' : 'No auto-cutter error';
descriptions.english.ASB_UNRECOVER_ERR = bits.ASB_UNRECOVER_ERR ? 'Unrecoverable error occurred' : 'No unrecoverable error';
descriptions.english.ASB_AUTORECOVER_ERR = bits.ASB_AUTORECOVER_ERR ? 'Auto-recoverable error occurred' : 'No auto-recoverable error';
descriptions.english.ASB_RECEIPT_NEAR_END = bits.ASB_RECEIPT_NEAR_END ? 'Paper near-end sensor detects no paper' : 'Paper near-end sensor detects paper';
descriptions.english.ASB_RECEIPT_END = bits.ASB_RECEIPT_END ? 'Paper end sensor detects no paper' : 'Paper end sensor detects paper';
descriptions.english.ASB_SPOOLER_IS_STOPPED = bits.ASB_SPOOLER_IS_STOPPED ? 'Spooler stopped' : 'Spooler operating';
return descriptions;
}
/**
* 获取错误消息
* @param {number} errorCode 错误码
* @returns {string} 错误消息
*/
getErrorMessage(errorCode) {
const errorMessages = {
[ERROR_CODES.SUCCESS]: '成功',
[ERROR_CODES.ERR_TYPE]: '类型错误',
[ERROR_CODES.ERR_OPENED]: '已经打开',
[ERROR_CODES.ERR_NO_PRINTER]: '无打印机驱动',
[ERROR_CODES.ERR_NO_TARGET]: '打印机不在范围内',
[ERROR_CODES.ERR_NO_MEMORY]: '内存不足',
[ERROR_CODES.ERR_HANDLE]: '无效句柄',
[ERROR_CODES.ERR_TIMEOUT]: '超时',
[ERROR_CODES.ERR_ACCESS]: '无法读写',
[ERROR_CODES.ERR_PARAM]: '参数错误',
[ERROR_CODES.ERR_NOT_SUPPORT]: '不支持',
[ERROR_CODES.ERR_OFFLINE]: '脱机状态',
[ERROR_CODES.ERR_NOT_EPSON]: '不是EPSON打印机',
[ERROR_CODES.ERR_WITHOUT_CB]: '没有回调函数',
[ERROR_CODES.ERR_LOCKED]: '打印机被锁定'
};
return errorMessages[errorCode] || `未知错误码: ${errorCode}`;
}
/**
* 检查是否已连接
* @returns {boolean} 连接状态
*/
isConnectedToPrinter() {
return this.isConnected;
}
/**
* 获取打印机名称
* @returns {string|null} 打印机名称
*/
getPrinterName() {
return this.printerName;
}
/**
* 获取打印机句柄
* @returns {number|null} 打印机句柄
*/
getPrinterHandle() {
return this.printerHandle;
}
}
// 导出模块
module.exports = {
EpsonPrinterMonitor,
ASB_STATUS_BITS,
ERROR_CODES,
// 便捷方法 - 创建新的监控实例
createMonitor: () => new EpsonPrinterMonitor(),
// 直接访问原生模块(高级用法)
native: epsonAddon
};