UNPKG

epson-printer-status

Version:

EPSON打印机状态监控 - Node.js原生模块,支持实时状态回调和完整ASB状态解析

285 lines (252 loc) 10.7 kB
/** * 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 };