@agentdeck/bridge 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/fm-helper/agentdeck-fm-helper +0 -0
- package/dist/apme/collector.d.ts.map +1 -1
- package/dist/apme/collector.js +5 -2
- package/dist/apme/collector.js.map +1 -1
- package/dist/apme/runner.d.ts +11 -0
- package/dist/apme/runner.d.ts.map +1 -1
- package/dist/apme/runner.js +60 -4
- package/dist/apme/runner.js.map +1 -1
- package/dist/apme/settings.d.ts +10 -0
- package/dist/apme/settings.d.ts.map +1 -1
- package/dist/apme/settings.js +14 -0
- package/dist/apme/settings.js.map +1 -1
- package/dist/awaiting-overlay.d.ts +44 -10
- package/dist/awaiting-overlay.d.ts.map +1 -1
- package/dist/awaiting-overlay.js +96 -28
- package/dist/awaiting-overlay.js.map +1 -1
- package/dist/bridge-core.d.ts +10 -0
- package/dist/bridge-core.d.ts.map +1 -1
- package/dist/bridge-core.js +47 -12
- package/dist/bridge-core.js.map +1 -1
- package/dist/card-feed.d.ts +107 -0
- package/dist/card-feed.d.ts.map +1 -0
- package/dist/card-feed.js +277 -0
- package/dist/card-feed.js.map +1 -0
- package/dist/card-modules.d.ts +87 -0
- package/dist/card-modules.d.ts.map +1 -0
- package/dist/card-modules.js +179 -0
- package/dist/card-modules.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +232 -69
- package/dist/cli.js.map +1 -1
- package/dist/daemon-server.d.ts.map +1 -1
- package/dist/daemon-server.js +1008 -47
- package/dist/daemon-server.js.map +1 -1
- package/dist/daemon-ws-client.d.ts +2 -1
- package/dist/daemon-ws-client.d.ts.map +1 -1
- package/dist/daemon-ws-client.js +2 -1
- package/dist/daemon-ws-client.js.map +1 -1
- package/dist/daemon.js +1 -1
- package/dist/device-photo.d.ts +86 -0
- package/dist/device-photo.d.ts.map +1 -0
- package/dist/device-photo.js +200 -0
- package/dist/device-photo.js.map +1 -0
- package/dist/device-voice-reply.d.ts +124 -0
- package/dist/device-voice-reply.d.ts.map +1 -0
- package/dist/device-voice-reply.js +236 -0
- package/dist/device-voice-reply.js.map +1 -0
- package/dist/device-voice.d.ts +56 -0
- package/dist/device-voice.d.ts.map +1 -0
- package/dist/device-voice.js +134 -0
- package/dist/device-voice.js.map +1 -0
- package/dist/esp32-serial.d.ts +40 -0
- package/dist/esp32-serial.d.ts.map +1 -1
- package/dist/esp32-serial.js +109 -13
- package/dist/esp32-serial.js.map +1 -1
- package/dist/foundation-models-helper.d.ts +30 -0
- package/dist/foundation-models-helper.d.ts.map +1 -1
- package/dist/foundation-models-helper.js +45 -0
- package/dist/foundation-models-helper.js.map +1 -1
- package/dist/idotmatrix/idotmatrix-daemon-sync.d.ts.map +1 -1
- package/dist/idotmatrix/idotmatrix-daemon-sync.js +5 -18
- package/dist/idotmatrix/idotmatrix-daemon-sync.js.map +1 -1
- package/dist/idotmatrix/idotmatrix-discover.d.ts.map +1 -1
- package/dist/idotmatrix/idotmatrix-discover.js +6 -14
- package/dist/idotmatrix/idotmatrix-discover.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/mdns.d.ts +11 -0
- package/dist/mdns.d.ts.map +1 -1
- package/dist/mdns.js +13 -0
- package/dist/mdns.js.map +1 -1
- package/dist/observed-inject.d.ts +119 -0
- package/dist/observed-inject.d.ts.map +1 -0
- package/dist/observed-inject.js +405 -0
- package/dist/observed-inject.js.map +1 -0
- package/dist/passive-observer.d.ts +14 -0
- package/dist/passive-observer.d.ts.map +1 -1
- package/dist/passive-observer.js +35 -5
- package/dist/passive-observer.js.map +1 -1
- package/dist/peripheral-mapping.d.ts +65 -0
- package/dist/peripheral-mapping.d.ts.map +1 -0
- package/dist/peripheral-mapping.js +115 -0
- package/dist/peripheral-mapping.js.map +1 -0
- package/dist/python-ble-runtime.d.ts +62 -0
- package/dist/python-ble-runtime.d.ts.map +1 -0
- package/dist/python-ble-runtime.js +215 -0
- package/dist/python-ble-runtime.js.map +1 -0
- package/dist/session-aggregator.d.ts +4 -1
- package/dist/session-aggregator.d.ts.map +1 -1
- package/dist/session-aggregator.js +5 -5
- package/dist/session-aggregator.js.map +1 -1
- package/dist/session-id-resolve.d.ts +17 -0
- package/dist/session-id-resolve.d.ts.map +1 -0
- package/dist/session-id-resolve.js +35 -0
- package/dist/session-id-resolve.js.map +1 -0
- package/dist/session-transcript-timeline.d.ts +7 -0
- package/dist/session-transcript-timeline.d.ts.map +1 -1
- package/dist/session-transcript-timeline.js +16 -6
- package/dist/session-transcript-timeline.js.map +1 -1
- package/dist/timebox/timebox-daemon-sync.d.ts.map +1 -1
- package/dist/timebox/timebox-daemon-sync.js +5 -20
- package/dist/timebox/timebox-daemon-sync.js.map +1 -1
- package/dist/timebox/timebox-discover.d.ts.map +1 -1
- package/dist/timebox/timebox-discover.js +6 -15
- package/dist/timebox/timebox-discover.js.map +1 -1
- package/dist/timeline-store.js +2 -2
- package/dist/timeline-store.js.map +1 -1
- package/dist/usage-event.d.ts.map +1 -1
- package/dist/usage-event.js +14 -7
- package/dist/usage-event.js.map +1 -1
- package/dist/voice.d.ts +13 -10
- package/dist/voice.d.ts.map +1 -1
- package/dist/voice.js +26 -272
- package/dist/voice.js.map +1 -1
- package/dist/ws-server.d.ts +14 -0
- package/dist/ws-server.d.ts.map +1 -1
- package/dist/ws-server.js +66 -1
- package/dist/ws-server.js.map +1 -1
- package/fm-helper/AgentDeckFMHelper.swift +303 -0
- package/package.json +8 -4
- package/python/requirements-ble.txt +5 -0
- package/src/idotmatrix/brightness.py +40 -0
- package/src/idotmatrix/scan.py +35 -0
- package/src/idotmatrix/sync.py +400 -0
- package/src/pysync/matrix_sync_common.py +89 -0
- package/src/timebox/scan_ble.py +52 -0
- package/src/timebox/sync_ble.py +394 -0
- package/dist/d200h/hid-protocol.d.ts +0 -62
- package/dist/d200h/hid-protocol.d.ts.map +0 -1
- package/dist/d200h/hid-protocol.js +0 -124
- package/dist/d200h/hid-protocol.js.map +0 -1
- package/dist/d200h/image-renderer.d.ts +0 -24
- package/dist/d200h/image-renderer.d.ts.map +0 -1
- package/dist/d200h/image-renderer.js +0 -321
- package/dist/d200h/image-renderer.js.map +0 -1
- package/dist/hook-migration.d.ts +0 -2
- package/dist/hook-migration.d.ts.map +0 -1
- package/dist/hook-migration.js +0 -104
- package/dist/hook-migration.js.map +0 -1
- package/dist/modules/d200h-module.d.ts +0 -65
- package/dist/modules/d200h-module.d.ts.map +0 -1
- package/dist/modules/d200h-module.js +0 -495
- package/dist/modules/d200h-module.js.map +0 -1
- package/dist/modules/d200h-renderer.d.ts +0 -7
- package/dist/modules/d200h-renderer.d.ts.map +0 -1
- package/dist/modules/d200h-renderer.js +0 -321
- package/dist/modules/d200h-renderer.js.map +0 -1
- package/dist/modules/trmnl-module.d.ts +0 -38
- package/dist/modules/trmnl-module.d.ts.map +0 -1
- package/dist/modules/trmnl-module.js +0 -111
- package/dist/modules/trmnl-module.js.map +0 -1
- package/dist/trmnl/byos-server.d.ts +0 -39
- package/dist/trmnl/byos-server.d.ts.map +0 -1
- package/dist/trmnl/byos-server.js +0 -301
- package/dist/trmnl/byos-server.js.map +0 -1
- package/dist/trmnl/frame-cache.d.ts +0 -37
- package/dist/trmnl/frame-cache.d.ts.map +0 -1
- package/dist/trmnl/frame-cache.js +0 -157
- package/dist/trmnl/frame-cache.js.map +0 -1
- package/dist/trmnl/image-renderer.d.ts +0 -27
- package/dist/trmnl/image-renderer.d.ts.map +0 -1
- package/dist/trmnl/image-renderer.js +0 -235
- package/dist/trmnl/image-renderer.js.map +0 -1
- package/dist/trmnl/trmnl-settings.d.ts +0 -96
- package/dist/trmnl/trmnl-settings.d.ts.map +0 -1
- package/dist/trmnl/trmnl-settings.js +0 -177
- package/dist/trmnl/trmnl-settings.js.map +0 -1
- package/dist/trmnl/trmnl-telemetry.d.ts +0 -47
- package/dist/trmnl/trmnl-telemetry.d.ts.map +0 -1
- package/dist/trmnl/trmnl-telemetry.js +0 -56
- package/dist/trmnl/trmnl-telemetry.js.map +0 -1
- package/dist/whisper-server-manager.d.ts +0 -19
- package/dist/whisper-server-manager.d.ts.map +0 -1
- package/dist/whisper-server-manager.js +0 -171
- package/dist/whisper-server-manager.js.map +0 -1
|
@@ -1,321 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* D200H framebuffer renderer — renders AgentDeck 14-key dashboard
|
|
3
|
-
* Screen: 960×540 logical (landscape), fb0: 540×960 with 90° CW rotation
|
|
4
|
-
* Transform: screen(sx,sy) → fb(sy, 959-sx)
|
|
5
|
-
* Layout: 3 rows × 5 cols, row2 col3+4 merged = 14 keys
|
|
6
|
-
*/
|
|
7
|
-
import { execSync } from 'child_process';
|
|
8
|
-
import { writeFileSync } from 'fs';
|
|
9
|
-
import { tmpdir } from 'os';
|
|
10
|
-
import { join } from 'path';
|
|
11
|
-
import { debug } from '../logger.js';
|
|
12
|
-
const TAG = 'd200h-render';
|
|
13
|
-
// Screen dimensions (logical, after rotation)
|
|
14
|
-
const SW = 960;
|
|
15
|
-
const SH = 540;
|
|
16
|
-
// Framebuffer dimensions (physical)
|
|
17
|
-
const FBW = 540;
|
|
18
|
-
const FBH = 960;
|
|
19
|
-
// Double buffer
|
|
20
|
-
const FB_SIZE = FBW * FBH * 2 * 4; // 2 pages, BGRA32
|
|
21
|
-
const PAGE_SIZE = FBW * FBH * 4;
|
|
22
|
-
// Key grid: 3 rows × 5 cols
|
|
23
|
-
const COLS = 5;
|
|
24
|
-
const ROWS = 3;
|
|
25
|
-
const COL_W = Math.floor(SW / COLS); // 192
|
|
26
|
-
const ROW_H = Math.floor(SH / ROWS); // 180
|
|
27
|
-
const GAP = 3;
|
|
28
|
-
const D200H_SERIAL = '0123456789ABCDEF';
|
|
29
|
-
// Colors (BGRA format)
|
|
30
|
-
const COLOR_BG = [20, 20, 25, 255]; // dark background
|
|
31
|
-
const COLOR_IDLE = [60, 50, 40, 255]; // slate
|
|
32
|
-
const COLOR_PROCESSING = [160, 80, 20, 255]; // blue (BGRA: high B)
|
|
33
|
-
const COLOR_AWAITING = [30, 140, 200, 255]; // amber
|
|
34
|
-
const COLOR_ERROR = [40, 40, 180, 255]; // red
|
|
35
|
-
const COLOR_TEXT = [220, 220, 220, 255]; // light gray
|
|
36
|
-
const COLOR_DIM = [120, 120, 120, 255]; // dim text
|
|
37
|
-
const COLOR_ACCENT = [200, 140, 40, 255]; // accent blue
|
|
38
|
-
const COLOR_GREEN = [60, 180, 60, 255]; // green
|
|
39
|
-
const COLOR_BAR_BG = [50, 50, 55, 255]; // gauge background
|
|
40
|
-
const COLOR_BAR_5H = [180, 160, 40, 255]; // 5h gauge color
|
|
41
|
-
const COLOR_BAR_7D = [160, 80, 40, 255]; // 7d gauge color
|
|
42
|
-
// 3×5 bitmap font — full alphanumeric (lowercase rendered, input lowercased)
|
|
43
|
-
const FONT_3X5 = {
|
|
44
|
-
'0': [0b111, 0b101, 0b101, 0b101, 0b111],
|
|
45
|
-
'1': [0b010, 0b110, 0b010, 0b010, 0b111],
|
|
46
|
-
'2': [0b111, 0b001, 0b111, 0b100, 0b111],
|
|
47
|
-
'3': [0b111, 0b001, 0b111, 0b001, 0b111],
|
|
48
|
-
'4': [0b101, 0b101, 0b111, 0b001, 0b001],
|
|
49
|
-
'5': [0b111, 0b100, 0b111, 0b001, 0b111],
|
|
50
|
-
'6': [0b111, 0b100, 0b111, 0b101, 0b111],
|
|
51
|
-
'7': [0b111, 0b001, 0b010, 0b010, 0b010],
|
|
52
|
-
'8': [0b111, 0b101, 0b111, 0b101, 0b111],
|
|
53
|
-
'9': [0b111, 0b101, 0b111, 0b001, 0b111],
|
|
54
|
-
'a': [0b010, 0b101, 0b111, 0b101, 0b101],
|
|
55
|
-
'b': [0b110, 0b101, 0b110, 0b101, 0b110],
|
|
56
|
-
'c': [0b011, 0b100, 0b100, 0b100, 0b011],
|
|
57
|
-
'd': [0b110, 0b101, 0b101, 0b101, 0b110],
|
|
58
|
-
'e': [0b111, 0b100, 0b110, 0b100, 0b111],
|
|
59
|
-
'f': [0b111, 0b100, 0b110, 0b100, 0b100],
|
|
60
|
-
'g': [0b011, 0b100, 0b101, 0b101, 0b011],
|
|
61
|
-
'h': [0b101, 0b101, 0b111, 0b101, 0b101],
|
|
62
|
-
'i': [0b111, 0b010, 0b010, 0b010, 0b111],
|
|
63
|
-
'j': [0b001, 0b001, 0b001, 0b101, 0b010],
|
|
64
|
-
'k': [0b101, 0b110, 0b100, 0b110, 0b101],
|
|
65
|
-
'l': [0b100, 0b100, 0b100, 0b100, 0b111],
|
|
66
|
-
'm': [0b101, 0b111, 0b111, 0b101, 0b101],
|
|
67
|
-
'n': [0b101, 0b111, 0b111, 0b111, 0b101],
|
|
68
|
-
'o': [0b010, 0b101, 0b101, 0b101, 0b010],
|
|
69
|
-
'p': [0b110, 0b101, 0b110, 0b100, 0b100],
|
|
70
|
-
'q': [0b010, 0b101, 0b101, 0b110, 0b011],
|
|
71
|
-
'r': [0b110, 0b101, 0b110, 0b101, 0b101],
|
|
72
|
-
's': [0b011, 0b100, 0b010, 0b001, 0b110],
|
|
73
|
-
't': [0b111, 0b010, 0b010, 0b010, 0b010],
|
|
74
|
-
'u': [0b101, 0b101, 0b101, 0b101, 0b011],
|
|
75
|
-
'v': [0b101, 0b101, 0b101, 0b101, 0b010],
|
|
76
|
-
'w': [0b101, 0b101, 0b111, 0b111, 0b101],
|
|
77
|
-
'x': [0b101, 0b101, 0b010, 0b101, 0b101],
|
|
78
|
-
'y': [0b101, 0b101, 0b010, 0b010, 0b010],
|
|
79
|
-
'z': [0b111, 0b001, 0b010, 0b100, 0b111],
|
|
80
|
-
'%': [0b101, 0b001, 0b010, 0b100, 0b101],
|
|
81
|
-
'.': [0b000, 0b000, 0b000, 0b000, 0b010],
|
|
82
|
-
',': [0b000, 0b000, 0b000, 0b010, 0b100],
|
|
83
|
-
':': [0b000, 0b010, 0b000, 0b010, 0b000],
|
|
84
|
-
'-': [0b000, 0b000, 0b111, 0b000, 0b000],
|
|
85
|
-
'_': [0b000, 0b000, 0b000, 0b000, 0b111],
|
|
86
|
-
'/': [0b001, 0b001, 0b010, 0b100, 0b100],
|
|
87
|
-
'$': [0b011, 0b110, 0b010, 0b011, 0b110],
|
|
88
|
-
' ': [0b000, 0b000, 0b000, 0b000, 0b000],
|
|
89
|
-
};
|
|
90
|
-
const KEY_DEFS = [
|
|
91
|
-
// Row 0: Mode, Session, Usage, Quick1, Quick2
|
|
92
|
-
{ id: 0, col: 0, row: 0, colSpan: 1, label: 'MODE', type: 'action' },
|
|
93
|
-
{ id: 1, col: 1, row: 0, colSpan: 1, label: 'SESSION', type: 'info' },
|
|
94
|
-
{ id: 2, col: 2, row: 0, colSpan: 1, label: 'USAGE', type: 'info' },
|
|
95
|
-
{ id: 3, col: 3, row: 0, colSpan: 1, label: 'QA 1', type: 'action' },
|
|
96
|
-
{ id: 4, col: 4, row: 0, colSpan: 1, label: 'QA 2', type: 'action' },
|
|
97
|
-
// Row 1: Quick3, Quick4, Model, 5h Rate, 7d Rate
|
|
98
|
-
{ id: 5, col: 0, row: 1, colSpan: 1, label: 'QA 3', type: 'action' },
|
|
99
|
-
{ id: 6, col: 1, row: 1, colSpan: 1, label: 'QA 4', type: 'action' },
|
|
100
|
-
{ id: 7, col: 2, row: 1, colSpan: 1, label: 'MODEL', type: 'info' },
|
|
101
|
-
{ id: 8, col: 3, row: 1, colSpan: 1, label: '5h', type: 'info' },
|
|
102
|
-
{ id: 9, col: 4, row: 1, colSpan: 1, label: '7d', type: 'info' },
|
|
103
|
-
// Row 2: Stop, Tokens, Cost, Info (merged 2-wide)
|
|
104
|
-
{ id: 10, col: 0, row: 2, colSpan: 1, label: 'STOP', type: 'action' },
|
|
105
|
-
{ id: 11, col: 1, row: 2, colSpan: 1, label: 'TOKENS', type: 'info' },
|
|
106
|
-
{ id: 12, col: 2, row: 2, colSpan: 1, label: 'COST', type: 'info' },
|
|
107
|
-
{ id: 13, col: 3, row: 2, colSpan: 2, label: 'INFO', type: 'info' },
|
|
108
|
-
];
|
|
109
|
-
/** Cached framebuffer */
|
|
110
|
-
let fbBuffer = null;
|
|
111
|
-
let lastRenderHash = '';
|
|
112
|
-
const tmpPath = join(tmpdir(), 'd200h_fb.raw');
|
|
113
|
-
function setPixel(fb, sx, sy, color) {
|
|
114
|
-
// Screen(sx,sy) → fb(sy, 959-sx)
|
|
115
|
-
const fx = sy;
|
|
116
|
-
const fy = 959 - sx;
|
|
117
|
-
if (fx < 0 || fx >= FBW || fy < 0 || fy >= FBH)
|
|
118
|
-
return;
|
|
119
|
-
const offset = (fy * FBW + fx) * 4;
|
|
120
|
-
fb[offset] = color[0]; // B
|
|
121
|
-
fb[offset + 1] = color[1]; // G
|
|
122
|
-
fb[offset + 2] = color[2]; // R
|
|
123
|
-
fb[offset + 3] = color[3]; // A
|
|
124
|
-
}
|
|
125
|
-
function fillRect(fb, x1, y1, x2, y2, color) {
|
|
126
|
-
for (let sy = Math.max(0, y1); sy < Math.min(SH, y2); sy++) {
|
|
127
|
-
for (let sx = Math.max(0, x1); sx < Math.min(SW, x2); sx++) {
|
|
128
|
-
setPixel(fb, sx, sy, color);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
function drawText(fb, x, y, text, scale, color) {
|
|
133
|
-
let cx = x;
|
|
134
|
-
for (const ch of text.toLowerCase()) {
|
|
135
|
-
const glyph = FONT_3X5[ch];
|
|
136
|
-
if (!glyph) {
|
|
137
|
-
cx += 4 * scale;
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
for (let dy = 0; dy < 5; dy++) {
|
|
141
|
-
for (let dx = 0; dx < 3; dx++) {
|
|
142
|
-
if (glyph[dy] & (1 << (2 - dx))) {
|
|
143
|
-
for (let ssy = 0; ssy < scale; ssy++) {
|
|
144
|
-
for (let ssx = 0; ssx < scale; ssx++) {
|
|
145
|
-
setPixel(fb, cx + dx * scale + ssx, y + dy * scale + ssy, color);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
cx += 4 * scale;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
function drawTextCentered(fb, cx, cy, text, scale, color) {
|
|
155
|
-
const textW = text.length * 4 * scale;
|
|
156
|
-
const textH = 5 * scale;
|
|
157
|
-
drawText(fb, cx - Math.floor(textW / 2), cy - Math.floor(textH / 2), text, scale, color);
|
|
158
|
-
}
|
|
159
|
-
function drawGauge(fb, x, y, w, h, percent, barColor) {
|
|
160
|
-
fillRect(fb, x, y, x + w, y + h, COLOR_BAR_BG);
|
|
161
|
-
const filled = Math.floor(w * Math.min(100, Math.max(0, percent)) / 100);
|
|
162
|
-
fillRect(fb, x, y, x + filled, y + h, barColor);
|
|
163
|
-
}
|
|
164
|
-
function parseState(evt) {
|
|
165
|
-
return {
|
|
166
|
-
state: evt?.state ?? 'DISCONNECTED',
|
|
167
|
-
projectName: evt?.projectName ?? '',
|
|
168
|
-
modelName: evt?.modelName ?? '',
|
|
169
|
-
agentType: evt?.agentType ?? 'claude-code',
|
|
170
|
-
mode: evt?.mode ?? 'default',
|
|
171
|
-
fiveHourPercent: typeof evt?.fiveHourPercent === 'number' ? evt.fiveHourPercent : undefined,
|
|
172
|
-
sevenDayPercent: typeof evt?.sevenDayPercent === 'number' ? evt.sevenDayPercent : undefined,
|
|
173
|
-
totalTokens: evt?.totalTokens ?? 0,
|
|
174
|
-
totalCost: evt?.totalCost ?? 0,
|
|
175
|
-
options: (evt?.options ?? []).map((o) => o?.label ?? o ?? ''),
|
|
176
|
-
currentTool: evt?.currentTool ?? '',
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
function stateColor(state) {
|
|
180
|
-
switch (state) {
|
|
181
|
-
case 'PROCESSING': return COLOR_PROCESSING;
|
|
182
|
-
case 'AWAITING_PERMISSION':
|
|
183
|
-
case 'AWAITING_INPUT':
|
|
184
|
-
case 'AWAITING_PROMPT': return COLOR_AWAITING;
|
|
185
|
-
case 'ERROR': return COLOR_ERROR;
|
|
186
|
-
default: return COLOR_IDLE;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
/** Render a single key to the framebuffer */
|
|
190
|
-
function renderKey(fb, key, state) {
|
|
191
|
-
const x1 = key.col * COL_W + GAP;
|
|
192
|
-
const y1 = key.row * ROW_H + GAP;
|
|
193
|
-
const x2 = (key.col + key.colSpan) * COL_W - GAP;
|
|
194
|
-
const y2 = (key.row + 1) * ROW_H - GAP;
|
|
195
|
-
const cx = Math.floor((x1 + x2) / 2);
|
|
196
|
-
const cy = Math.floor((y1 + y2) / 2);
|
|
197
|
-
switch (key.id) {
|
|
198
|
-
case 0: // MODE
|
|
199
|
-
fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
|
|
200
|
-
drawTextCentered(fb, cx, cy - 16, 'mode', 3, COLOR_DIM);
|
|
201
|
-
drawTextCentered(fb, cx, cy + 10, state.mode, 3, COLOR_TEXT);
|
|
202
|
-
break;
|
|
203
|
-
case 1: // SESSION
|
|
204
|
-
fillRect(fb, x1, y1, x2, y2, stateColor(state.state));
|
|
205
|
-
drawTextCentered(fb, cx, cy - 20, state.projectName.slice(0, 10), 3, COLOR_TEXT);
|
|
206
|
-
drawTextCentered(fb, cx, cy + 5, state.state.slice(0, 12).toLowerCase(), 2, COLOR_DIM);
|
|
207
|
-
break;
|
|
208
|
-
case 2: // USAGE
|
|
209
|
-
fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
|
|
210
|
-
drawTextCentered(fb, cx, cy - 16, 'usage', 3, COLOR_DIM);
|
|
211
|
-
break;
|
|
212
|
-
case 3:
|
|
213
|
-
case 4:
|
|
214
|
-
case 5:
|
|
215
|
-
case 6: { // Quick Actions
|
|
216
|
-
const qaIdx = key.id <= 4 ? key.id - 3 : key.id - 3;
|
|
217
|
-
const label = state.options[qaIdx] ?? '';
|
|
218
|
-
if (label) {
|
|
219
|
-
fillRect(fb, x1, y1, x2, y2, COLOR_ACCENT);
|
|
220
|
-
drawTextCentered(fb, cx, cy, label.slice(0, 10), 3, COLOR_TEXT);
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
|
|
224
|
-
drawTextCentered(fb, cx, cy, key.label, 2, COLOR_DIM);
|
|
225
|
-
}
|
|
226
|
-
break;
|
|
227
|
-
}
|
|
228
|
-
case 7: // MODEL
|
|
229
|
-
fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
|
|
230
|
-
drawTextCentered(fb, cx, cy - 12, 'model', 2, COLOR_DIM);
|
|
231
|
-
drawTextCentered(fb, cx, cy + 8, state.modelName.slice(0, 10), 3, COLOR_TEXT);
|
|
232
|
-
break;
|
|
233
|
-
case 8: // 5h Rate
|
|
234
|
-
fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
|
|
235
|
-
drawTextCentered(fb, cx, y1 + 20, '5h', 2, COLOR_DIM);
|
|
236
|
-
if (state.fiveHourPercent != null) {
|
|
237
|
-
drawGauge(fb, x1 + 10, cy - 4, x2 - x1 - 20, 12, state.fiveHourPercent, COLOR_BAR_5H);
|
|
238
|
-
drawTextCentered(fb, cx, y2 - 25, `${Math.round(state.fiveHourPercent)}%`, 3, COLOR_TEXT);
|
|
239
|
-
}
|
|
240
|
-
break;
|
|
241
|
-
case 9: // 7d Rate
|
|
242
|
-
fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
|
|
243
|
-
drawTextCentered(fb, cx, y1 + 20, '7d', 2, COLOR_DIM);
|
|
244
|
-
if (state.sevenDayPercent != null) {
|
|
245
|
-
drawGauge(fb, x1 + 10, cy - 4, x2 - x1 - 20, 12, state.sevenDayPercent, COLOR_BAR_7D);
|
|
246
|
-
drawTextCentered(fb, cx, y2 - 25, `${Math.round(state.sevenDayPercent)}%`, 3, COLOR_TEXT);
|
|
247
|
-
}
|
|
248
|
-
break;
|
|
249
|
-
case 10: // STOP
|
|
250
|
-
fillRect(fb, x1, y1, x2, y2, state.state === 'PROCESSING' ? COLOR_ERROR : COLOR_IDLE);
|
|
251
|
-
drawTextCentered(fb, cx, cy, 'stop', 3, state.state === 'PROCESSING' ? COLOR_TEXT : COLOR_DIM);
|
|
252
|
-
break;
|
|
253
|
-
case 11: // TOKENS
|
|
254
|
-
fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
|
|
255
|
-
drawTextCentered(fb, cx, cy - 12, 'tokens', 2, COLOR_DIM);
|
|
256
|
-
const tk = state.totalTokens > 1000 ? `${(state.totalTokens / 1000).toFixed(0)}k` : `${state.totalTokens}`;
|
|
257
|
-
drawTextCentered(fb, cx, cy + 10, tk, 3, COLOR_TEXT);
|
|
258
|
-
break;
|
|
259
|
-
case 12: // COST
|
|
260
|
-
fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
|
|
261
|
-
drawTextCentered(fb, cx, cy - 12, 'cost', 2, COLOR_DIM);
|
|
262
|
-
drawTextCentered(fb, cx, cy + 10, `${state.totalCost.toFixed(2)}`, 3, COLOR_GREEN);
|
|
263
|
-
break;
|
|
264
|
-
case 13: // INFO (merged)
|
|
265
|
-
fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
|
|
266
|
-
if (state.currentTool) {
|
|
267
|
-
drawTextCentered(fb, cx, cy - 12, 'tool', 2, COLOR_DIM);
|
|
268
|
-
drawTextCentered(fb, cx, cy + 10, state.currentTool.slice(0, 18), 2, COLOR_TEXT);
|
|
269
|
-
}
|
|
270
|
-
else {
|
|
271
|
-
drawTextCentered(fb, cx, cy - 12, state.agentType, 2, COLOR_DIM);
|
|
272
|
-
drawTextCentered(fb, cx, cy + 10, 'agentdeck', 3, COLOR_ACCENT);
|
|
273
|
-
}
|
|
274
|
-
break;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
/** Render full dashboard and return raw BGRA framebuffer */
|
|
278
|
-
export function renderDashboard(stateEvt) {
|
|
279
|
-
const fb = Buffer.alloc(FB_SIZE, 0);
|
|
280
|
-
const state = parseState(stateEvt);
|
|
281
|
-
// Fill background
|
|
282
|
-
for (let sy = 0; sy < SH; sy++) {
|
|
283
|
-
for (let sx = 0; sx < SW; sx++) {
|
|
284
|
-
setPixel(fb, sx, sy, COLOR_BG);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
// Render all 14 keys
|
|
288
|
-
for (const key of KEY_DEFS) {
|
|
289
|
-
renderKey(fb, key, state);
|
|
290
|
-
}
|
|
291
|
-
return fb;
|
|
292
|
-
}
|
|
293
|
-
/** Push framebuffer to D200H via ADB */
|
|
294
|
-
export function pushToDevice(fb) {
|
|
295
|
-
try {
|
|
296
|
-
writeFileSync(tmpPath, fb);
|
|
297
|
-
execSync(`adb -s ${D200H_SERIAL} push ${tmpPath} /tmp/agentdeck.raw`, {
|
|
298
|
-
stdio: 'pipe',
|
|
299
|
-
timeout: 5000,
|
|
300
|
-
});
|
|
301
|
-
execSync(`adb -s ${D200H_SERIAL} shell "cat /tmp/agentdeck.raw > /dev/fb0"`, {
|
|
302
|
-
stdio: 'pipe',
|
|
303
|
-
timeout: 3000,
|
|
304
|
-
});
|
|
305
|
-
return true;
|
|
306
|
-
}
|
|
307
|
-
catch (err) {
|
|
308
|
-
debug(TAG, `push failed: ${err}`);
|
|
309
|
-
return false;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
/** Render and push dashboard to D200H */
|
|
313
|
-
export function updateD200hDisplay(stateEvt) {
|
|
314
|
-
const hash = JSON.stringify(stateEvt?.state) + JSON.stringify(stateEvt?.fiveHourPercent);
|
|
315
|
-
if (hash === lastRenderHash)
|
|
316
|
-
return; // skip if unchanged
|
|
317
|
-
lastRenderHash = hash;
|
|
318
|
-
const fb = renderDashboard(stateEvt);
|
|
319
|
-
pushToDevice(fb);
|
|
320
|
-
}
|
|
321
|
-
//# sourceMappingURL=d200h-renderer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"d200h-renderer.js","sourceRoot":"","sources":["../../src/modules/d200h-renderer.ts"],"names":[],"mappings":"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E,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK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"}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TRMNL device module — keeps the BYOS frame cache fresh.
|
|
3
|
-
*
|
|
4
|
-
* TRMNL is a WiFi e-ink display that PULLS rendered images from a server on its
|
|
5
|
-
* own schedule (the BYOS /api/display contract), so unlike Pixoo/D200H this
|
|
6
|
-
* module never pushes to hardware. It only subscribes to AgentDeck state
|
|
7
|
-
* broadcasts and re-renders the cached 800×480 1-bit frame when the visual state
|
|
8
|
-
* changes; the daemon's HTTP routes (bridge/src/trmnl/byos-server.ts) serve that
|
|
9
|
-
* frame when a device polls.
|
|
10
|
-
*
|
|
11
|
-
* Rendering is gated on a device being registered (or `trmnl.enabled`) so a
|
|
12
|
-
* machine with no TRMNL panel does no extra rasterization. The gate is refreshed
|
|
13
|
-
* from settings on a short interval and immediately when a device enrolls.
|
|
14
|
-
*/
|
|
15
|
-
import type { DeviceModule, BridgeContext } from './types.js';
|
|
16
|
-
export declare class TrmnlModule implements DeviceModule {
|
|
17
|
-
readonly name = "trmnl";
|
|
18
|
-
private lastState;
|
|
19
|
-
private lastUsage;
|
|
20
|
-
private lastSessions;
|
|
21
|
-
private gateActive;
|
|
22
|
-
private gateTimer;
|
|
23
|
-
shouldActivate(config: 'auto' | boolean): Promise<boolean>;
|
|
24
|
-
start(ctx: BridgeContext): Promise<void>;
|
|
25
|
-
stop(): Promise<void>;
|
|
26
|
-
statusSnapshot(): Record<string, unknown>;
|
|
27
|
-
/** Re-read settings to decide whether rendering is worthwhile. */
|
|
28
|
-
private refreshGate;
|
|
29
|
-
private render;
|
|
30
|
-
/**
|
|
31
|
-
* Combine the latest state_update + usage_update + sessions into one render
|
|
32
|
-
* event. usage_update is spread last so its 5H/7D + reset fields win. No time
|
|
33
|
-
* component is added: the frame hash must change only on real visual change so
|
|
34
|
-
* a real TRMNL can skip the (battery + flaky-WiFi) re-download otherwise.
|
|
35
|
-
*/
|
|
36
|
-
private buildRenderState;
|
|
37
|
-
}
|
|
38
|
-
//# sourceMappingURL=trmnl-module.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"trmnl-module.d.ts","sourceRoot":"","sources":["../../src/modules/trmnl-module.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAgB9D,qBAAa,WAAY,YAAW,YAAY;IAC9C,QAAQ,CAAC,IAAI,WAAW;IAExB,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAA+C;IAE1D,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ1D,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBxC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAoBzC,kEAAkE;IAClE,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,MAAM;IAWd;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;CAYzB"}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { initTrmnlRenderer, isTrmnlResvgLoaded } from '../trmnl/image-renderer.js';
|
|
2
|
-
import { refreshTrmnlFrame, setTrmnlState, getTrmnlFrameKeys, getTrmnlActivity } from '../trmnl/frame-cache.js';
|
|
3
|
-
import { loadTrmnlConfig, effectiveRefreshRate } from '../trmnl/trmnl-settings.js';
|
|
4
|
-
import { getTelemetryHealth } from '../trmnl/trmnl-telemetry.js';
|
|
5
|
-
import { debug } from '../logger.js';
|
|
6
|
-
const TAG = 'trmnl';
|
|
7
|
-
const GATE_REFRESH_MS = 30_000;
|
|
8
|
-
function isControllableOrObserved(session) {
|
|
9
|
-
// TRMNL is a read-only dashboard — show every live session (controllable or
|
|
10
|
-
// observed), unlike D200H which filters to controllable for its buttons.
|
|
11
|
-
return !!session && session.alive !== false;
|
|
12
|
-
}
|
|
13
|
-
export class TrmnlModule {
|
|
14
|
-
name = 'trmnl';
|
|
15
|
-
lastState = null;
|
|
16
|
-
lastUsage = null;
|
|
17
|
-
lastSessions = [];
|
|
18
|
-
gateActive = false;
|
|
19
|
-
gateTimer = null;
|
|
20
|
-
async shouldActivate(config) {
|
|
21
|
-
if (config === false)
|
|
22
|
-
return false;
|
|
23
|
-
if (config === true)
|
|
24
|
-
return true;
|
|
25
|
-
// auto: active if a device is registered or the user forced it on.
|
|
26
|
-
const cfg = loadTrmnlConfig();
|
|
27
|
-
return cfg.enabled || cfg.devices.length > 0;
|
|
28
|
-
}
|
|
29
|
-
async start(ctx) {
|
|
30
|
-
await initTrmnlRenderer();
|
|
31
|
-
this.refreshGate();
|
|
32
|
-
this.gateTimer = setInterval(() => this.refreshGate(), GATE_REFRESH_MS);
|
|
33
|
-
ctx.wsServer.onBroadcast((evt) => {
|
|
34
|
-
if (evt?.type === 'state_update') {
|
|
35
|
-
this.lastState = evt;
|
|
36
|
-
this.render();
|
|
37
|
-
}
|
|
38
|
-
else if (evt?.type === 'usage_update') {
|
|
39
|
-
// state_update never carries usage; the 5H/7D gauges + token/cost footer
|
|
40
|
-
// only exist on usage_update (same as Pixoo/ESP32). Without this the panel
|
|
41
|
-
// renders a confident 0% forever.
|
|
42
|
-
this.lastUsage = evt;
|
|
43
|
-
this.render();
|
|
44
|
-
}
|
|
45
|
-
else if (evt?.type === 'sessions_list') {
|
|
46
|
-
this.lastSessions = (evt.sessions ?? []).filter(isControllableOrObserved);
|
|
47
|
-
this.render();
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
debug(TAG, `started (resvg=${isTrmnlResvgLoaded()}, gate=${this.gateActive})`);
|
|
51
|
-
}
|
|
52
|
-
async stop() {
|
|
53
|
-
if (this.gateTimer) {
|
|
54
|
-
clearInterval(this.gateTimer);
|
|
55
|
-
this.gateTimer = null;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
statusSnapshot() {
|
|
59
|
-
const cfg = loadTrmnlConfig();
|
|
60
|
-
const activeResolutions = getTrmnlFrameKeys();
|
|
61
|
-
const activity = getTrmnlActivity();
|
|
62
|
-
const currentRefreshRate = effectiveRefreshRate(cfg, activity);
|
|
63
|
-
return {
|
|
64
|
-
resvgLoaded: isTrmnlResvgLoaded(),
|
|
65
|
-
gateActive: this.gateActive,
|
|
66
|
-
enabled: cfg.enabled,
|
|
67
|
-
deviceCount: cfg.devices.length,
|
|
68
|
-
refreshRate: cfg.refreshRate,
|
|
69
|
-
refreshActive: cfg.refreshActive,
|
|
70
|
-
currentRefreshRate,
|
|
71
|
-
activeResolutions,
|
|
72
|
-
frameCount: activeResolutions.length,
|
|
73
|
-
// Health uses the current adaptive cadence so "stale" tracks real expectations.
|
|
74
|
-
telemetry: getTelemetryHealth(currentRefreshRate),
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
/** Re-read settings to decide whether rendering is worthwhile. */
|
|
78
|
-
refreshGate() {
|
|
79
|
-
const cfg = loadTrmnlConfig();
|
|
80
|
-
this.gateActive = cfg.enabled || cfg.devices.length > 0;
|
|
81
|
-
}
|
|
82
|
-
render() {
|
|
83
|
-
const evt = this.buildRenderState();
|
|
84
|
-
if (!this.gateActive) {
|
|
85
|
-
// No device yet — remember the state so the frame is correct the instant a
|
|
86
|
-
// device enrolls (byos-server forces a render then), but skip rasterizing.
|
|
87
|
-
setTrmnlState(evt);
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
refreshTrmnlFrame(evt);
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Combine the latest state_update + usage_update + sessions into one render
|
|
94
|
-
* event. usage_update is spread last so its 5H/7D + reset fields win. No time
|
|
95
|
-
* component is added: the frame hash must change only on real visual change so
|
|
96
|
-
* a real TRMNL can skip the (battery + flaky-WiFi) re-download otherwise.
|
|
97
|
-
*/
|
|
98
|
-
buildRenderState() {
|
|
99
|
-
const u = this.lastUsage ?? {};
|
|
100
|
-
// Usage is "known" only when the hub actually has subscription quota (the
|
|
101
|
-
// gauges are meaningful); otherwise the layout renders "—" instead of 0%.
|
|
102
|
-
const usageKnown = u.fiveHourPercent != null || u.sevenDayPercent != null;
|
|
103
|
-
return {
|
|
104
|
-
...(this.lastState ?? {}),
|
|
105
|
-
...u,
|
|
106
|
-
usageKnown,
|
|
107
|
-
allSessions: this.lastSessions,
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
//# sourceMappingURL=trmnl-module.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"trmnl-module.js","sourceRoot":"","sources":["../../src/modules/trmnl-module.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TRMNL BYOS (Bring Your Own Server) HTTP handlers, mounted on the daemon hub.
|
|
3
|
-
*
|
|
4
|
-
* Implements the minimal TRMNL device contract so a stock-firmware panel pointed
|
|
5
|
-
* at `http://<daemon-host>:9120` renders the AgentDeck dashboard:
|
|
6
|
-
*
|
|
7
|
-
* GET /api/setup ID:<mac> → { api_key, friendly_id, image_url }
|
|
8
|
-
* GET /api/display ID:<mac> Access-Token:<key> → { image_url, filename, refresh_rate, ... }
|
|
9
|
-
* GET /trmnl/image/<W>x<H>-<hash>.png → 1-bit PNG frame (per resolution)
|
|
10
|
-
* POST /api/log ID:<mac> → 204 (device logs, debug only)
|
|
11
|
-
*
|
|
12
|
-
* The device authenticates only by MAC (ID header); the api_key issued at setup
|
|
13
|
-
* is a soft gate on /api/display. This is LAN-local hardware, so no token is
|
|
14
|
-
* required to fetch the image itself. Any panel auto-enrolls regardless of MAC,
|
|
15
|
-
* and the dashboard is rendered at the device-reported Width/Height so different
|
|
16
|
-
* BYOS panels render correctly. The device's FW-Version/RSSI/Battery/etc. headers
|
|
17
|
-
* are captured as runtime telemetry. See docs: https://docs.trmnl.com/go/diy/byos
|
|
18
|
-
*/
|
|
19
|
-
import type { IncomingMessage, ServerResponse } from 'http';
|
|
20
|
-
/** Test helper — clear weak-RSSI transition tracking. */
|
|
21
|
-
export declare function _resetWeakRssiTracking(): void;
|
|
22
|
-
/** GET /api/setup — enroll the device (by MAC) and hand back an api_key. */
|
|
23
|
-
export declare function handleTrmnlSetup(req: IncomingMessage, res: ServerResponse): void;
|
|
24
|
-
/**
|
|
25
|
-
* GET /api/display — return the next image + polling cadence.
|
|
26
|
-
*
|
|
27
|
-
* NOTE: we always reply with HTTP 200; the BYOS `status` field carries the real
|
|
28
|
-
* signal (0 = show image, 202 = call /api/setup). Stock firmware treats a non-200
|
|
29
|
-
* HTTP status as an error and goes back to sleep without rendering, so HTTP 200 is
|
|
30
|
-
* required even in the "needs setup" case.
|
|
31
|
-
*/
|
|
32
|
-
export declare function handleTrmnlDisplay(req: IncomingMessage, res: ServerResponse): void;
|
|
33
|
-
/** GET /trmnl/image/<W>x<H>-<hash>.png — serve the 1-bit PNG for that resolution. */
|
|
34
|
-
export declare function handleTrmnlImage(req: IncomingMessage, res: ServerResponse): void;
|
|
35
|
-
/** POST /api/log — the panel's own error report; always logged (rate-limited). */
|
|
36
|
-
export declare function handleTrmnlLog(req: IncomingMessage, res: ServerResponse): void;
|
|
37
|
-
/** True for any path this module owns, so the daemon router can delegate. */
|
|
38
|
-
export declare function isTrmnlImagePath(pathname: string): boolean;
|
|
39
|
-
//# sourceMappingURL=byos-server.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"byos-server.d.ts","sourceRoot":"","sources":["../../src/trmnl/byos-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AA+C5D,yDAAyD;AACzD,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAkGD,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,CA8BhF;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,CA4ElF;AAED,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,CAoBhF;AA0BD,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,CA0B9E;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE1D"}
|