index ↓
system
client.system Device identity, health, logs, and power control for a webapp. versionRequest and
diagnosticsGet return the daemon version and a health snapshot, logsTail returns a batch of
log entries, and logsSubscribe streams them as onLogEntry. onOtaProgress and
onOtaFinished track a software update.
requests
you ask, the daemon answers. await the tagged result and check .ok
versionRequest(): Promise<TypedRequestResult<BridgeThingMeta, never>>
push form: onVersion (subscribe instead of awaiting)
Returns the daemon's version and identity as BridgeThingMeta.
const res = await client.system.versionRequest();
if (res.ok) {
console.log(res.response.bridgethingVersion);
} type Result =
| { ok: true; response: BridgeThingMeta }
| { ok: false; kind: 'domain'; error: never }
| { ok: false; kind: 'protocol'; error: WireError }; diagnosticsGet(): Promise<TypedRequestResult<DiagnosticsReply, never>>
push form: onDiagnosticsReply (subscribe instead of awaiting)
Returns disk and memory use, uptime, SoC temperature, load average, and versions.
const res = await client.system.diagnosticsGet();
if (res.ok) {
console.log(res.response.diagnostics);
} type Result =
| { ok: true; response: DiagnosticsReply }
| { ok: false; kind: 'domain'; error: never }
| { ok: false; kind: 'protocol'; error: WireError }; logsTail(LogsTail): Promise<TypedRequestResult<LogsTailReply, never>>
push form: onLogsTailReply (subscribe instead of awaiting)
const res = await client.system.logsTail({ source: 'daemon', levels: 'trace', maxLines: 0 });
if (res.ok) {
console.log(res.response.entries);
} type Result =
| { ok: true; response: LogsTailReply }
| { ok: false; kind: 'domain'; error: never }
| { ok: false; kind: 'protocol'; error: WireError }; logsSubscribe(LogsSubscribe): Promise<TypedRequestResult<LogsSubscribeReply, never>>
push form: onLogsSubscribeReply (subscribe instead of awaiting)
const res = await client.system.logsSubscribe({ source: 'daemon', levels: 'trace' });
if (res.ok) {
console.log(res.response.token);
} type Result =
| { ok: true; response: LogsSubscribeReply }
| { ok: false; kind: 'domain'; error: never }
| { ok: false; kind: 'protocol'; error: WireError }; deviceGetNickname(): Promise<TypedRequestResult<DeviceNicknameReply, never>>
push form: onDeviceNickname (subscribe instead of awaiting)
const res = await client.system.deviceGetNickname();
if (res.ok) {
console.log(res.response.nickname);
} type Result =
| { ok: true; response: DeviceNicknameReply }
| { ok: false; kind: 'domain'; error: never }
| { ok: false; kind: 'protocol'; error: WireError }; commands
fire-and-forget. the promise resolves once the daemon has taken the message
logsUnsubscribe(LogsUnsubscribe): Promise<void>
await client.system.logsUnsubscribe({ token: '...' }); reboot(): Promise<void>
await client.system.reboot(); powerOff(): Promise<void>
await client.system.powerOff(); factoryReset(): Promise<void>
await client.system.factoryReset(); events
the daemon pushes these unprompted. subscribing returns an unsubscribe function
onLogEntry(handler: (LogEntry) => void): () => void
const off = client.system.onLogEntry((entry) => {
console.log(entry.tsUnixS);
});
// call off() to unsubscribe onOtaProgress(handler: (OtaProgress) => void): () => void
const off = client.system.onOtaProgress((otaProgress) => {
console.log(otaProgress.phase);
});
// call off() to unsubscribe onOtaError(handler: (OtaError) => void): () => void
const off = client.system.onOtaError((otaError) => {
console.log(otaError.code);
});
// call off() to unsubscribe onOtaFinished(handler: (OtaFinished) => void): () => void
const off = client.system.onOtaFinished((otaFinished) => {
console.log(otaFinished.kind);
});
// call off() to unsubscribe onDeviceNicknameChanged(handler: (DeviceNicknameReply) => void): () => void
const off = client.system.onDeviceNicknameChanged((reply) => {
console.log(reply.nickname);
});
// call off() to unsubscribe types
shapes referenced above, as the sdk types them
type LogEntry = {
tsUnixS: number;
level: LogLevel;
target: string;
message: string;
}; type OtaProgress = {
phase: OtaPhase;
percent: number; // 0 to 100, within the current phase.
step: number;
nsteps: number;
dwlPercent: number;
dwlBytes: number;
etaMs?: number;
}; type OtaError = {
code: OtaErrorCode;
msg: string;
updateId?: string; // A resume of the same artifact reuses the id.
replayed: boolean; // The device is redelivering a failure the phone missed.
}; type OtaFinished = {
kind: OtaKind;
updateId: string;
}; type DeviceNicknameReply = {
nickname?: string;
}; Identity and build information for the device.
type BridgeThingMeta = {
bridgethingVersion: string;
libbridgethingVersion: string;
appName: string;
nickname?: string;
appVersion: string;
daemonSha256?: string;
wakewordModelVersion?: string; // Null when no wake word model is loaded, or the loaded model carries no version.
osName: string;
osVersion: string;
osDescription: string;
btMac: string;
serialNumber: string;
fccId: string;
icId: string;
modelName: string;
channel: string;
imageVariant: string;
imageVersion: string;
imageBuildId: string;
imageBuildDate: string;
imageDistro: string;
imageMachine: string;
discord: string;
credits: string;
}; type DiagnosticsReply = {
diagnostics: Diagnostics;
}; type LogsTail = {
source: LogSource;
levels: LogLevel[];
filter?: string;
maxLines: number;
}; type LogsTailReply = {
entries: LogEntry[];
}; type LogsSubscribe = {
source: LogSource;
levels: LogLevel[];
filter?: string;
}; type LogsSubscribeReply = {
token: string;
}; type LogsUnsubscribe = {
token: string;
}; type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error'; Each kind emits the phases that apply to it.
type OtaPhase =
| 'streaming'
| 'verifying'
| 'writing'
| 'confirming'
| 'reboot'; type OtaErrorCode =
| 'unknownUpdate' // The update id does not match an update the device has begun.
| 'offsetMismatch' // A fragment arrived at an offset the device was not expecting.
| 'hashMismatch' // The transferred bytes do not match the declared sha256.
| 'sizeMismatch' // The transferred bytes do not match the declared size.
| 'cancelled'
| 'writeFailed' // The device rejected the payload while writing it.
| 'confirmFailed' // The update wrote successfully. The device could not mark the new slot bootable.
| 'internal' // An unexpected failure.; What an update installs.
type OtaKind =
| 'image'
| 'daemon'
| 'builtinWebapp'
| 'installedWebapp'
| 'wakewordModel'; type Diagnostics = {
diskUsedBytes: number;
diskFreeBytes: number;
memUsedBytes: number;
memAvailBytes: number;
uptimeS: number;
socTempC?: number;
loadAvg: [f32 ; 3];
daemonVersion: string;
kernelVersion: string;
bootId: string;
}; type LogSource = 'daemon' | 'system' | 'all';