mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-18 21:47:39 +02:00
feat(printers): airduct mode + status badges + force refresh on printer card
Surface four Home Assistant-style controls on the Printers page card:
- SD Card badge in the top status row (green / red, icon-only).
- Enclosure Door badge in the top status row (green / yellow, icon-only).
Detection per printer family — X1/X1C/X1E read home_flag bit 23, all
others read top-level `stat` (hex string) bit 23 — so X1 firmware that
does not flip stat bit 23 stops false-triggering "open". WebSocket
status-change dedup key now includes door_open so toggling the door
alone publishes a push, no 30s REST-poll wait.
- Airduct Mode badge beside the speed control (cooling / heating)
for P2S/H2D/H2C/H2S; one-click dropdown calls the existing
set_airduct MQTT command via a new POST /printers/{id}/airduct-mode
route.
- Force Refresh entry in the kebab menu — calls the existing
/printers/{id}/refresh-status endpoint to request a pushall snapshot
without forcing a reconnect.
Tests: door-open parsing (X1 home_flag, non-X1 stat, ignore mismatched
source, invalid hex) and airduct route (validation, not-connected,
success, failure).
This commit is contained in:
@@ -206,3 +206,38 @@ describe('FormData requests include auth header', () => {
|
||||
expect(capturedHeaders!.get('Authorization')).toBe('Bearer test-token');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Printer control endpoints', () => {
|
||||
it('refreshPrinterStatus POSTs to /printers/:id/refresh-status', async () => {
|
||||
let calledUrl: string | null = null;
|
||||
let calledMethod: string | null = null;
|
||||
server.use(
|
||||
http.post('/api/v1/printers/:id/refresh-status', ({ request, params }) => {
|
||||
calledUrl = `/printers/${params.id}/refresh-status`;
|
||||
calledMethod = request.method;
|
||||
return HttpResponse.json({ status: 'ok' });
|
||||
}),
|
||||
);
|
||||
|
||||
const result = await api.refreshPrinterStatus(7);
|
||||
expect(calledMethod).toBe('POST');
|
||||
expect(calledUrl).toBe('/printers/7/refresh-status');
|
||||
expect(result).toEqual({ status: 'ok' });
|
||||
});
|
||||
|
||||
it('setAirductMode passes mode in query string', async () => {
|
||||
let capturedUrl = '';
|
||||
server.use(
|
||||
http.post('/api/v1/printers/:id/airduct-mode', ({ request }) => {
|
||||
capturedUrl = request.url;
|
||||
return HttpResponse.json({ success: true, message: 'ok' });
|
||||
}),
|
||||
);
|
||||
|
||||
await api.setAirductMode(3, 'cooling');
|
||||
expect(capturedUrl).toContain('mode=cooling');
|
||||
|
||||
await api.setAirductMode(3, 'heating');
|
||||
expect(capturedUrl).toContain('mode=heating');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user