send ping
This commit is contained in:
+51
-11
@@ -18,7 +18,7 @@ class WallPlotter {
|
||||
// Static constants
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static VERSION = '2.3.4';
|
||||
static VERSION = '2.3.5';
|
||||
static MIN_FEED_MM_MIN = 1;
|
||||
static MAX_FEED_MM_MIN = 10000;
|
||||
/** Offline overlay size when not connected (mm) — 150×150 cm centred on origin */
|
||||
@@ -32,6 +32,8 @@ class WallPlotter {
|
||||
/** If a USB write does not complete, the ACM device is usually gone. */
|
||||
static WRITE_TIMEOUT_MS = 3000;
|
||||
static RESUME_STORAGE_KEY = 'wallplotter.resume.v1';
|
||||
/** Send a quiet M400 if the line has been silent this long (keeps USB awake). */
|
||||
static KEEPALIVE_MS = 1200;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Construction
|
||||
@@ -118,6 +120,8 @@ class WallPlotter {
|
||||
this._okWaiter = null;
|
||||
this._sendChain = Promise.resolve();
|
||||
this._lastBusyLogAt = 0;
|
||||
this._lastSendAt = 0;
|
||||
this._keepaliveTimer = null;
|
||||
|
||||
// --- Keyboard / buttons ---
|
||||
this._keysEnabled = false;
|
||||
@@ -429,6 +433,7 @@ class WallPlotter {
|
||||
|
||||
this.writer = this.port.writable.getWriter();
|
||||
this._startReadLoop();
|
||||
this._startKeepalive();
|
||||
this._link = 'connected';
|
||||
this.onStatusChange('connected');
|
||||
|
||||
@@ -493,6 +498,7 @@ class WallPlotter {
|
||||
if (this._link === 'disconnected' && !this.port) return;
|
||||
|
||||
this.readLoopActive = false;
|
||||
this._stopKeepalive();
|
||||
this._cancelPendingOk();
|
||||
this._rxBuf = '';
|
||||
|
||||
@@ -538,6 +544,7 @@ class WallPlotter {
|
||||
_releaseSerialNow() {
|
||||
if (!this.port && this._link === 'disconnected') return;
|
||||
this.readLoopActive = false;
|
||||
this._stopKeepalive();
|
||||
this._cancelPendingOk();
|
||||
this._rxBuf = '';
|
||||
const reader = this.reader;
|
||||
@@ -569,7 +576,7 @@ class WallPlotter {
|
||||
}
|
||||
}
|
||||
|
||||
_writeLine(command) {
|
||||
_writeLine(command, quiet = false) {
|
||||
if (!this.writer) {
|
||||
return Promise.reject(new Error('Not connected to plotter'));
|
||||
}
|
||||
@@ -588,7 +595,7 @@ class WallPlotter {
|
||||
if (done) return;
|
||||
done = true;
|
||||
clearTimeout(timer);
|
||||
this.onLog('→ ' + command);
|
||||
if (!quiet) this.onLog('→ ' + command);
|
||||
resolve();
|
||||
},
|
||||
(err) => {
|
||||
@@ -673,9 +680,9 @@ class WallPlotter {
|
||||
if (this._unloadBound) return;
|
||||
this._unloadBound = true;
|
||||
const release = () => {
|
||||
this._stashInterruptedPath();
|
||||
this._persistResumeState(true);
|
||||
this._releaseSerialNow();
|
||||
this._stashInterruptedPath();
|
||||
this._persistResumeState(true);
|
||||
this._releaseSerialNow();
|
||||
};
|
||||
window.addEventListener('pagehide', release);
|
||||
window.addEventListener('beforeunload', release);
|
||||
@@ -806,15 +813,18 @@ class WallPlotter {
|
||||
return;
|
||||
}
|
||||
|
||||
this._lastSendAt = performance.now();
|
||||
const waitOk = options.waitOk !== false;
|
||||
const quiet = options.quiet === true || /^M400\b/i.test(command);
|
||||
const okPromise = waitOk
|
||||
? this._waitForOk(options.timeoutMs ?? WallPlotter.OK_TIMEOUT_MS, {
|
||||
command,
|
||||
waitLogAfterMs: options.waitLogAfterMs,
|
||||
quiet,
|
||||
})
|
||||
: null;
|
||||
try {
|
||||
const written = this._writeLine(command);
|
||||
const written = this._writeLine(command, quiet);
|
||||
if (okPromise) {
|
||||
await Promise.all([
|
||||
written.catch((err) => {
|
||||
@@ -1268,8 +1278,11 @@ class WallPlotter {
|
||||
|
||||
_waitForOk(timeoutMs, options = {}) {
|
||||
const command = options.command || '';
|
||||
const waitLogAfterMs = options.waitLogAfterMs ?? WallPlotter.OK_WAIT_LOG_MS;
|
||||
const waitLabel = command ? ` (${command})` : '';
|
||||
const quiet = options.quiet === true;
|
||||
const waitLogAfterMs = quiet
|
||||
? Math.max(options.waitLogAfterMs ?? WallPlotter.OK_WAIT_LOG_MS, 8000)
|
||||
: options.waitLogAfterMs ?? WallPlotter.OK_WAIT_LOG_MS;
|
||||
const waitLabel = command && !quiet ? ` (${command})` : '';
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this._okWaiter) {
|
||||
@@ -1339,6 +1352,32 @@ class WallPlotter {
|
||||
waiter.reject(err);
|
||||
}
|
||||
|
||||
_startKeepalive() {
|
||||
this._stopKeepalive();
|
||||
this._keepaliveTimer = setInterval(() => {
|
||||
this._keepaliveTick();
|
||||
}, WallPlotter.KEEPALIVE_MS);
|
||||
}
|
||||
|
||||
_stopKeepalive() {
|
||||
if (this._keepaliveTimer != null) {
|
||||
clearInterval(this._keepaliveTimer);
|
||||
this._keepaliveTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
_keepaliveTick() {
|
||||
if (this._link !== 'connected' || !this.writer) return;
|
||||
if (this._okWaiter || this._job === 'aborting') return;
|
||||
if (performance.now() - this._lastSendAt < WallPlotter.KEEPALIVE_MS) return;
|
||||
this.send('M400', {
|
||||
quiet: true,
|
||||
allowWithoutHome: true,
|
||||
timeoutMs: 4000,
|
||||
waitLogAfterMs: 10000,
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
_startReadLoop() {
|
||||
this.readLoopActive = true;
|
||||
const plotter = this;
|
||||
@@ -1403,8 +1442,9 @@ class WallPlotter {
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.onLog('← ' + line);
|
||||
if (/^(echo:\s*)?ok\b/i.test(line)) {
|
||||
const isOk = /^(echo:\s*)?ok\b/i.test(line);
|
||||
if (!isOk) this.onLog('← ' + line);
|
||||
if (isOk) {
|
||||
const waiter = this._okWaiter;
|
||||
if (waiter) waiter.resolve();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user