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.channel = undefined;
this.info = {};
this.stopHeartbeat();
this.dispatchTypedEvent("disconnect", new DisconnectEvent());
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 {
info: PrinterInfo;
constructor(info: PrinterInfo) {
@ -92,6 +100,7 @@ export interface ClientEventMap {
packetreceived: PacketReceivedEvent;
packetsent: PacketSentEvent;
heartbeat: HeartbeatEvent;
heartbeatfailed: HeartbeatFailedEvent;
printerinfofetched: PrinterInfoFetchedEvent;
printprogress: PrintProgressEvent;
}

@ -8,7 +8,7 @@ import {
NiimbotPacket,
} from "../packets";
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";
export type ConnectionInfo = {
@ -33,12 +33,17 @@ export abstract class NiimbotAbstractClient extends TypedEventTarget<ClientEvent
public readonly abstraction: Abstraction;
protected info: PrinterInfo = {};
private heartbeatTimer?: NodeJS.Timeout;
private heartbeatFails: number = 0;
private heartbeatIntervalMs: number = 2_000;
/** https://github.com/MultiMote/niimblue/issues/5 */
protected packetIntervalMs: number = 10;
constructor() {
super();
this.abstraction = new Abstraction(this);
this.addEventListener("connect", () => this.startHeartbeat())
this.addEventListener("disconnect", () => this.stopHeartbeat())
}
/** 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
*/
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.abstraction
.heartbeat()
.then((data) => {
this.heartbeatFails = 0;
this.dispatchTypedEvent("heartbeat", new HeartbeatEvent(data));
})
.catch(console.error);
}, intervalMs);
.catch((e) => {
console.error(e);
this.heartbeatFails++;
this.dispatchTypedEvent("heartbeatfailed", new HeartbeatFailedEvent(this.heartbeatFails));
});
}, this.heartbeatIntervalMs);
}
public stopHeartbeat(): void {

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

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