Improve heartbeat functionality, autostart heartbeat

This commit is contained in:
MultiMote 2024-10-10 21:58:24 +03:00
parent 51e67561f0
commit 91f7de3687
5 changed files with 50 additions and 10 deletions

@ -43,7 +43,6 @@ export class NiimbotBluetoothClient extends NiimbotAbstractClient {
this.gattServer = undefined; this.gattServer = undefined;
this.channel = undefined; this.channel = undefined;
this.info = {}; this.info = {};
this.stopHeartbeat();
this.dispatchTypedEvent("disconnect", new DisconnectEvent()); this.dispatchTypedEvent("disconnect", new DisconnectEvent());
device.removeEventListener("gattserverdisconnected", disconnectListener); device.removeEventListener("gattserverdisconnected", disconnectListener);
}; };

@ -57,6 +57,14 @@ export class HeartbeatEvent extends Event {
} }
} }
export class HeartbeatFailedEvent extends Event {
failedAttempts: number;
constructor(failedAttempts: number) {
super("heartbeatfailed");
this.failedAttempts = failedAttempts;
}
}
export class PrinterInfoFetchedEvent extends Event { export class PrinterInfoFetchedEvent extends Event {
info: PrinterInfo; info: PrinterInfo;
constructor(info: PrinterInfo) { constructor(info: PrinterInfo) {
@ -92,6 +100,7 @@ export interface ClientEventMap {
packetreceived: PacketReceivedEvent; packetreceived: PacketReceivedEvent;
packetsent: PacketSentEvent; packetsent: PacketSentEvent;
heartbeat: HeartbeatEvent; heartbeat: HeartbeatEvent;
heartbeatfailed: HeartbeatFailedEvent;
printerinfofetched: PrinterInfoFetchedEvent; printerinfofetched: PrinterInfoFetchedEvent;
printprogress: PrintProgressEvent; printprogress: PrintProgressEvent;
} }

@ -8,7 +8,7 @@ import {
NiimbotPacket, NiimbotPacket,
} from "../packets"; } from "../packets";
import { PrinterModelMeta, getPrinterMetaById } from "../printer_models"; import { PrinterModelMeta, getPrinterMetaById } from "../printer_models";
import { ClientEventMap, PacketSentEvent, PrinterInfoFetchedEvent, HeartbeatEvent } from "./events"; import { ClientEventMap, PacketSentEvent, PrinterInfoFetchedEvent, HeartbeatEvent, HeartbeatFailedEvent } from "./events";
import { getPrintTaskVersion, PrintTaskVersion } from "../print_task_versions"; import { getPrintTaskVersion, PrintTaskVersion } from "../print_task_versions";
export type ConnectionInfo = { export type ConnectionInfo = {
@ -33,12 +33,17 @@ export abstract class NiimbotAbstractClient extends TypedEventTarget<ClientEvent
public readonly abstraction: Abstraction; public readonly abstraction: Abstraction;
protected info: PrinterInfo = {}; protected info: PrinterInfo = {};
private heartbeatTimer?: NodeJS.Timeout; private heartbeatTimer?: NodeJS.Timeout;
private heartbeatFails: number = 0;
private heartbeatIntervalMs: number = 2_000;
/** https://github.com/MultiMote/niimblue/issues/5 */ /** https://github.com/MultiMote/niimblue/issues/5 */
protected packetIntervalMs: number = 10; protected packetIntervalMs: number = 10;
constructor() { constructor() {
super(); super();
this.abstraction = new Abstraction(this); this.abstraction = new Abstraction(this);
this.addEventListener("connect", () => this.startHeartbeat())
this.addEventListener("disconnect", () => this.stopHeartbeat())
} }
/** Connect to printer port */ /** Connect to printer port */
@ -102,19 +107,38 @@ export abstract class NiimbotAbstractClient extends TypedEventTarget<ClientEvent
} }
/** /**
* Starts the heartbeat timer, "heartbeat" is emitted after packet received. * Set interval for {@link startHeartbeat}.
* *
* @param interval Heartbeat interval, default is 1000ms * @param interval Heartbeat interval, default is 1000ms
*/ */
public startHeartbeat(intervalMs: number = 1000): void { public setHeartbeatInterval(intervalMs: number): void {
this.heartbeatIntervalMs = intervalMs;
}
/**
* Starts the heartbeat timer, "heartbeat" is emitted after packet received.
*
* If you need to change interval, call {@link setHeartbeatInterval} before.
*/
public startHeartbeat(): void {
this.heartbeatFails = 0;
this.stopHeartbeat();
this.heartbeatTimer = setInterval(() => { this.heartbeatTimer = setInterval(() => {
this.abstraction this.abstraction
.heartbeat() .heartbeat()
.then((data) => { .then((data) => {
this.heartbeatFails = 0;
this.dispatchTypedEvent("heartbeat", new HeartbeatEvent(data)); this.dispatchTypedEvent("heartbeat", new HeartbeatEvent(data));
}) })
.catch(console.error); .catch((e) => {
}, intervalMs); console.error(e);
this.heartbeatFails++;
this.dispatchTypedEvent("heartbeatfailed", new HeartbeatFailedEvent(this.heartbeatFails));
});
}, this.heartbeatIntervalMs);
} }
public stopHeartbeat(): void { public stopHeartbeat(): void {

@ -25,7 +25,6 @@ export class NiimbotSerialClient extends NiimbotAbstractClient {
_port.addEventListener("disconnect", () => { _port.addEventListener("disconnect", () => {
this.port = undefined; this.port = undefined;
console.log("serial disconnect event");
this.dispatchTypedEvent("disconnect", new DisconnectEvent()); this.dispatchTypedEvent("disconnect", new DisconnectEvent());
}); });

@ -92,8 +92,8 @@ export class Abstraction {
} }
/** Send packet and wait for response */ /** Send packet and wait for response */
private async send(packet: NiimbotPacket): Promise<NiimbotPacket> { private async send(packet: NiimbotPacket, forceTimeout?: number): Promise<NiimbotPacket> {
return this.client.sendPacketWaitResponse(packet, this.timeout); return this.client.sendPacketWaitResponse(packet, forceTimeout ?? this.timeout);
} }
public async getPrintStatus(): Promise<PrintStatus> { public async getPrintStatus(): Promise<PrintStatus> {
@ -200,7 +200,7 @@ export class Abstraction {
} }
public async heartbeat(): Promise<HeartbeatData> { public async heartbeat(): Promise<HeartbeatData> {
const packet = await this.send(PacketGenerator.heartbeat(HeartbeatType.Advanced1)); const packet = await this.send(PacketGenerator.heartbeat(HeartbeatType.Advanced1), 500);
const info: HeartbeatData = { const info: HeartbeatData = {
paperState: -1, paperState: -1,
@ -342,6 +342,15 @@ export class Abstraction {
await this.send(PacketGenerator.printerReset()); await this.send(PacketGenerator.printerReset());
} }
/**
*
* Call client.stopHeartbeat before print is started!
*
* @param taskVersion
* @param image
* @param options
* @param timeout
*/
public async print( public async print(
taskVersion: PrintTaskVersion, taskVersion: PrintTaskVersion,
image: EncodedImage, image: EncodedImage,