npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@litepos/pos-epoint

v1.0.0

Published

Epoint Landlord POS integration - polls LitePOS API and sends orders via serial port

Downloads

18

Readme

@litepos/pos-epoint

LitePOS 与 Epoint 业主收银 POS 的集成服务。定时从 LitePOS API 拉取已付款账单,通过串口发送给 Epoint POS。

运行环境

  • Windows x64(需要串口 COM 口)
  • RS-232 串口线(直连,无需 RTS/CTS)
  • 部署机器无需安装 Node.js——LitePosEpoint.exe 已内嵌 Node 运行时

快速开始

1. 打包部署文件(开发机)

cd packages/pos-epoint
pnpm build:deploy

生成 dist/deploy/ 目录,将该目录完整复制到目标机器。

2. 配置(目标机器)

编辑 deploy/.env

# LitePOS API
POS_API_URL=http://192.168.1.100:3000/api
POS_API_KEY=你的API密钥

# 轮询间隔(毫秒)
POLL_INTERVAL_MS=5000

# 串口
SERIAL_PORT=COM3
SERIAL_BAUD_RATE=9600
SERIAL_RETRY_COUNT=3
SERIAL_TIMEOUT_MS=5000
SERIAL_RTSCTS=false

# 日志目录
LOG_DIR=./logs

LOG_LEVEL=info

串口号在设备管理器 → 端口中查看。如果线缆未接 RTS/CTS 引脚,SERIAL_RTSCTS 设为 false

3. 测试串口连接

test-serial.bat COM3

输出 ACK (0x06) - Connection OK! 表示连接成功。

4. 安装为 Windows 服务

右键 install-service.bat以管理员身份运行。脚本会通过 NSSM 注册名为 LitePosEpoint 的服务,配置开机自启、崩溃自动重启、stdout/stderr 滚动写入 logs/

卸载:右键 uninstall-service.bat以管理员身份运行

服务管理(以管理员身份运行 cmd):

nssm.exe start LitePosEpoint
nssm.exe stop LitePosEpoint
nssm.exe restart LitePosEpoint
nssm.exe status LitePosEpoint

或在 services.msc 里以图形界面管理。

前台调试:双击 LitePosEpoint.exe 直接运行可看到实时日志。


配置项说明

| 环境变量 | 默认值 | 说明 | |----------|--------|------| | POS_API_URL | 必填 | LitePOS API 地址,结尾不加 / | | POS_API_KEY | 必填 | API 鉴权密钥,请求头 X-API-Key | | POLL_INTERVAL_MS | 5000 | 轮询间隔(毫秒) | | SERIAL_PORT | COM1 | 串口号 | | SERIAL_BAUD_RATE | 9600 | 波特率 | | SERIAL_RETRY_COUNT | 3 | 发送失败重试次数 | | SERIAL_TIMEOUT_MS | 5000 | 等待 ACK/NAK 超时(毫秒) | | SERIAL_RTSCTS | true | 硬件流控,无 RTS/CTS 线缆时设 false | | LOG_DIR | ./logs | 日志文件目录 | | LOG_LEVEL | info | 日志级别(debug/info/warn/error) |


运行逻辑

启动
 │
 ├─ 读取 .env 配置
 ├─ 连接串口
 ├─ 读取 data/state.json(恢复上次处理进度)
 │
 └─ 每隔 POLL_INTERVAL_MS 循环:
      ├─ GET /invoices?status=paid
      ├─ 过滤 id_in_server > lastId 的新账单
      ├─ 按 id 顺序逐条处理:
      │    ├─ 转换为 Epoint 串口格式
      │    ├─ 发送,等待 ACK/NAK
      │    ├─ 成功 → 更新 lastId,继续
      │    └─ 失败(重试 N 次)→ 程序退出(避免跳单)
      └─ 等待下一轮
  • 程序重启后从 data/state.json 续传,不会重复发送
  • 某条账单发送失败会停止程序,需人工处理后重启

日志

日志同时写入本地文件和云端平台:

  • 本地文件logs/YYYY-MM-DD.log,每天一个文件,JSON Lines 格式
  • 云端https://logs.xposhq.com/,service 为 pos-epoint

日志示例:

{"message":"Invoice sent","level":"info","ref_id":"T10-123456","timestamp":"2026-04-24T10:30:00.000Z"}
{"message":"Error fetching invoices","level":"error","error":"Network Error","timestamp":"2026-04-24T10:30:05.000Z"}

后端 API 规格

程序调用 LitePOS 后端的一个接口:

GET /invoices?status=paid

请求头:

X-API-Key: <POS_API_KEY>

响应:

[
  {
    "uid": "inv_abc123",
    "id_in_server": 1042,
    "ref_id": "T10-123456",
    "table_name": "10",
    "discount_amount": 1.00,
    "lines": [
      {
        "item": {
          "sku": "0001",
          "name": "Soup Noodle",
          "category_uid": "FOOD"
        },
        "quantity": 1,
        "price": 10.00,
        "discount_amount": 0.00,
        "modifiers": []
      }
    ]
  }
]

字段说明:

| 字段 | 说明 | |------|------| | id_in_server | 单调递增整数,去重依据,必须唯一且递增 | | uid | 账单唯一字符串 ID | | ref_id | 账单编号,取末尾 6 位数字作为 Epoint CheckNumber | | table_name | 桌号,不足 4 位左补 0 | | discount_amount | 整单折扣,> 0 时生成 Epoint D 行 | | lines[].price | 折前单价 | | lines[].discount_amount | 单品折扣 | | lines[].modifiers[].price | 为 0 的 modifier 不发送 |


Epoint 串口接口格式

串口参数:9600, N, 8, 1,数据帧格式:<STX> <data> <ETX> <LRC>

生成的接口文件内容:

F,0010_123456.TXT
I,123456,0001,Soup Noodle,1,10.00,0.00,FOOD
I,123456,0002,Orange Juice,1,5.00,2.50,BEV
D,1.00
  • F 行:文件名(桌号_账单号.TXT
  • I 行:每个商品一行(I,账单号,SKU,名称,数量,折前价,折扣,部门
  • D 行:整单折扣(可选,与单品折扣不能同时存在)

响应:ACK (0x06) 成功,NAK (0x15) 校验失败自动重试。


目录结构(部署包)

deploy/
  LitePosEpoint.exe       # 主程序(内嵌 Node 运行时)
  test-serial.exe         # 串口测试程序
  test-serial.bat         # 串口测试启动器
  nssm.exe                # 服务管理器
  install-service.bat     # 注册为 Windows 服务(管理员)
  uninstall-service.bat   # 卸载服务(管理员)
  .env                    # 配置文件(需修改)
  data/                   # 运行状态(state.json)
  logs/                   # 应用日志 + 服务 stdout/stderr