cctv 2.0.0

Terminal interface for CoolerControl
cctv-2.0.0 is not a library.

A terminal client for CoolerControl.

:warning: Requires the CoolerControl service daemon to be running either locally or remotely, see Configuration.

[[TOC]]

Building

Clone the git repo and build with cargo. Requires a working Rust installation.

git clone https://gitlab.com/coolercontrol/cctv.git
cd cctv
cargo build --release
cargo run --release

Installing/Upgrading

There are no packages for distributions yet but you can download and install the latest binary artifact built from master or build from source yourself.

AUR (Arch Linux)

:warning: Not yet published — install cctv-bin with your preferred AUR helper:

yay -S cctv-bin

To run cctv tasks in the background, enable the systemd user service:

systemctl --user enable --now cctv.service

Latest release

curl -LOJ --clobber --output-dir "/tmp" \
    https://gitlab.com/api/v4/projects/69657520/packages/generic/master/latest/cctv
sudo install -Dm 755 /tmp/cctv -t /usr/bin

From source

Install with cargo. Requires a working Rust installation.

cargo install --git https://gitlab.com/coolercontrol/cctv.git

From crates.io

cctv is also published to crates.io. Note that the version there may be slightly outdated.

cargo install cctv

Make sure $HOME/.cargo/bin is in your path:

# Bash users
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

# zsh users
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

Usage

CLI

See cctv --help for a list of available commands.

The dump command is meant to be used with jq.

For example, to get the name of the currently active mode:

cctv dump | jq -r '.state.current_mode_uid as $uid | .modes[] | select(.uid == $uid) | .name'

Feel free to reach out to request dedicated subcommands for commonly used operations.

TUI

Keybindings

Shared
Keys Action
Down, e, j Select next item
Up, i, k Select previous item
Right, o, l Go to the next page
Left, n, h Go to the previous page
R Refresh app data
s Toggle legend visibility
q Quit
- Decrease chart time range by 30 seconds (min 30s)
+/= Increase chart time range by 30 seconds
Ctrl+b Toggle dock visibility. You can still use relevant keybindings when the dock is hidden.
Devices
Keys Action
a Toggle between the default and the alternative chart

cctv shows all channels enabled in the CoolerControl daemon. To hide a channel (e.g. per-core temperatures), disable it in the CoolerControl UI.

Modes
Keys Action
Enter Activate currently highlighted mode
Profiles
Keys Action
E Enter edit mode
Enter Save working changes
Esc Leave edit mode and keep a draft
A Apply saved changes to the daemon
D Reset edit buffer to current profile values
Tasks
Keys Action
N Create a new task and open editor
E Edit the selected task
Enter Validate and save changes
Esc Close editor and save a draft
X Toggle deletion mark on the selected task
A Validate and apply all tasks to the config file
D Discard in-memory changes (reload from disk)

Editing profiles

There are two input modes: normal and edit. Normal mode is the default for navigation. Edit mode opens a popup prefilled with the current settings.

Edits are in one of three states: draft, saved, and applied.

State Description
Draft Local edits kept in memory, not yet validated.
Saved Validated edits used for graph drawing, ineffective until applied.
Applied Final changes sent to the daemon.

Changes are validated when moving between stages.

From To Validation
Draft Saved All syntactically correct changes are accepted.
Saved Applied All changes deemed valid by the daemon are accepted.

There are no guard rails beyond these. You will be notified of errors; no notification means success.

:light_bulb: Refreshing the page syncs cctv with the daemon and drops saved changes.

:warning: Changes made in cctv require a page refresh to be reflected in the GUI. The reverse is also true.

Editing tasks

Tasks that have been modified but not yet persisted are marked in the dock:

Suffix Meaning
(none) Applied — matches what's on disk.
(Draft) Local edits, not yet validated.
(Unapplied) Validated, but not yet written to disk.
(Deleted) Marked for deletion — will be removed on apply.

Tasks

Tasks are event-driven automation rules that pair a trigger with an action. They run only on the leader cctv instance to prevent duplicate execution.

Triggers

Trigger Fields Description
Alert alert_uid, state (Active, Inactive, Error) Fires when an alert transitions to the given state.
Mode change mode_uid Fires when the specified mode is activated.

:light_bulb: Get alert UIDs with cctv dump | jq -r '.state.alerts[] | {uid: .uid, name: .name}' and mode UIDs with cctv dump | jq -r '.modes[] | {uid: .uid, name: .name}'.

Actions

Type Fields Description
Script path Executes a script. The shebang is parsed to determine the interpreter; the script does not have to be executable but must contain a valid shebang or be runnable via /usr/bin/env bash.
ChangeMode mode_uid Activates the specified mode via the daemon.
ActivatePreviousMode Reverts to the previously active mode.

Example

{
	"tasks": [
		{
			"trigger": { "alert_uid": "<uid>", "state": "Active" },
			"action": { "type": "Script", "path": "/path/to/script" }
		},
		{
			"trigger": { "alert_uid": "<uid>", "state": "Inactive" },
			"action": { "type": "ActivatePreviousMode" }
		},
		{
			"trigger": { "mode_uid": "<uid>" },
			"action": { "type": "ChangeMode", "mode_uid": "<target-mode-uid>" }
		}
	]
}

Configuration

Configuration is optional. cctv reads its from one of these locations, in order of precedence:

  • CCTV_CONFIG_FILEPATH environment variable
  • $XDG_CONFIG_HOME/coolercontrol/cctv.json
  • $HOME/.config/coolercontrol/cctv.json

If a file is not found, cctv will use default values and create one for you.

If daemon_address or port are undefined, cctv will pull them from the local coolercontrold config file located at /etc/coolercontrol/config.toml.

These are useful for connecting to remote daemons. Combined with CCTV_CONFIG_FILEPATH, you can have multiple cctv instances on one machine connecting to different coolercontrold instances.

Finally, for security, the password is read from the CCTV_DAEMON_PASSWORD environment variable.

Configuration Options

Option Description Default
daemon_address Address CoolerControl is listening on. Value in the coolercontrold configuration file or internal default.
port Port CoolerControl is listening on. Value in the coolercontrold configuration file or internal default.
time_range_s History in seconds for timeseries charts. 60
username CoolerControl username. Internal default
skip_splash Skips the splash screen. false
tasks List of tasks to execute. []

Environment variables

Environment Variable Description Default
CCTV_CONFIG_FILEPATH Absolute path to the CCTV configuration file. See above.
CCTV_DAEMON_PASSWORD CoolerControl password. Internal default

Note that there's currently no SSL or IPv6 support.

Obtaining cctv logs

TUI logs are written to cctv-<timestamp>-<pid>.log in XDG_STATE_HOME/coolercontrol or HOME/.local/state/coolercontrol. A cctv-latest.log symlink always points to the most recently started instance's log. Other modes write to stdout. Daemon logs from a systemd unit can be retrieved with journalctl --user -u cctv.