Working tree changes 2024-08-08 01:00
All checks were successful
Test project build / Build (push) Successful in 1m12s

This commit is contained in:
Bot 2024-08-08 01:00:01 +03:00 committed by multimote
parent 4833283963
commit 356e0a9c56
8 changed files with 220 additions and 6 deletions

1
.gitignore vendored
View File

@ -27,3 +27,4 @@
!/niimbluelib/tsconfig.json
!/niimbluelib/yarn.lock
!/niimbluelib/src
!/niimbluelib/utils

View File

@ -5,10 +5,14 @@ import {
HeartbeatEvent,
NiimbotBluetoothClient,
NiimbotSerialClient,
PacketReceivedEvent,
PacketSentEvent,
PrinterInfoFetchedEvent,
// PacketParsedEvent,
RawPacketReceivedEvent,
RawPacketSentEvent,
RequestCommandId,
ResponseCommandId,
Utils,
type HeartbeatData,
type NiimbotAbstractClient,
@ -43,12 +47,21 @@ export const initClient = (connectionType: ConnectionType) => {
newClient = new NiimbotSerialClient();
}
newClient.addEventListener("rawpacketsent", (e: RawPacketSentEvent) => {
console.log(`>> ${Utils.bufToHex(e.data)}`);
// newClient.addEventListener("rawpacketsent", (e: RawPacketSentEvent) => {
// console.log(`>> ${Utils.bufToHex(e.data)}`);
// });
newClient.addEventListener("packetsent", (e: PacketSentEvent) => {
console.log(`>> ${Utils.bufToHex(e.packet.toBytes())} (${RequestCommandId[e.packet.command]})`);
});
newClient.addEventListener("rawpacketreceived", (e: RawPacketReceivedEvent) => {
console.log(`<< ${Utils.bufToHex(e.data)}`);
// newClient.addEventListener("rawpacketreceived", (e: RawPacketReceivedEvent) => {
// console.log(`<< ${Utils.bufToHex(e.data)}`);
// });
newClient.addEventListener("packetreceived", (e: PacketReceivedEvent) => {
console.log(`<< ${Utils.bufToHex(e.packet.toBytes())} (${ResponseCommandId[e.packet.command]})`);
});
newClient.addEventListener("connect", (e: ConnectEvent) => {

View File

@ -33,6 +33,17 @@ export class PacketReceivedEvent extends Event {
}
}
/**
*
*/
export class PacketSentEvent extends Event {
packet: NiimbotPacket;
constructor(packet: NiimbotPacket) {
super("packetsent");
this.packet = packet;
}
}
/**
*
*/
@ -83,6 +94,7 @@ export interface ClientEventMap {
rawpacketsent: RawPacketSentEvent;
rawpacketreceived: RawPacketReceivedEvent;
packetreceived: PacketReceivedEvent;
packetsent: PacketSentEvent;
heartbeat: HeartbeatEvent;
printerinfofetched: PrinterInfoFetchedEvent;
}

View File

@ -8,7 +8,7 @@ import {
ProtocolVersion,
} from "../packets";
import { TypedEventTarget } from "typescript-event-target";
import { ClientEventMap, HeartbeatEvent, PrinterInfoFetchedEvent } from "./events";
import { ClientEventMap, HeartbeatEvent, PacketSentEvent, PrinterInfoFetchedEvent } from "./events";
import { Abstraction } from "../packets/abstraction";
import { getPrinterMetaById, PrinterModelMeta } from "..";
@ -62,6 +62,7 @@ export abstract class NiimbotAbstractClient extends TypedEventTarget<ClientEvent
public async sendPacket(packet: NiimbotPacket, force?: boolean) {
await this.sendRaw(packet.toBytes(), force);
this.dispatchTypedEvent("packetsent", new PacketSentEvent(packet));
}
/** Send "connect" packet and fetch the protocol version */

View File

@ -73,7 +73,7 @@ export class NiimbotSerialClient extends NiimbotAbstractClient {
try {
const result = await this.reader!.read();
if (result.value) {
console.info(`<< serial chunk ${Utils.bufToHex(result.value)}`); // todo: remove
// console.info(`<< serial chunk ${Utils.bufToHex(result.value)}`);
const newBuf = new Uint8Array(buf.length + result.value.length);
newBuf.set(buf, 0);

View File

@ -0,0 +1,85 @@
// https://print.niimbot.com/api/hardware/list
fetch("https://oss-print.niimbot.com/public_resources/static_resources/devices.json")
.then((resp) => resp.json())
.then((items) => {
const dir_d = {
270: "left",
180: "top",
90: "left",
0: "top",
};
const ppmm_d = {
203: 8,
300: 11.81,
};
const labeltypes_d = {
"1": "LT.WithGaps",
"2": "LT.Black",
"3": "LT.Continuous",
"4": "LT.Perforated",
"5": "LT.Transparent",
"6": "LT.PvcTag",
"10": "LT.BlackMarkGap",
"11": "LT.HeatShrinkTube",
}
console.log("/* AUTO-GENERATED FILE. DO NOT EDIT! */");
console.log("/* use 'yarn gen-printer-models' to generate */\n");
console.log('import { PrintDirection, LabelType as LT } from ".";\n');
console.log("export enum PrinterModel {");
console.log(' UNKNOWN = "UNKNOWN",');
for (const item of items) {
const name = item.name.toUpperCase().replaceAll("-", "_");
console.log(` ${name} = "${name}",`);
}
console.log("};");
console.log(`
export interface PrinterModelMeta {
model: PrinterModel;
id: [number, ...number[]];
dpi: number;
printDirection: PrintDirection;
printheadPixels: number;
paperTypes: number[];
}
`);
console.log("export const modelsLibrary: PrinterModelMeta[] = [");
for (const item of items) {
if (item.codes.length === 0) {
continue;
}
const name = item.name.toUpperCase().replaceAll("-", "_");
const dir = dir_d[item.printDirection];
const ppmm = ppmm_d[item.paccuracyName];
const paperTypes = item.paperType.split(',').map(e => labeltypes_d[e]).join(", ");
console.log(" {");
console.log(` model: PrinterModel.${name},`);
console.log(` id: [${item.codes.join(', ')}],`);
console.log(` dpi: ${item.paccuracyName},`);
console.log(` printDirection: "${dir}",`);
console.log(` printheadPixels: ${Math.ceil(item.widthSetEnd * ppmm)},`);
console.log(` paperTypes: [${paperTypes}],`);
console.log(" },");
}
console.log("];");
console.log(`
export const getPrinterMetaById = (id: number): PrinterModelMeta | undefined => {
return modelsLibrary.find((o) => o.id.includes(id));
};
export const getPrinterMetaByModel = (model: PrinterModel): PrinterModelMeta | undefined => {
return modelsLibrary.find((o) => o.model === model);
};`);
});

View File

@ -0,0 +1,102 @@
import { Utils, NiimbotPacket, RequestCommandId, ResponseCommandId } from "../dist/index.js";
import { spawn } from "child_process";
const TSHARK_PATH = "C:\\Program Files\\Wireshark\\tshark.exe";
if (process.argv.length < 4 || !["usb", "ble"].includes(process.argv[2])) {
console.error("usage: yarn parse-dump <ble|usb> <filename> [min|min-out]");
}
const capType = process.argv[2];
const capPath = process.argv[3];
const args = ["-2", "-r", capPath, "-P", "-T", "fields", "-e", /*"frame.time_relative"*/ "frame.time_delta"];
const display = process.argv.length > 4 ? process.argv[4] : "";
if (capType === "ble") {
args.push("-R", "btspp.data", "-e", "hci_h4.direction", "-e", "btspp.data");
} else {
args.push("-R", "usb.capdata", "-e", "usb.dst", "-e", "usb.capdata");
}
const spawned = spawn(TSHARK_PATH, args);
let output = "";
spawned.stdout.on("data", (data) => {
output += data.toString();
});
spawned.stderr.on("data", (data) => {
console.error(data);
});
spawned.on("close", (code) => {
console.log(`child process exited with code ${code}`);
if (code !== 0) {
console.error(output);
return;
}
const lines = output.split(/\r?\n/);
let printStarted = false;
for (const line of lines) {
const splitted = line.split("\t");
if (splitted.length !== 3) {
continue;
}
let [time, direction, hexData] = splitted;
direction = ["host", "0x01"].includes(direction) ? "<<" : ">>";
let comment = "";
try {
const data = Utils.hexToBuf(hexData);
const packets = NiimbotPacket.fromBytesMultiPacket(data);
if (packets.length === 0) {
comment = "Parse error (no packets found)";
} else if (packets.length > 1) {
comment = `Multi-packet (x${packets.length}); `;
}
for (const packet of packets) {
if (direction === ">>") {
comment += RequestCommandId[packet.command] ?? "???";
if (packet.command === RequestCommandId.PrintStart) {
printStarted = true;
const versions = { 1: "v1", 2: "v3", 7: "v4", 8: "v5" };
comment += "_" + versions[packet.dataLength];
} else if (packet.command === RequestCommandId.SetPageSize) {
const versions = { 2: "v1", 4: "v2", 6: "v3", 8: "v5" };
comment += "_" + versions[packet.dataLength];
}else if (packet.command === RequestCommandId.PrintEnd) {
printStarted = false;
}
} else {
comment += ResponseCommandId[packet.command] ?? "???";
}
comment += `(${packet.dataLength}); `;
}
} catch (e) {
comment = "Invalid packet";
}
if (display === "min") {
console.log(`${direction} ${comment}`);
} else if (display === "min-out") {
if (direction === ">>") {
console.log(`${direction} ${comment}`);
}
} else if (display === "print-task") {
if (direction === ">>" && printStarted) {
console.log(`${direction} ${comment}`);
}
} else {
console.log(`[${time}] ${direction} ${hexData}\t// ${comment}`);
}
}
});

View File