tassello 0.7.0 → 0.9.0
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/CHANGELOG.md +24 -0
- package/README.md +50 -3
- package/dist/server/message_format.d.ts +1 -0
- package/dist/server/message_format.js +21 -0
- package/dist/server/server.js +4 -0
- package/dist/server/session.d.ts +2 -0
- package/dist/server/session.js +8 -0
- package/dist/server/system.d.ts +40 -0
- package/dist/server/system.js +606 -0
- package/dist/server/system_format.d.ts +51 -0
- package/dist/server/system_format.js +264 -0
- package/dist/server/topic_monitor.d.ts +3 -1
- package/dist/server/topic_monitor.js +51 -6
- package/dist/shared/monitor.d.ts +6 -0
- package/dist/shared/monitor.js +4 -0
- package/dist/shared/protocol.d.ts +23 -3
- package/dist/shared/system.d.ts +113 -0
- package/dist/shared/system.js +45 -0
- package/dist/types/client/connection.d.ts +6 -4
- package/dist/types/client/icons.d.ts +3 -0
- package/dist/types/client/sdk/index.d.ts +3 -2
- package/dist/types/client/widgets/types.d.ts +1 -0
- package/dist/types/shared/monitor.d.ts +6 -0
- package/dist/types/shared/protocol.d.ts +23 -3
- package/dist/types/shared/system.d.ts +113 -0
- package/dist/www/assets/Joystick.js +1 -1
- package/dist/www/assets/RobotModelView.js +2 -2
- package/dist/www/assets/TerminalView.js +2 -2
- package/dist/www/assets/dialogs.js +1 -1
- package/dist/www/assets/icons.js +1 -1
- package/dist/www/assets/index.css +1 -1
- package/dist/www/assets/index.js +53 -47
- package/dist/www/assets/shared/tassello-sdk.js +1 -1
- package/docs/plugins.md +3 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,30 @@ change the plugin API (`tassello/sdk`, `tassello/server`, `tassello/vite`), as n
|
|
|
5
5
|
|
|
6
6
|
## Unreleased
|
|
7
7
|
|
|
8
|
+
- Plot widget: numbers of any topic over time, as rqt_plot and PlotJuggler plot them
|
|
9
|
+
(`/odom.twist.twist.linear.x`, a battery's voltage, joints' efforts), up to 8 series on a
|
|
10
|
+
chart, from every message. Live over the latest *time shown*; paused, zoomed (drag across it,
|
|
11
|
+
the wheel, a pinch) and scrolled through time (Shift+wheel, a swipe, the arrow keys); the value
|
|
12
|
+
axis fitted to what is shown or fixed; the values at the pointer; series hidden from the
|
|
13
|
+
legend. What is shown exported as CSV, a row a message. The series are picked in the widget,
|
|
14
|
+
from the topics of the graph and the numeric fields of their latest message (a `JointState`'s
|
|
15
|
+
named by joint), and saved with the panel, or listed in its properties.
|
|
16
|
+
- The topic monitor (`topic.monitor`) samples: the numbers of every message at some fields, sent
|
|
17
|
+
ten times a second (`TopicSamples`). Plugins: `subscribeTopicMonitor`'s `samples`; its `stats`
|
|
18
|
+
and `echo` handlers are optional.
|
|
19
|
+
- Plugins: widgets get `updateConfig`, which changes their properties and saves the panel, as the
|
|
20
|
+
side panel does.
|
|
21
|
+
- System Monitor widget: the robot's computer, every second. The CPU's load, of each core (those
|
|
22
|
+
offline too), their frequencies and the load average; the memory, its cache and the swap; the
|
|
23
|
+
temperatures of the thermal zones and hwmon chips, by chip with their hottest, against their
|
|
24
|
+
own limits; the fans; a Raspberry Pi's throttling (under-voltage, frequency capped, throttled,
|
|
25
|
+
soft temperature limit, now and since boot); the GPUs: a Jetson's (devfreq), NVIDIA's
|
|
26
|
+
(`nvidia-smi`), AMD's (amdgpu); the power rails: a Jetson's INA3221 (L4T 32's too), hwmon's
|
|
27
|
+
power sensors, Intel's RAPL when readable; the disks' traffic and busy time, and the file
|
|
28
|
+
systems' space; the networks' traffic, of the device's own interfaces or those chosen. Charts
|
|
29
|
+
of the last 5 minutes, kept by the server, with the values at the pointer (or the arrow keys).
|
|
30
|
+
The board, its OS, uptime, and a Jetson's L4T release and power mode.
|
|
31
|
+
- Plugins: `connection.subscribeSystem`, and the types of `src/shared/system.ts`.
|
|
8
32
|
- Rosbags widget: the robot's rosbags, as `ros2 bag` makes and reads them. A folder's bags, the
|
|
9
33
|
newest first, with their time span, size, storage and compression, and each topic's type,
|
|
10
34
|
count and rate, from their `metadata.yaml` (Humble's and Jazzy's), else from their files (a
|
package/README.md
CHANGED
|
@@ -12,9 +12,11 @@ and plugins add more.
|
|
|
12
12
|
- **Built in**: teleop pads, a Nav2 map with goals, the robot's URDF in 3D, an arm jogger, cameras,
|
|
13
13
|
images, command buttons, a systemd application manager, a behavior tree inspector and
|
|
14
14
|
editor, the ROS log of every node, the robot's diagnostics, its topics, services and actions
|
|
15
|
-
as the `ros2` command line shows them,
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
as the `ros2` command line shows them, plots of their numbers over time, its nodes'
|
|
16
|
+
parameters, its rosbags (recorded, listed,
|
|
17
|
+
downloaded and played back), a file manager, a terminal, its networks (Wi-Fi
|
|
18
|
+
joined, connections switched, the robot as an access point), and its computer: CPU, memory,
|
|
19
|
+
temperatures, a Raspberry Pi's throttling, a Jetson's GPU and power, disks and networks.
|
|
18
20
|
- **Plugins**: widgets of your own, with server-side code if they need it, as npm or ROS packages.
|
|
19
21
|
- **One process**: a ROS 2 node in Node.js. Nothing to install on the robot but Node.js.
|
|
20
22
|
|
|
@@ -132,10 +134,12 @@ after the others on the devices already arranged.
|
|
|
132
134
|
| **Logs** | The ROS log (`/rosout`), as rqt_console and swri_console show it: every node's messages coloured by level, the nodes running and those that logged with their counts, filtered by node, by level and by text (terms or a regular expression, to show or to hide). Pause, follow the newest, clear, download, and a message's details: where it was logged |
|
|
133
135
|
| **Diagnostics** | The robot's diagnostics (`/diagnostics`, or the aggregator's `/diagnostics_agg`), as rqt_robot_monitor shows them: each status's level, the groups with the worst under them, those with problems unfolded. As a tree, as a list (the worst first) or as the latest changes of level, filtered by level and by text; a widget can be for some statuses only. A status's details: its message, hardware ID, values and latest changes. Pause, download, and forget the statuses no longer published |
|
|
134
136
|
| **ROS Monitor** | The ROS graph, as the `ros2` command line shows it, on three sheets: its topics, services and actions, filtered by name or type, the hidden ones on demand. A topic's messages, their rate, bandwidth and delay, its publishers and subscriptions with their QoS and those that cannot talk, a message to publish once or at a rate (`ros2 topic echo`, `hz`, `bw`, `delay`, `info -v`, `pub`); a service to call, once or at a rate (`ros2 service call`, `info`, `echo`); every goal of an action, whoever sent it, with its feedback, and a goal to send or cancel (`ros2 action send_goal`, `info`); their types' definitions (`ros2 interface show`) |
|
|
137
|
+
| **Plot** | Numbers of any topic over time, as rqt_plot and PlotJuggler plot them: `/odom.twist.twist.linear.x`, a battery's voltage, joints' efforts (named by their joints), up to 8 series on a chart, from every message. Paused, zoomed and scrolled through time, each series shown or hidden; what is shown exported as CSV. Its series are picked in the widget, from the topics of the graph and the fields of their messages, or listed in its properties |
|
|
135
138
|
| **Parameters** | Nodes' parameters, as rqt_reconfigure and `ros2 param` show them: the nodes of the graph, and the parameters of the one chosen grouped by their prefixes, each edited in place (a switch, a slider within its range, a field), live as they change wherever they are set. Their descriptions, ranges and constraints (`ros2 param describe`); new ones set and undeclared ones deleted (`set`, `delete`); all of them dumped as YAML, downloaded or saved on the robot (`dump`), and loaded from a YAML file of the robot or of the page's device (`load`) |
|
|
136
139
|
| **Rosbags** | The robot's rosbags, as `ros2 bag` makes and reads them: those of a folder, the newest first, with when, how long and how big, their storage and compression, each topic's type, count and rate (`ros2 bag info`); downloaded, deleted, or played on the robot's topics (`ros2 bag play`: paused, sought, sped up, looped, some topics only). New ones recorded (`ros2 bag record`): topics chosen from the graph, all of them, or matching an expression, with rosbag2's options: the storage (MCAP, SQLite) and its preset, a new file by size or duration, compression of each file or message. Every page sees the recordings and the playback, the behavior tree inspectors' too |
|
|
137
140
|
| **File Manager** | The robot's files: folders unfolded in place, places (home, the ROS workspaces, bookmarks) and the disks' free space, an entry's details and permissions, what takes a folder's space. Make, rename, cut, copy, paste, drag onto folders, delete, download (folders as `.tar.gz`) and upload (drop files and folders onto it). Text files edited in tabs as gedit does: highlighting, search and replace, undo; images and PGM maps shown |
|
|
138
141
|
| **Terminal** | A shell on the robot, or a command (`htop`, `tmux attach`), in a full terminal: colours, full screen programs, the mouse. It outlives the page: reloaded, reconnected or shown again, it is as it was. On touch screens, the keys phones lack, as Termux has them: Esc, Tab, Ctrl, Alt, Home, End, the arrows, Page Up and Down, and while typing the terminal fills the screen above the on-screen keyboard |
|
|
142
|
+
| **System Monitor** | The robot's computer, as top, sensors and a Jetson's jtop show it: the CPU's load, of each core, and their frequencies; the memory and swap; the temperatures by chip, and the fans; a Raspberry Pi's throttling (under-voltage, capped frequency, now and since boot); the GPUs (a Jetson's, NVIDIA's, AMD's) and the power rails (a Jetson's); the disks' traffic and space; the networks' traffic. With charts of the last 5 minutes |
|
|
139
143
|
| **Networking** | The robot's networks, through NetworkManager, as a phone's settings show them: the Wi-Fi networks in range, joined with their password; the connections saved, switched between, edited (their addresses by DHCP or static), forgotten; the robot as an access point, its network shared by a QR code; the interfaces, their state and addresses. Asks before a change that would cut the page off from the robot |
|
|
140
144
|
|
|
141
145
|
Their properties (topics, frames, speeds, colours, ...) are edited in the side panel of edit mode.
|
|
@@ -306,6 +310,26 @@ Notes on some of them:
|
|
|
306
310
|
|
|
307
311
|
Messages, requests and goals are made from rclnodejs's code of their types, which Tassello
|
|
308
312
|
makes when it starts for the workspaces sourced (see Install).
|
|
313
|
+
- **Plot** draws up to 8 series on one value axis: a topic, a dot and its field
|
|
314
|
+
(`/odom.twist.twist.linear.x`, `/joint_states.effort[2]`, list items by their index), then a
|
|
315
|
+
label if any, one a line in its *series* property. *Series…* picks them in the widget, in view
|
|
316
|
+
mode, and saves them with the panel: a topic of the graph, then fields among those of its
|
|
317
|
+
latest message that are numbers, with their values (a `JointState`'s by joint name), or a field
|
|
318
|
+
typed. Numbers, booleans (0 or 1) and times (in seconds, a header's stamp) are plotted; NaN and
|
|
319
|
+
infinities break the line, as does a topic that stopped. The server reads every message of the
|
|
320
|
+
topics plotted, not 10 a second, and sends the numbers of the fields asked for ten times a
|
|
321
|
+
second; each sample is on the server's clock, when its message came. The page keeps the
|
|
322
|
+
latest 10 minutes of each series (200,000 samples at most, 200 s of a 1 kHz topic), from when
|
|
323
|
+
the widget opened.
|
|
324
|
+
|
|
325
|
+
Live, it shows the latest *time shown* (30 s), the value axis fitted to what is shown or
|
|
326
|
+
*fixed*. Drag across it to zoom in on that span, which pauses it; the wheel zooms around the
|
|
327
|
+
pointer (live, a shorter or longer span to now), Shift+wheel or a sideways swipe scrolls
|
|
328
|
+
through time, two fingers pinch; *Live* or a double click goes on. Space pauses, the arrow keys
|
|
329
|
+
scroll, `+` and `-` zoom, Escape goes back live. The pointer shows each series' value at its
|
|
330
|
+
time, the legend the values at the right edge; clicking a series in the legend hides it. The
|
|
331
|
+
download button exports what is shown as CSV: the time (s since the epoch), then a column a
|
|
332
|
+
series, a row a message (those of a topic's series on the same rows).
|
|
309
333
|
- **Parameters** lists the nodes of the graph (but the hidden ones, as `ros2 node list` does), or
|
|
310
334
|
shows one node only, its *node* (a panel to tune `/controller_server`). A node's parameters are
|
|
311
335
|
read through its parameter services (`rcl_interfaces`), grouped by the prefixes of their names
|
|
@@ -466,6 +490,21 @@ Notes on some of them:
|
|
|
466
490
|
Without it, the widget says the networks cannot be changed. *Share…* reads the passwords with
|
|
467
491
|
`nmcli --show-secrets`, which needs the same right; those a desktop's keyring keeps cannot be
|
|
468
492
|
read.
|
|
493
|
+
- **System Monitor** reads `/proc` and `/sys` every second, for every page at once, while one
|
|
494
|
+
shows it, and keeps the last 5 minutes for the charts (a page opened later has them at once).
|
|
495
|
+
The temperatures are the kernel's thermal zones and its hwmon chips' sensors (the chips that
|
|
496
|
+
are a thermal zone again, once), grouped by chip with the hottest of each; a sensor is hot from
|
|
497
|
+
its own limits (else 80 °C), and critical at its own critical (else 95 °C). A **Raspberry Pi**'s
|
|
498
|
+
throttling is its firmware's (`get_throttled` in `/sys`, else `vcgencmd get_throttled`): under-
|
|
499
|
+
voltage, frequency capped, throttled, soft temperature limit, now and since boot. A **Jetson**'s
|
|
500
|
+
GPU is devfreq's (its load and clock), its power the INA3221's rails (`VDD_IN` the whole
|
|
501
|
+
board's), its L4T release and power mode (`nvpmodel -q`) are shown with the board. NVIDIA's
|
|
502
|
+
GPUs are read with `nvidia-smi` every 2 s, AMD's from amdgpu's files; an Intel CPU's package
|
|
503
|
+
power from RAPL, if its counters are readable (root's only, since Linux 5.10). Cores taken
|
|
504
|
+
offline (a Jetson's power modes) show as such. The disks are the whole ones (not partitions,
|
|
505
|
+
loop devices, device mapper or RAID), their space the File Manager's; the networks are the
|
|
506
|
+
device's own interfaces (not docker's bridges, VPN clients' tunnels: their traffic is the
|
|
507
|
+
devices' too), or those of its *interfaces* (`wlan0, tun*`). Each section can be hidden.
|
|
469
508
|
|
|
470
509
|
## Plugins
|
|
471
510
|
|
|
@@ -517,6 +556,7 @@ own pages only too: those whose origin is the host they reached (the `Host` head
|
|
|
517
556
|
├─ python3: the terminals' pseudo-terminals
|
|
518
557
|
├─ nmcli: the networks (NetworkManager)
|
|
519
558
|
├─ ros2 bag: rosbags recorded and played
|
|
559
|
+
├─ /proc, /sys, nvidia-smi: the system monitor
|
|
520
560
|
└─ the plugins' server sides
|
|
521
561
|
```
|
|
522
562
|
|
|
@@ -554,6 +594,13 @@ Safety and bandwidth are the server's concern:
|
|
|
554
594
|
one recording per folder, for every page (the behavior tree inspectors' among them), one
|
|
555
595
|
playback. A folder of bags is read once for every page showing it, every 2 s, a bag's metadata
|
|
556
596
|
again only when its files change; the recordings' sizes every second.
|
|
597
|
+
- A topic plotted is followed once for every page (the ROS Monitor's subscription, with its
|
|
598
|
+
publishers' QoS): its messages are deserialized only while a page plots it, and each page gets
|
|
599
|
+
the numbers of its own fields, ten batches a second: for a 200 Hz topic, about 3 KB a second
|
|
600
|
+
for when its messages came, and 4 KB for each field.
|
|
601
|
+
- The system monitor's sensors are read once for every page, every second while one watches and
|
|
602
|
+
for 30 s after the last leaves; they are looked for again every 30 s (USB ones come and go).
|
|
603
|
+
Each page gets a sample a second, about 4 KB.
|
|
557
604
|
- The File Manager's folders are read again every 3 s, and answered "unchanged" while they are;
|
|
558
605
|
the largest are listed in part (5,000 entries), and only the rows in sight are drawn. Uploads
|
|
559
606
|
and downloads are streamed, folders archived by `tar` as they are sent; saves replace files at
|
|
@@ -21,4 +21,5 @@ export interface RosTime {
|
|
|
21
21
|
}
|
|
22
22
|
export declare function toRosMessage(value: unknown, type: string, schemas: Record<string, MessageSchema>, now: () => RosTime, path?: string): Record<string, unknown>;
|
|
23
23
|
export declare function fieldAt(message: unknown, path: string): unknown;
|
|
24
|
+
export declare function sampleValue(value: unknown): number | null;
|
|
24
25
|
export declare function echoJson(value: unknown, limit: number): unknown;
|
|
@@ -307,6 +307,27 @@ export function fieldAt(message, path) {
|
|
|
307
307
|
}
|
|
308
308
|
return value;
|
|
309
309
|
}
|
|
310
|
+
// A field's value as a plot takes it: numbers, 64 bit integers, booleans (0
|
|
311
|
+
// or 1), times and durations (in seconds); null for anything else, and for
|
|
312
|
+
// NaN and infinities
|
|
313
|
+
export function sampleValue(value) {
|
|
314
|
+
if (typeof value === 'number') {
|
|
315
|
+
return Number.isFinite(value) ? value : null;
|
|
316
|
+
}
|
|
317
|
+
if (typeof value === 'bigint') {
|
|
318
|
+
return Number(value);
|
|
319
|
+
}
|
|
320
|
+
if (typeof value === 'boolean') {
|
|
321
|
+
return value ? 1 : 0;
|
|
322
|
+
}
|
|
323
|
+
if (value !== null && typeof value === 'object' && 'sec' in value && 'nanosec' in value) {
|
|
324
|
+
const { sec, nanosec } = value;
|
|
325
|
+
if (typeof sec === 'number' && typeof nanosec === 'number') {
|
|
326
|
+
return sec + nanosec / 1e9;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
310
331
|
function number(value) {
|
|
311
332
|
if (Number.isFinite(value)) {
|
|
312
333
|
return value;
|
package/dist/server/server.js
CHANGED
|
@@ -33,6 +33,7 @@ import { Rosbags } from './rosbags.js';
|
|
|
33
33
|
import { Rosout } from './rosout.js';
|
|
34
34
|
import { Session } from './session.js';
|
|
35
35
|
import { FrameStreams } from './streams.js';
|
|
36
|
+
import { SystemMonitor } from './system.js';
|
|
36
37
|
import { SystemdServices } from './systemd.js';
|
|
37
38
|
import { Teleop } from './teleop.js';
|
|
38
39
|
import { Terminals } from './terminals.js';
|
|
@@ -112,6 +113,7 @@ export async function startServer(options) {
|
|
|
112
113
|
const diagnostics = new Diagnostics(node, logger);
|
|
113
114
|
const terminals = new Terminals(logger);
|
|
114
115
|
const networking = new Networking(logger);
|
|
116
|
+
const system = new SystemMonitor(logger);
|
|
115
117
|
// Next to the panels
|
|
116
118
|
const uploadsDir = path.join(path.dirname(panelsDir), 'images');
|
|
117
119
|
const rosbags = new Rosbags(ros, logger);
|
|
@@ -171,6 +173,7 @@ export async function startServer(options) {
|
|
|
171
173
|
actions,
|
|
172
174
|
parameters,
|
|
173
175
|
rosbags,
|
|
176
|
+
system,
|
|
174
177
|
plugins: host,
|
|
175
178
|
hostname: os.hostname(),
|
|
176
179
|
}, ownPage(req.headers), req.socket.localAddress ?? null);
|
|
@@ -207,6 +210,7 @@ export async function startServer(options) {
|
|
|
207
210
|
systemd.stopAll();
|
|
208
211
|
terminals.stopAll();
|
|
209
212
|
networking.stopAll();
|
|
213
|
+
system.stop();
|
|
210
214
|
// Stops the robot if a page was driving it, while the node still runs
|
|
211
215
|
for (const session of sessions) {
|
|
212
216
|
session.close();
|
package/dist/server/session.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ import type { Rosbags } from './rosbags.ts';
|
|
|
20
20
|
import type { RosGraph } from './ros_graph.ts';
|
|
21
21
|
import type { Rosout } from './rosout.ts';
|
|
22
22
|
import type { FrameStreams } from './streams.ts';
|
|
23
|
+
import type { SystemMonitor } from './system.ts';
|
|
23
24
|
import type { SystemdServices } from './systemd.ts';
|
|
24
25
|
import type { Teleop } from './teleop.ts';
|
|
25
26
|
import type { Terminals } from './terminals.ts';
|
|
@@ -52,6 +53,7 @@ export interface SessionServices {
|
|
|
52
53
|
actions: Actions;
|
|
53
54
|
parameters: Parameters;
|
|
54
55
|
rosbags: Rosbags;
|
|
56
|
+
system: SystemMonitor;
|
|
55
57
|
plugins: PluginHost;
|
|
56
58
|
hostname: string;
|
|
57
59
|
}
|
package/dist/server/session.js
CHANGED
|
@@ -404,9 +404,11 @@ export class Session {
|
|
|
404
404
|
echo: echo && typeof echo === 'object'
|
|
405
405
|
? { field: optionalString(echo.field), truncate: number(echo.truncate, 1, MAX_TRUNCATE, 128) }
|
|
406
406
|
: null,
|
|
407
|
+
samples: message.samples === undefined ? null : strings(message.samples, 'samples'),
|
|
407
408
|
onStatus: (state, text) => this.sendStreamStatus(id, state, text),
|
|
408
409
|
onStats: (stats) => this.send({ type: 'topic.stats', id, stats }),
|
|
409
410
|
onEcho: (update) => this.send({ type: 'topic.echo', id, ...update }),
|
|
411
|
+
onSamples: (samples) => this.send({ type: 'topic.samples', id, ...samples }),
|
|
410
412
|
}));
|
|
411
413
|
return;
|
|
412
414
|
}
|
|
@@ -468,6 +470,12 @@ export class Session {
|
|
|
468
470
|
case 'bags.action':
|
|
469
471
|
this.answer(message.id, Promise.resolve().then(() => services.rosbags.act(checkBagsRequest(message.request), this.ownPage)));
|
|
470
472
|
return;
|
|
473
|
+
case 'system.subscribe': {
|
|
474
|
+
const id = subscriptionId(message.id);
|
|
475
|
+
this.unsubscribe(id);
|
|
476
|
+
this.subscriptions.set(id, services.system.watch((update) => this.send({ type: 'system', id, ...update })));
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
471
479
|
case 'action.subscribe': {
|
|
472
480
|
const id = subscriptionId(message.id);
|
|
473
481
|
this.unsubscribe(id);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { SystemUpdate } from '../shared/protocol.ts';
|
|
2
|
+
import { type Logger } from './util.ts';
|
|
3
|
+
export type SystemUpdateBody = Omit<SystemUpdate, 'type' | 'id'>;
|
|
4
|
+
type Listener = (update: SystemUpdateBody) => void;
|
|
5
|
+
export declare class SystemMonitor {
|
|
6
|
+
private readonly logger;
|
|
7
|
+
private readonly listeners;
|
|
8
|
+
private readonly history;
|
|
9
|
+
private info;
|
|
10
|
+
private infoJson;
|
|
11
|
+
private infoAt;
|
|
12
|
+
private space;
|
|
13
|
+
private spaceJson;
|
|
14
|
+
private spaceAt;
|
|
15
|
+
private sensors;
|
|
16
|
+
private sensorsAt;
|
|
17
|
+
private previous;
|
|
18
|
+
private latest;
|
|
19
|
+
private nvidia;
|
|
20
|
+
private vcgencmd;
|
|
21
|
+
private underVoltageSeen;
|
|
22
|
+
private timer;
|
|
23
|
+
private linger;
|
|
24
|
+
private running;
|
|
25
|
+
private ticking;
|
|
26
|
+
constructor(logger: Logger);
|
|
27
|
+
watch(listener: Listener): () => void;
|
|
28
|
+
stop(): void;
|
|
29
|
+
private send;
|
|
30
|
+
private tick;
|
|
31
|
+
private refresh;
|
|
32
|
+
private sample;
|
|
33
|
+
private temperatures;
|
|
34
|
+
private fans;
|
|
35
|
+
private frequencies;
|
|
36
|
+
private power;
|
|
37
|
+
private gpus;
|
|
38
|
+
private throttled;
|
|
39
|
+
}
|
|
40
|
+
export {};
|