<div align="center">
<h1>
<img alt="cctv_logo" src="https://gitlab.com/coolercontrol/cctv/-/raw/master/assets/cctv.png" width="200">
<br>
cctv
<br>
</h1>
A terminal client for [CoolerControl](https://gitlab.com/coolercontrol/coolercontrol).

:warning: Requires the CoolerControl service daemon to be running either locally or remotely, [see Configuration](#configuration).
</div>
[[_TOC_]]
## Building
Clone the git repo and build with cargo. Requires a working [Rust installation](https://www.rust-lang.org/tools/install).
```bash
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.
### Latest release
```bash
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](https://www.rust-lang.org/tools/install).
```bash
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.
```bash
cargo install cctv
```
Make sure `$HOME/.cargo/bin` is in your path:
```bash
# 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
```None
Usage: cctv [OPTIONS]
TUI client for CoolerControl
Options:
--list-modes, -l Lists all available modes.
--activate-mode <mode-name>, -a <mode-name> Activates the specified mode.
--daemonize Do not launch the TUI and daemonize cctv.
--activate-previous-mode, -p Activates the previously active mode.
--dump Dump information about the system to stdout as json.
--help, -h Shows this help message.
If no options are passed, the application will launch into the TUI.
```
The `dump` command is meant to be used with [`jq`](https://jqlang.org). To get
the name of the currently active mode:
```Bash
Feel free to reach out to request shortcuts for commonly used operations.
### TUI
#### Keybindings
For the differences between `working` and `saved` changes or `edit` and `normal` modes,
refer to [editing profiles](#editing-profiles).
| Down, e, j | All | Normal | Select next item |
| Up, i, k | All | Normal | Select previous item |
| Right, o, l | All | Normal | Go to the next page |
| Left, n, h | All | Normal | Go to the previous page |
| R | All | Normal | Refresh app data |
| s | All | Normal | Toggle legend visibility |
| q | All | Normal | Quit |
| Ctrl+b | All | Normal | Toggle dock visibility. You can still use relevant keybindings when the dock is hidden. |
| a | Devices | Normal | Toggle between the default and the alternative chart |
| Enter | Modes | Normal | Activate currently highlighted mode |
| D | Profiles | All | Discard working changes |
| E | Profiles | Normal | Enter edit mode |
| A | Profiles | Normal | Apply saved changes to daemon |
| Esc | Profiles | Edit | Exit edit mode |
| Enter | Profiles | Edit | Save working changes |
| Right, o, l | Profiles | Edit | Move cursor right |
| Left, n, h | Profiles | Edit | Move cursor left |
| Backspace | Profiles | Edit | Delete one character |
| digits, space, dot, comma, [, ] | Profiles | Edit | Insert the character |
#### Editing profiles
Profile editing is a work-in-progress. There's experimental support for
manipulating graph and fixed profiles.
:warning: Take a backup of your config before editing - there may be breakages.
There are two input modes: edit and normal. Normal mode is the default.
When you enter edit mode you will see a popup populated with the current
settings.
Edits are in one of three states: working, saved, and applied.
| Working | Changes made but not saved within `cctv`. Visible only in the text box. |
| Saved | Changes saved in `cctv` but not submitted to CoolerControl. Used for graph drawing, ineffective until applied. |
| Applied | Final changes successfully sent to the daemon. |
:light_bulb: Working changes are preserved (without being saved) when moving between
edit and normal modes.
Changes are validated when moving between stages.
| Working | 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 any errors. Lack
of a notification indicates success.
:light_bulb: To discard saved changes: press 'R' to sync `cctv` with the daemon.
:warning: Changes made in `cctv` require a page refresh to be reflected in the GUI.
The reverse is also true.
### Alerts
`cctv` will listen for server side events both when daemonized and in interactive mode.
It will send desktop notifications when it receives an alert.
## 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
| `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 when given alerts shift to the specified state. cctv will parse the shebang in the script meaning it can execute anything and not just Bash. See [example.json](assets/example.json)| [] |
### Environment variables
| `CCTV_CONFIG_FILEPATH` | Absolute path to the CCTV configuration file. | See [above](#configuration). |
| `CCTV_DAEMON_PASSWORD` | CoolerControl password. | *Internal default* |
Note that there's currently no SSL or IPv6 support.