UNPKG

react-native-epson-escposprinter

Version:
1,402 lines (1,338 loc) 52.7 kB
"use strict"; import EventEmitter from "eventemitter3"; import { ErrorCode, getEpsonError, PrinterIllegalError } from "./errors/index.js"; import { events, NativeInterface } from "./NativeInterface.js"; const printers = new Map(); events.addListener("statusChange", ({ printerId, status } = {}) => printers.get(printerId)?.emit("statusChange", status)); events.addListener("printStatusChange", ({ printerId, code, status, printJobId } = {}) => printers.get(printerId)?.emit("printStatusChange", code, status, printJobId)); events.addListener("updateProgress", ({ printerId, task, progress } = {}) => printers.get(printerId)?.emit("updateProgress", task, progress)); /** * Starts communication with the printer. * * @returns A printer instance. */ export async function connect(series, lang, target, timeout) { try { const printerId = await NativeInterface.connect(series, lang, target, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT); const printer = new Printer(printerId); printers.set(printerId, printer); return printer; } catch (error) { throw getEpsonError(error, { [ErrorCode.ERR_ILLEGAL]: "Tried to start communication with a printer with which communication had been already established." }) || error; } } class CommonPrinter extends EventEmitter { static TRUE = 1; static FALSE = 0; static PARAM_UNSPECIFIED = -1; static PARAM_DEFAULT = -2; static UNKNOWN = -3; // public static SWITCH_OFF = 0; // public static SWITCH_ON = 1; static REMOVAL_WAIT_PAPER = 0; static REMOVAL_WAIT_NONE = 1; static EVENT_RECONNECTING = 0; static EVENT_RECONNECT = 1; static EVENT_DISCONNECT = 2; } export class Printer extends CommonPrinter { static WIFI_SIGNAL_NO = 0; static WIFI_SIGNAL_FAIL = 1; static WIFI_SIGNAL_GOOD = 2; static WIFI_SIGNAL_EXCELLENT = 3; static JSON_KEY_PRINTERSPEC_NAME = "PrinterSpec"; static JSON_KEY_PRODUCT_NAME = "Product"; static JSON_KEY_SERIALNO_NAME = "SerialNo"; static JSON_KEY_MAINTENANCE_NAME = "Maintenance"; static JSON_KEY_THERMALHEAD_NAME = "ThermalHead"; static JSON_KEY_N_WARNINGDOT_NAME = "NumberOfWarningDot"; static JSON_KEY_P_WARNINGDOT_NAME = "PositionOfWarningDot"; static JSON_KEY_N_BROKENDOT_NAME = "NumberOfBrokenDot"; static JSON_KEY_P_BROKENDOT_NAME = "PositionOfBrokenDot"; static JSON_KEY_SETTING_NWDEVINFO_PASSWORDAUTH_KEY = "Setting/NwDevInfo/PasswordAuth"; static JSON_KEY_SETTING_NWDEVINFO_ADMINID_KEY = "Setting/NwDevInfo/AdminId"; static JSON_KEY_SETTING_NWCSAUTH_PASSWORD_KEY = "Setting/NwCSAuth/Password"; static JSON_KEY_SETTING_WIFICFG_WPAPSK_KEY = "Setting/WifiCfg/WpaPsk/Key"; static PREFIX_ENCRYPT = "U2FsdGVkX1"; static FIRMWARE_MODE_NORMAL = 1; static FIRMWARE_MODE_MEMORY_REWRITE = 2; static HTTPS_TIMEOUT = 30000; #id; constructor(id) { super(); this.#id = id; } /** * Supports `using` keyword via the Explicit Resource Management proposal. * * The draft needs to reach stage 4 and in turn implemented by Hermes to work, * let's sit back and wait. * * @example * ```ts * await using printer = await connect(ESCPOSConst.CMP_PORT_USB); * ``` * * @see https://github.com/tc39/proposal-explicit-resource-management */ async [Symbol.asyncDispose]() { return this.disconnect(); } #ensureConnected() { if (!printers.has(this.#id)) { throw new PrinterIllegalError(); } } /** * Ends communication with the printer. */ async disconnect() { this.#ensureConnected(); try { await NativeInterface.disconnect(this.#id); printers.delete(this.#id); this.emit("disconnect"); } catch (error) { const printerError = getEpsonError(error, { [ErrorCode.ERR_ILLEGAL]: "Tried to end communication where it had not been established." }) || error; if (printerError instanceof PrinterIllegalError) { printers.delete(this.#id); } throw printerError; } } /** Acquires the current status information. */ async getStatus() { this.#ensureConnected(); try { const info = await NativeInterface.getStatus(this.#id); return info; } catch (error) { throw getEpsonError(error) || error; } } /** * Sends the print command. * * Make sure not to use this API repeatedly without getting the result in the * callback. * * This API sends data buffered by an add-type API (e.g., `addText`). */ async sendData(timeout) { this.#ensureConnected(); try { return await NativeInterface.sendData(this.#id, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error, { [ErrorCode.ERR_ILLEGAL]: "The control commands have not been buffered." }) || error; } } /** * Starts a transaction. * * A transaction represents a single printing task such as printing a single * sheet of receipt or coupon. * * After this API is called, data until the transaction is terminated by * `endTransaction` will be regarded as a single printing task. */ async beginTransaction() { this.#ensureConnected(); try { return await NativeInterface.beginTransaction(this.#id); } catch (error) { throw getEpsonError(error, { [ErrorCode.ERR_ILLEGAL]: "Another transaction had been already started by this function." }) || error; } } /** * Ends a transaction. * * A transaction represents a single printing task such as printing a single * sheet of receipt or coupon. * * After `beginTransaction` is called, data until the transaction is * terminated by this API will be regarded as a single printing task. */ async endTransaction() { this.#ensureConnected(); try { return await NativeInterface.endTransaction(this.#id); } catch (error) { throw getEpsonError(error, { [ErrorCode.ERR_ILLEGAL]: "This API was called while no transaction had been started." }) || error; } } /** * Acquires the print result for the specified print job ID. * * - The result of this API is notified to the listener method set by the * `setReceiveEventListener` API of the `Printer` class. * - When multiple print processes were performed with the same print job ID, * the status of the latest print job is acquired. */ async requestPrintJobStatus( /** * Specifies the print job ID. * * Alphanumeric characters, underscore, hyphen, and period in 1 to 30 digits * can be used. */ printJobId) { this.#ensureConnected(); try { return await NativeInterface.requestPrintJobStatus(this.#id, printJobId); } catch (error) { throw getEpsonError(error, { [ErrorCode.ERR_CONNECT]: "Communication error" }) || error; } } /** * Clears the command buffer. * * The contents buffered in the command buffer are retained until this API is * called. */ async clearCommandBuffer() { this.#ensureConnected(); try { return await NativeInterface.clearCommandBuffer(this.#id); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds text alignment setting to the command buffer. * * - Use this API at the "beginning of a line." If this API is used elsewhere, * it will be ignored. * - Setting of this API is also applied to the barcode/2D symbol/raster * image/NV logo. * - When specifying alignment in the page mode, use `addPagePosition` instead * of this API. */ async addTextAlign(align) { this.#ensureConnected(); try { return await NativeInterface.addTextAlign(this.#id, align !== undefined ? align : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds line spacing setting to the command buffer. * * - If the line spacing for a single line is set smaller than the print * character size, paper may be fed for a larger quantity than the set amount * to ensure proper printing. */ async addLineSpace(/** Specifies the line spacing (in dots). */ lineSpace) { this.#ensureConnected(); try { return await NativeInterface.addLineSpace(this.#id, Math.max(0, Math.min(255, lineSpace))); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds text rotation setting to the command buffer. * * - Use this API at the "beginning of a line." If this API is used elsewhere, * it will be ignored. * - Setting of this API is also applied to the barcode/2D symbol. * - When specifying text rotation in the page mode, use addPageDirection * instead of this API. */ async addTextRotate(/** Specifies the text rotation. */ rotate) { this.#ensureConnected(); try { return await NativeInterface.addTextRotate(this.#id, rotate ? Printer.TRUE : Printer.FALSE); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a character print command to the command buffer. * * - To print data other than text after printing text, feed a line or page. * A line which does not end with a line feed will be discarded as unfixed * data by the next `sendData`. * - In the page mode, text is printed from the current print position with * the base line dot of the characters as the standard. */ async addText( /** * Specifies the string to print. * * Use the following escape sequences for a horizontal tab and line feed. * * | String | Description | * | ------ | :------------------ | * | \t | Horizontal tab (HT) | * | \h | Line feed (LF) | * | \\ | Backslash | */ text) { this.#ensureConnected(); try { return await NativeInterface.addText(this.#id, text); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds language setting to the command buffer. * * A text string specified by the addText API is encoded according to the * language specified by this API. * * - This API is called before the `addText` API. * - Use this API at the top of each print job. * - Available languages differ depending on character specifications of the * printer. For details, see Technical Reference Guide of the printer. */ async addTextLang(/** Specifies the language. */ lang) { this.#ensureConnected(); try { return await NativeInterface.addTextLang(this.#id, lang !== undefined ? lang : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds character font setting to the command buffer. */ async addTextFont(/** Specifies the font. */ font) { this.#ensureConnected(); try { return await NativeInterface.addTextFont(this.#id, font !== undefined ? font : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds smoothing setting to the command buffer. */ async addTextSmooth(smooth) { this.#ensureConnected(); try { return await NativeInterface.addTextSmooth(this.#id, smooth ? Printer.TRUE : Printer.FALSE); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds character scaling factor setting to the command buffer. * * - If all the parameters are set to "Printer.PARAM_UNSPECIFIED," * ERR_PARAM will be returned. * - For slip, endorsement, or validation printing, an integer from 1 to 2 * can be set for the width and height. */ async addTextSize(/** Specifies the width scaling factor. */ width, /** Specifies the height scaling factor. */ height) { this.#ensureConnected(); try { return await NativeInterface.addTextSize(this.#id, Math.max(1, Math.min(8, width)), Math.max(1, Math.min(8, height))); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds character style setting to the command buffer. * * - Use this API at the "beginning of a line." If this API is used elsewhere, * it will be ignored. */ async addTextStyle(/** Specifies the reverse print. */ reverse, /** Specifies the underline. */ ul, /** Specifies the emphasized print. */ em, /** Specifies the color. */ color) { this.#ensureConnected(); try { return await NativeInterface.addTextStyle(this.#id, reverse ? Printer.TRUE : Printer.FALSE, ul ? Printer.TRUE : Printer.FALSE, em ? Printer.TRUE : Printer.FALSE, color !== undefined ? color : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds horizontal character print start position to the command buffer. * * - Calling this API causes the printer positioned at "other than the * beginning of the line." This is also true even if 0 is set to "X." * - After executing this API, addTextAlign and addTextRotate cannot be used. * - Setting of this API is also applied to the barcode/2D symbol/raster * image/NV logo. * - The setting of this API is applied to each line (Or to each barcode, * 2D symbol, raster image, or NV logo). If you want to apply the setting to * multiple lines, set this API to each of the lines. */ async addHPosition(/** Specifies the horizontal position (in dots). */ x) { this.#ensureConnected(); try { return await NativeInterface.addHPosition(this.#id, Math.max(0, Math.min(65535, x))); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a paper-feed-by-dot command to the command buffer. * * - Calling this API causes the printer positioned at "the beginning of the * line." */ async addFeedUnit(/** Specifies the feed amount (in dots). */ unit) { this.#ensureConnected(); try { return await NativeInterface.addFeedUnit(this.#id, Math.max(0, Math.min(255, unit))); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a paper-feed-by-line command to the command buffer. * * - Calling this API causes the printer positioned at "the beginning of the * line." */ async addFeedLine(/** Specifies the feed amount (in lines). */ line) { this.#ensureConnected(); try { return await NativeInterface.addFeedLine(this.#id, Math.max(0, Math.min(255, line))); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a raster image print command to the command buffer. * * Prints Android.graphics.Bitmap class graphics. * * A specified area of Android.graphics.Bitmap class graphics is binarized * according to the mode, halftone, and brightness parameters and converted * into a raster image. * * The converted image is compressed or not compressed before transmission * according to the compress parameter value. * * One pixel of an image corresponds to one dot of the printer. When a * transparent color is contained in the image, the background of the image is * assumed to be white. * * - Use this API at the "beginning of a line." If this API is used elsewhere, * it will be ignored. * - If the area specified by x/y and width/height parameters does not fit * within the image size specified by data parameter, ERR_PARAM will be * returned as an exception. * - The "compress" parameter is effective when the printer is connected via * Bluetooth. For other printers, specify Printer.COMPRESS_AUTO. * - Printing may get slower if a transparent image is printed. * - The multi-gradation and the compression of image data are not supported * in the page mode. If you set those in the page mode, nothing will be * printed. * - Set an image size appropriate for the printer. If you set to print a * large image, the API commands will be succeeded, but the printer may * print nothing. * - Even if the size of an image is printable, the ERR_MEMORY error may occur * depending on the Android device specification. In such case, reduce the * image size. * - This API consumes a lot of the buffer provided in the printer. When using * this API for LFCPrinter class, be sure to check the buffer size of the * printer. */ async addImage(/** Bitmap data in base64 format. */ image, /** Specifies the horizontal start position of the print area (in pixels). */ x, /** Specifies the vertical start position of the print area (in pixels). */ y, /** Specifies the width (in dots). */ width, /** Specifies the height (in dots). */ height, /** Specifies the color. */ color, /** Specifies the mode. */ mode, /** * Specifies the halftone. * * Effective for the monochrome (2 scales) color mode only. */ halftone, /** * Specifies the brightness. * * When a value other than 1.0 is specified for the brightness compensation * value, processing gets slower. */ brightness, /** Specifies the compress. */ compress) { this.#ensureConnected(); try { return await NativeInterface.addImage(this.#id, image, Math.max(0, Math.min(65534, x)), Math.max(0, Math.min(65534, y)), Math.max(1, Math.min(65535, width)), Math.max(1, Math.min(65535, height)), color !== undefined ? color : Printer.PARAM_DEFAULT, mode !== undefined ? mode : Printer.PARAM_DEFAULT, halftone !== undefined ? halftone : Printer.PARAM_DEFAULT, brightness ? Math.max(0, Math.min(10, brightness)) : Printer.PARAM_DEFAULT, compress !== undefined ? compress : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a NV logo print command to the command buffer. * * Prints the logo registered in the NV memory of the printer. * * - Use this API at the "beginning of a line." If this API is used elsewhere, * it will be ignored. * - For how to register the NV logo, refer to the Technical Reference Guide * of the printer. * - The page mode does not support multi-gradation printing. Multi-gradation * graphics can be printed in the standard mode only. * - The NV logo specified by this API is printed with the color setting * specified by addTextStyle buffered in advance. * - TM-U220 and TM-U220II, TM-U330 use only the key1 parameter, however, you * need to set "Printer.PARAM_DEFAULT" as the key2 parameter for those * printers since an empty key2 parameter causes an error. */ async addLogo(/** Specifies the key code 1 of the NV logo. */ key1, /** Specifies the key code 2 of the NV logo. */ key2) { this.#ensureConnected(); try { return await NativeInterface.addLogo(this.#id, key1, key2 !== undefined ? key2 : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a barcode print command to the command buffer. * * - Use this API at the "beginning of a line." * - When the barcode data specified in data does not conform to the barcode * type specified in type, an error will not be returned as an exception and * the barcode will not be printed. * - The "CODE 128 auto" type of barcode can be specified when the printer is * TM-m30II, TM-m30II-H, TM-m30II-NT, TMm30II-S, TM-m30II-SL, TM-m30III, * TM-m30III-H, TM-m50, TM-m50II, TM-m50II-H, TM-T88VII, TM-L100, TM-P20II * or TM-P80II. */ async addBarcode( /** * Specifies barcode data as a text string. * * When specifying binary data which cannot be represented as a string, use * the following escape sequences. * * | String | Description | * | ------ | :------------------------- | * | \xnn | Hexadecimal control code | * | \\ | Backslash | */ barcode, /** Specifies the barcode type. */ type, /** Specifies the HRI (Human Readable Interpretation) setting. */ hri, /** Specify the font */ font, /** Specifies the barcode width (in dots). */ width, /** Specifies the barcode height (in dots). */ height) { this.#ensureConnected(); try { return await NativeInterface.addBarcode(this.#id, barcode, type, hri, font, Math.max(2, Math.min(6, width)), Math.max(1, Math.min(255, height))); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a 2D symbol print command to the command buffer. * * - Use this API at the "beginning of a line." * - When the 2D symbol data specified in data does not conform to the 2D * symbol type specified in type, an error will not be returned as an * exception and the 2D symbol will not be printed. * - During ESC/POS control, specifying values outside the valid ranges for * the width and height parameters results in default value printing. * - During ePOS-Device XML control, specifying values outside the valid * ranges for the width and height parameters causes `sendData` to generate * an exception with ERR_FAILURE. */ async addSymbol(symbol, type, level, width, height = 0, size = 0) { this.#ensureConnected(); try { return await NativeInterface.addSymbol(this.#id, symbol, type, level, Math.max(2, Math.min(16, width)), Math.max(2, Math.min(8, height)), Math.max(0, Math.min(65535, size))); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a horizontal ruled line print command to the command buffer. * * Draws a horizontal ruled line. * * - This API cannot be used in the page mode. * - Use addPageLine to draw a horizontal ruled line in the page mode. */ async addHLine(x1, x2, lineStyle) { this.#ensureConnected(); try { return await NativeInterface.addHLine(this.#id, Math.max(0, Math.min(65535, x1)), Math.max(0, Math.min(65535, x2)), lineStyle !== undefined ? lineStyle : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a command to start drawing a vertical ruled line to the command * buffer. * * Starts drawing a vertical line. * * - This API cannot be used in the page mode. * - Use addPageLine to draw a vertical ruled line in the page mode. * - Drawing of the vertical ruled line continues until stopped by the * `addVLineEnd` API. * - Use this API with the `addVLineEnd` API. */ async addVLineBegin(/** Start position to draw a vertical ruled line (in dots) */ x, lineStyle) { this.#ensureConnected(); try { return await NativeInterface.addVLineBegin(this.#id, Math.max(0, Math.min(65535, x)), lineStyle !== undefined ? lineStyle : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a command to stop drawing a vertical ruled line to the command buffer. * * Ends drawing a vertical line. * * - This API cannot be used in the page mode. * - Use addPageLine to draw a vertical ruled line in the page mode. * - This API draws a vertical ruled line until stopped by `addVLineEnd`. * - Use this API with the `addVLineBegin` API. */ async addVLineEnd(lineId) { this.#ensureConnected(); try { return await NativeInterface.addVLineEnd(this.#id, lineId); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a page mode start command to the command buffer. * * Starts processing in the page mode. * * - The page mode does not support multi-gradation printing. * - Use this API with the `addPageEnd` API. * - Use this API at the "beginning of a line." If this API is used elsewhere, * it will be ignored. */ async addPageBegin() { this.#ensureConnected(); try { return await NativeInterface.addPageBegin(this.#id); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a page mode end command to the command buffer. * * Ends processing in the page mode. * * - The page mode does not support multi-gradation printing. * - Use this API with the `addPageBegin` API. */ async addPageEnd() { this.#ensureConnected(); try { return await NativeInterface.addPageEnd(this.#id); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds page mode print area setting to the command buffer. * * Specifies the page mode print area (coordinates). Following this API, call * an API to specify print data such as the `addText` API. * * - Define the print area in accordance with the contents to print. If the * print data does not fit within the print area, the printed contents will * be truncated. * - Use this API between the `addPageBegin` and `addPageEnd` APIs. * - Specify the width and height of the print area in accordance with the * print direction setting. Otherwise the print data may be truncated. Set * the print direction by `addPageDirection`. * - This API does not work in the standard mode. */ async addPageArea(/** Specifies the horizontal start position of the print area (in dots). */ x, /** Specifies the vertical start position of the print area (in dots). */ y, /** Specifies the width of a print area (in dots). */ width, /** Specifies the height of a print area (in dots). */ height) { this.#ensureConnected(); try { return await NativeInterface.addPageArea(this.#id, Math.max(0, Math.min(65535, x)), Math.max(0, Math.min(65535, y)), Math.max(1, Math.min(65535, width)), Math.max(1, Math.min(65535, height))); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds page mode print direction setting to the command buffer. * * Specifies the print direction in the page mode. * * - This API does not work in the standard mode. * - Use this API between the `addPageBegin` and `addPageEnd` APIs. */ async addPageDirection(/** Specifies the print direction. */ direction) { this.#ensureConnected(); try { return await NativeInterface.addPageDirection(this.#id, direction !== undefined ? direction : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds print position setting within the print area in the page mode to the * command buffer. * * Specifies the print start position (coordinates) within the area specified * by the `addPageArea` API. * * - This API does not work in the standard mode. * - Use this API between the `addPageBegin` and `addPageEnd` APIs. * - Specify the print start position (coordinates) in accordance with the * contents to print. */ async addPagePosition(/** Specifies the horizontal start position of the print area (in dots). */ x, /** Specifies the vertical start position of the print area (in dots). */ y) { this.#ensureConnected(); try { return await NativeInterface.addPagePosition(this.#id, Math.max(0, Math.min(65535, x)), Math.max(0, Math.min(65535, y))); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a page mode line draw command to the command buffer. * * Draws a line in the page mode. * * - This API does not work in the standard mode. * - A diagonal line cannot be drawn. * - Use this API between the `addPageBegin` and `addPageEnd` APIs. */ async addPageLine(x1, y1, x2, y2, style) { this.#ensureConnected(); try { return await NativeInterface.addPageLine(this.#id, Math.max(0, Math.min(65535, x1)), Math.max(0, Math.min(65535, y1)), Math.max(0, Math.min(65535, x2)), Math.max(0, Math.min(65535, y2)), style !== undefined ? style : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a page mode rectangle draw command to the command buffer. * * Draws a rectangle in the page mode. * * - This API does not work in the standard mode. * - Use this API between the `addPageBegin` and `addPageEnd` APIs. */ async addPageRectangle(x1, y1, x2, y2, style) { this.#ensureConnected(); try { return await NativeInterface.addPageRectangle(this.#id, Math.max(0, Math.min(65535, x1)), Math.max(0, Math.min(65535, y1)), Math.max(0, Math.min(65535, x2)), Math.max(0, Math.min(65535, y2)), style !== undefined ? style : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds the start batch rotate print mode to the command buffer. * * - This API does not work in the page mode. * - Use the add APIs for batch rotate printing (Example: `addText`) by * enclosing between this API and the `addRotateEnd` API. * - Do not use the following APIs between this API and the `addRotateEnd` API. * - `endTransaction` * - `addPageBegin` * - `addPageEnd` * - `addCut` * - `addPulse` * - `addSound` * - `setPrinterSetting` * - `ejectPaper` * - The data volume that the printer can process in a single batch rotate * printing is as described below. * - Strings: 80 lines * - Graphics: 2400 dots * - When you are using the add APIs (Example: `addText`) in the batch rotate * print mode, you must take care while using certain APIs. * - `addTextSize` * - If the longitudinal direction is set to triple angle or higher with * `addTextSize` before this API, then this API and the succeeding APIs * will become double-angled. * - If the longitudinal direction is set to triple angle or higher with * `addTextSize` after this API, then the specification in the * longitudinal direction will be ignored and become single-angled. * - `addFeedUnit` * - The number of paper feed lines varies depending on the line spacing * specified in `addLineSpace`. If the line spacing is specified as 30 * in `addLineSpace`, paper feeding can be performed for 8 lines with * the maximum value of `addFeedUnit` as 255. * - `addImage` * - If the total vertical size of print data exceeds 2400 dots, printing * may not be performed as intended. For example, if 500-dot data B is * sent to a location in the printer buffer where 2000-dot data A is * accumulated, then data B will be accumulated in the printer buffer * after data A has been printed. * - The multi-gradation (16 scales) maximum size is up to 600 dots * vertically. In the case of multi-gradation (16 scales), a data volume * that is four times that of monochrome (2 scales) is required. * - If the vertical size of one image element exceeds the data volume * that can be processed in one go, printing will not be performed. * - Monochrome (2 scales) maximum value: 2400 dots * - Multi-gradation (16 scales) maximum value: 600 dots */ async addRotateBegin() { this.#ensureConnected(); try { return await NativeInterface.addRotateBegin(this.#id); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds the end batch rotate print mode to the command buffer. * * - This API does not work in the page mode. * - Use the add APIs for batch rotate printing (Example: addText) by * enclosing between this API and the `addRotateBegin` API. */ async addRotateEnd() { this.#ensureConnected(); try { return await NativeInterface.addRotateEnd(this.#id); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a sheet cut command to the command buffer. * * Sets how to cut paper. * * - This API cannot be used in the page mode. * - Use this API at the "beginning of a line." If this API is used elsewhere, * it will be ignored. * - If print data is not specified after the cut reservation * (Printer.CUT_RESERVE), the printer will execute the cut after feeding * paper up to the position of the reserved cut. * - Depending on the printer, it may wait approximately 2 seconds for the * print data after the cut reservation (Printer.CUT_RESERVE) before * starting the paper feed operation. * - When using the cut reservation (Printer.CUT_RESERVE), set the length of * one receipt to at least 20 mm. */ async addCut(/** Specifies the cut type. */ type) { this.#ensureConnected(); try { return await NativeInterface.addCut(this.#id, type !== undefined ? type : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a drawer kick command to the command buffer. * * Sets the drawer kick. * * - This API cannot be used in the page mode. * - The drawer and optional external buzzer cannot be connected * simultaneously. * - Do not open the drawer repeatedly for a short time. The drawer may be * damaged due to too much load. * - For built-in buzzer equipped models of the following printers, sounding * the buzzer is possible using the pulse output commands for drawer kick * connectors. For details on controlling the built-in buzzer, refer to the * Technical Reference Guide of the printer. TM-T70 / TM-T70II / TM-T82II / * TM-T82III / TM-T83II / TM-T88IV / TM-T88V / TM-T88VI / TM-T88VII / * TM-T82II-i / TM-T83II-i / TM-T88VI-iHUB / TM-L90 / TM-L100 */ async addPulse(/** Specifies the drawer kick connector number. */ drawer, /** Specifies the on time (in milliseconds). */ time) { this.#ensureConnected(); try { return await NativeInterface.addPulse(this.#id, drawer !== undefined ? drawer : Printer.PARAM_DEFAULT, time !== undefined ? time : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds buzzer sound setting to the command buffer. * * Sets the buzzer. * * - This API cannot be used in the page mode. * - The drawer and optional external buzzer cannot be connected simultaneously. * - This API cannot be used if the printer is not equipped with a buzzer. * - The timing to receive the callback of sendData API varies by printer. * - Mobile models: after the `sendData` API is executed. * - Other than Mobile models: after the buzzer sounding is finished. * - For built-in buzzer equipped models of the following printers, sounding * the buzzer is possible using `addPulse`. * TM-T70 / TM-T70II / TM-T82II / TM-T82III / TM-T83II / TM-T88IV / TM-T88V * / TM-T88VI / TM-T88VII / TM-T82II-i / TM-T83II-i / TM-T88VI-iHUB / TM-L90 * / TM-L100 */ async addSound(/** Specifies the sound pattern. */ pattern, /** Specifies the repeat count. 0 = Unlimited */ repeat, /** Effective for Patterns 1 to 10 only. */ cycle) { this.#ensureConnected(); try { return await NativeInterface.addSound(this.#id, pattern !== undefined ? pattern : Printer.PARAM_DEFAULT, repeat ? Math.max(0, Math.min(255, repeat)) : Printer.PARAM_DEFAULT, cycle ? Math.max(1000, Math.min(25500, cycle)) : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a label sheet/black mark sheet feed command to the command buffer. * * - The label sheet/black mark sheet can be controlled in the standard mode. * - This API cannot be used in the page mode. * - Use this API at the "beginning of a line." If this API is used elsewhere, * it will be ignored. */ async addFeedPosition(position) { this.#ensureConnected(); try { return await NativeInterface.addFeedPosition(this.#id, position); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds layout setting of the label sheet/black mark sheet to the command * buffer. * * - This API does not work in the page mode. * - Use this API at the "beginning of a line." If this API is used elsewhere, * it will be ignored. * - Available setting values vary by TM printer model. For more details, see * the FS (L<Function 33> command. * https://support.epson.net/publist/reference_en/ * - The available parameter values for each type of paper are listed below. * The following table shows available values for TM printer models, and * shows those for POS terminal models in parentheses. */ async addLayout(/** Specifies the paper type. */ type, /** Specifies the paper width (in 0.1 mm units). */ width, /** * Specifies the distance from the print reference mark to the next print * reference mark (in 0.1mm units). */ height, /** * Specifies the distance from the print reference mark to the top of the * sheet (in 0.1mm units). */ marginTop, /** * Specifies the distance from the eject reference mark to the bottom edge * of the printable area (in 0.1mm units). */ marginBottom, /** * Specifies the distance from the eject reference mark to the cut position * (in 0.1mm units). */ offsetCut, /** * Specifies the distance from the eject reference mark to the bottom edge * of the label (in 0.1mm units). */ offsetLabel) { this.#ensureConnected(); try { return await NativeInterface.addLayout(this.#id, type, Math.max(1, Math.min(10000, width)), Math.max(0, Math.min(10000, height)), Math.max(-9999, Math.min(10000, marginTop)), Math.max(-9999, Math.min(10000, marginBottom)), Math.max(-9999, Math.min(10000, offsetCut)), Math.max(0, Math.min(10000, offsetLabel))); } catch (error) { throw getEpsonError(error) || error; } } /** * Adds a command to the command buffer. * * Sends the ESC/POS command. * * - Refer to the following URL for details of the ESC/POS command. * https://support.epson.net/publist/reference_en/ * * - Epson ePOS SDK does not check the commands sent using this API. * * If the commands interfere with Epson ePOS SDK operations, other APIs may * work wrongly or status values may become invalid. * * This API should be used with a full understanding of ESC/POS commands and * the receipt printer specifications. */ async addCommand(command) { this.#ensureConnected(); try { return await NativeInterface.addCommand(this.#id, command); } catch (error) { throw getEpsonError(error) || error; } } /** * Acquires the value of the printer's maintenance counter. */ async getMaintenanceCounter(type, timeout) { this.#ensureConnected(); try { return await NativeInterface.getMaintenanceCounter(this.#id, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT, type); } catch (error) { throw getEpsonError(error) || error; } } /** * Resets the value of the printer's maintenance counter. * * The value acquired by this API is notified to the listener method specified * in the listener parameter. */ async resetMaintenanceCounter(type, timeout) { this.#ensureConnected(); try { return await NativeInterface.resetMaintenanceCounter(this.#id, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT, type); } catch (error) { throw getEpsonError(error) || error; } } /** * Acquires the set value of the printer setting. * * The value acquired by this API is notified to the listener method specified * in the listener parameter. */ async getPrinterSetting(type, timeout) { this.#ensureConnected(); try { const ret = await NativeInterface.getPrinterSetting(this.#id, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT, type); return ret; } catch (error) { throw getEpsonError(error) || error; } } /** * Changes the set value of the printer setting. * * The value acquired by this API is notified to the listener method specified * in the listener parameter. */ async setPrinterSetting(settings, timeout) { this.#ensureConnected(); try { return await NativeInterface.setPrinterSetting(this.#id, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT, settings); } catch (error) { throw getEpsonError(error) || error; } } /** * Acquires the set value of the printer setting in JSON format. */ async getPrinterSettingEx(timeout) { this.#ensureConnected(); try { const ret = await NativeInterface.getPrinterSettingEx(this.#id, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT); return ret; } catch (error) { throw getEpsonError(error) || error; } } /** * Changes the set value of the printer setting in JSON format. * * For the JSON used in this API, use the printer information JSON acquired * with the getPrinterSettingEx API. * * Do not use the printer information JSON acquired from another model. * * Before executing the API, you can execute the verifyPassword API to make * sure this API uses the correct password. * * Execute the getPrinterSettingEx API after executing this API, and check * that the printer settings have been changed correctly. * * This API error status is the API processing result. * * The processing result of the devices using this API is notified to the * listener method set by the `setSetPrinterSettingExListener` API of the * Printer class. * * Do not execute this API in continuation without checking the processing * result with the callback method. */ async setPrinterSettingEx( /** * Specifies the set value of the printer setting in JSON format. * * Refer to JSON_Spec_sheet_revx.pdf included in the package for more * information. */ settings, password, timeout) { this.#ensureConnected(); try { return await NativeInterface.setPrinterSettingEx(this.#id, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT, JSON.stringify({ Setting: settings }), password); } catch (error) { throw getEpsonError(error) || error; } } /** * Compare the character string specified in this API with the administrator * password set in the printer. Check to see if the specified character string * and administrator password match. * * This API error status is the API processing result. * * The processing result of the devices using this API is notified to the * listener method set by the `setVerifyPasswordListener` API of the Printer * class. * * Do not execute this API in continuation without checking the processing * result with the callback method. */ async verifyPassword(password, timeout) { this.#ensureConnected(); try { const ret = await NativeInterface.verifyPassword(this.#id, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT, password); return ret; } catch (error) { throw getEpsonError(error, { [ErrorCode.ERR_CONNECT]: "Communication with the server failed." }) || error; } } /** * Acquires the printer serial number and the missing dot information of the * thermal head. * * The value acquired by this API is notified to the listener method specified * in the listener parameter. */ async getPrinterInformation(timeout) { this.#ensureConnected(); try { const ret = await NativeInterface.getPrinterInformation(this.#id, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT); return ret; } catch (error) { throw getEpsonError(error) || error; } } /** * Acquires the firmware information for the connected printer. */ async getPrinterFirmwareInfo(timeout) { this.#ensureConnected(); try { const ret = await NativeInterface.getPrinterFirmwareInfo(this.#id, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT); return ret; } catch (error) { throw getEpsonError(error) || error; } } /** * Compares the firmware of the connected printer with the firmware image * specified by `updateFirmware`. * * Execute this API after executing `updateFirmware`, and confirm that the * printer firmware has been overwritten by the firmware image specified in * `updateFirmware`. * * The processing result of this API is notified to the listener method * specified in the listener parameter. */ async verifyUpdate(targetFirmwareInfo) { this.#ensureConnected(); try { return await NativeInterface.verifyUpdate(this.#id, JSON.stringify(targetFirmwareInfo)); } catch (error) { throw getEpsonError(error) || error; } } async downloadFirmwareList(printerModel, option) { this.#ensureConnected(); try { const ret = await NativeInterface.downloadFirmwareList(this.#id, printerModel, option); return ret; } catch (error) { throw getEpsonError(error, { [ErrorCode.ERR_PARAM]: "- An invalid parameter was passed.\n - This API was called before updateFirmware was executed." }) || error; } } /** * Downloads the firmware image from the server and instructs the printer to * overwrite the firmware image. * * Execute verifyUpdate after executing this API, and confirm that the printer * firmware has been overwritten by the firmware image. * * The return value from this API is the result of instructing writing of the * firmware image to the printer. It is not the execution result of the * overall firmware update. * * The progress and processing result of this API is notified to the listener * method specified in the listener parameter. * * @returns The maximum waiting time for the firmware update */ async updateFirmware(firmwareInfo) { this.#ensureConnected(); try { return await NativeInterface.updateFirmware(this.#id, JSON.stringify(firmwareInfo)); } catch (error) { throw getEpsonError(error) || error; } } /** * Forcibly sends the error recovery command from a recoverable error status * (example: auto cutter error). * * For details on recoverable errors, refer to the Technical Reference Guide * of each printer. * * - After recovering from a recoverable error, the buffer of the printer is * reset. * - For TM-H6000V, the “Command execution during offline” setting must be * enabled. \ * Refer to TM-H6000V Utility User’s Manual for more information. * - Available during ePOS-Device XML control. */ async forceRecover(timeout) { this.#ensureConnected(); try { return await NativeInterface.forceRecover(this.#id, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Forcibly sends the drawer kick command. * * - The drawer and optional external buzzer cannot be connected * simultaneously. * - For TM-H6000V, the “Command execution during offline” setting must be * enabled. \ * Refer to TM-H6000V Utility User’s Manual for more information. * - Available during ePOS-Device XML control. */ async forcePulse(drawer, time, timeout) { this.#ensureConnected(); try { return await NativeInterface.forcePulse(this.#id, drawer, time !== undefined ? time : Printer.PARAM_DEFAULT, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Forcibly sends the buzzer sound command. * * - The drawer and optional external buzzer cannot be connected * simultaneously. * - For TM-H6000V, the “Command execution during offline” setting must be * enabled. \ * Refer to TM-H6000V Utility User’s Manual for more information. * - Available during ePOS-Device XML control. */ async forceStopSound(timeout) { this.#ensureConnected(); try { return await NativeInterface.forceStopSound(this.#id, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Forcibly sends the ESC/POS command. * * - For TM-H6000V, the “Command execution during offline” setting must be * enabled. \ * Refer to TM-H6000V Utility User’s Manual for more information. * - Available during ePOS-Device XML control. */ async forceCommand(/** Base64 encoded byte[] */ data, timeout) { this.#ensureConnected(); try { return await NativeInterface.forceCommand(this.#id, data, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } /** * Forcibly sends the printer reset command. * * - For TM-H6000V, the “Command execution during offline” setting must be * enabled. \ * Refer to TM-H6000V Utility User’s Manual for more information. * - Available during ePOS-Device XML control. */ async forceReset(timeout) { this.#ensureConnected(); try { return await NativeInterface.forceReset(this.#id, timeout !== undefined ? timeout : Printer.PARAM_DEFAULT); } catch (error) { throw getEpsonError(error) || error; } } #mutex = Promise.resolve(); /** * Sending print data in the callback as a single transaction. */ async transaction(callback) { this.#mutex = this.#mutex.then(async () => { await this.beginTransaction(); await callback(this); await this.endTransaction(); }); await this.#mutex; } /** * Sending print data in the callback as a single rotate batch. */ async rotate(callback) { this.#mutex = this.#mutex.then(async () => { await this.addRotateBegin(); await callback(this); await this.addRotateEnd(); });