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);
}

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);
}

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);
}

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);
}

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);
}

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';