Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added "config validate" cli command #90

Merged
merged 1 commit into from
Feb 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 44 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
<h4 align="center">A daemon to control the fans of a computer.</h4>

<div align="center">
[![Programming Language](https://img.shields.io/badge/Go-00ADD8?logo=go&logoColor=white)]()
[![Latest Release](https://img.shields.io/github/release/markusressel/fan2go.svg)](https://github.com/markusressel/fan2go/releases)
[![License](https://img.shields.io/badge/license-AGPLv3-blue.svg)](/LICENSE)

[![Programming Language](https://img.shields.io/badge/Go-00ADD8?logo=go&logoColor=white)]()
[![Latest Release](https://img.shields.io/github/release/markusressel/fan2go.svg)](https://github.com/markusressel/fan2go/releases)
[![License](https://img.shields.io/badge/license-AGPLv3-blue.svg)](/LICENSE)

</div>

<p align="center"><img src="screenshots/graph.png" width=90% alt="Screenshot of Pyrra"></p>
Expand All @@ -22,8 +22,8 @@
* [x] Fan speed control using user-defined speed curves
* [x] Fully customizable and composable curve definitions
* [x] Massive range of supported devices
* [x] Direct integration with lm-sensors
* [x] File Fan/Sensor for control/measurement of custom devices
* [x] Direct integration with lm-sensors
* [x] File Fan/Sensor for control/measurement of custom devices
* [x] Works after resume from suspend
* [x] **Stable** device paths after reboot
* [x] Automatic analysis of fan properties, like:
Expand Down Expand Up @@ -137,7 +137,7 @@ fans:
path: /tmp/file_fan
```

```bash
```shell
> cat /tmp/file_fan
255
```
Expand Down Expand Up @@ -239,17 +239,38 @@ curves:

An example configuration file including more detailed documentation can be found in [fan2go.yaml](/fan2go.yaml).

### Verify your Configuration

To check whether your configuration is correct before actually running fan2go you can use:

```shell
> fan2go config validate
INFO Using configuration file at: ./fan2go.yaml
SUCCESS Config looks good! :)
```

or to validate a specific config file:

```shell
> fan2go -c "./my_config.yaml" config validate
INFO Using configuration file at: ./my_config.yaml
WARNING Unused curve configuration: m2_first_ssd_curve
ERROR Validation failed: Curve m2_ssd_curve: no curve definition with id 'm2_first_ssd_curve123' found
```

## Run

Assuming you put your configuration file in `/etc/fan2go/fan2go.yaml`:
After successfully verifying your configuration you can launch fan2go from the CLI and make sure the initial setup is
working as expected. Assuming you put your configuration file in `/etc/fan2go/fan2go.yaml` run:

```shell
sudo fan2go
> sudo fan2go
```

Alternatively you can specify the path to your configuration file like this:

```shell
fan2go -c /home/markus/my_fan2go_config.yaml
> fan2go -c /home/markus/my_fan2go_config.yaml
```

## As a Service
Expand All @@ -267,8 +288,8 @@ journalctl -u fan2go -f

## CLI Commands

Although fan2go is a fan controller daemon at heart, it also provides some handy cli commands
to interact with the devices that you have specified within your config.
Although fan2go is a fan controller daemon at heart, it also provides some handy cli commands to interact with the
devices that you have specified within your config.

### Fans interaction

Expand Down Expand Up @@ -341,8 +362,8 @@ statistics:
port: 9000
```

You can then see the metics on [http://localhost:9000/metrics](http://localhost:9000/metrics) while the fan2go daemon
is running.
You can then see the metics on [http://localhost:9000/metrics](http://localhost:9000/metrics) while the fan2go daemon is
running.

# How it works

Expand All @@ -361,19 +382,22 @@ To properly control a fan which fan2go has not seen before, its speed curve is a
measurements. Measurements taken during this process will then be used to determine the lowest PWM value at which the
fan is still running, as well as the highest PWM value that still yields a change in RPM.

All of this is saved to a local database (path given by the `dbPath` config option), so it is only needed once per fan configuration.
All of this is saved to a local database (path given by the `dbPath` config option), so it is only needed once per fan
configuration.

To reduce the risk of runnin the whole system on low fan speeds for such a long period of time, you can force fan2go to initialize only
one fan at a time, using the `runFanInitializationInParallel: false` config option.
To reduce the risk of runnin the whole system on low fan speeds for such a long period of time, you can force fan2go to
initialize only one fan at a time, using the `runFanInitializationInParallel: false` config option.

## Monitoring

Temperature and RPM sensors are polled continuously at the rate specified by the `tempSensorPollingRate` config option.
`tempRollingWindowSize`/`rpmRollingWindowSize` amount of measurements are always averaged and stored as the average sensor value.
`tempRollingWindowSize`/`rpmRollingWindowSize` amount of measurements are always averaged and stored as the average
sensor value.

## Fan Controllers

Fan speeds are continuously adjusted at the rate specified by the `controllerAdjustmentTickRate` config option based on the value of their associated curve.
Fan speeds are continuously adjusted at the rate specified by the `controllerAdjustmentTickRate` config option based on
the value of their associated curve.

# Dependencies

Expand Down
14 changes: 14 additions & 0 deletions cmd/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package config

import "github.com/spf13/cobra"

var Command = &cobra.Command{
Use: "config",
Short: "Configuration related commands",
Long: ``,
TraverseChildren: true,
}

func init() {
_ = Command.MarkPersistentFlagRequired("config")
}
33 changes: 33 additions & 0 deletions cmd/config/validate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package config

import (
"github.com/markusressel/fan2go/internal/configuration"
"github.com/markusressel/fan2go/internal/ui"
"github.com/spf13/cobra"
"os"
)

var validateCmd = &cobra.Command{
Use: "validate",
Short: "Validates the current configuration",
Long: ``,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
// note: config file path parameter comes from the root command (-c)
configPath := configuration.DetectConfigFile()
ui.Info("Using configuration file at: %s", configPath)
configuration.LoadConfig()

if err := configuration.Validate(); err != nil {
ui.Error("Validation failed: %v", err)
os.Exit(1)
}

ui.Success("Config looks good! :)")
return nil
},
}

func init() {
Command.AddCommand(validateCmd)
}
10 changes: 8 additions & 2 deletions cmd/curve.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,15 @@ import (
var curveCmd = &cobra.Command{
Use: "curve",
Short: "Print the measured fan curve(s) to console",
//Long: `All software has versions. This is fan2go's`,
Run: func(cmd *cobra.Command, args []string) {
configuration.ReadConfigFile()
configPath := configuration.DetectConfigFile()
ui.Info("Using configuration file at: %s", configPath)
configuration.LoadConfig()
err := configuration.Validate()
if err != nil {
ui.Fatal(err.Error())
}

persistence := persistence.NewPersistence(configuration.CurrentConfig.DbPath)

controllers := hwmon.GetChips()
Expand Down
9 changes: 8 additions & 1 deletion cmd/fan/fan.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/markusressel/fan2go/internal/configuration"
"github.com/markusressel/fan2go/internal/fans"
"github.com/markusressel/fan2go/internal/hwmon"
"github.com/markusressel/fan2go/internal/ui"
"github.com/spf13/cobra"
"regexp"
)
Expand All @@ -30,7 +31,13 @@ func init() {
}

func getFan(id string) (fans.Fan, error) {
configuration.ReadConfigFile()
configPath := configuration.DetectConfigFile()
ui.Info("Using configuration file at: %s", configPath)
configuration.LoadConfig()
err := configuration.Validate()
if err != nil {
ui.Fatal(err.Error())
}

controllers := hwmon.GetChips()

Expand Down
12 changes: 11 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"fmt"
"github.com/markusressel/fan2go/cmd/config"
"github.com/markusressel/fan2go/cmd/fan"
"github.com/markusressel/fan2go/cmd/sensor"
"github.com/markusressel/fan2go/internal"
Expand Down Expand Up @@ -30,7 +31,14 @@ on your computer based on temperature sensors.`,
setupUi()
printHeader()

configuration.ReadConfigFile()
configPath := configuration.DetectConfigFile()
ui.Info("Using configuration file at: %s", configPath)
configuration.LoadConfig()
err := configuration.Validate()
if err != nil {
ui.Fatal(err.Error())
}

internal.RunDaemon()
},
}
Expand All @@ -41,6 +49,8 @@ func init() {
rootCmd.PersistentFlags().BoolVarP(&noStyle, "no-style", "", false, "Disable all terminal output styling")
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "More verbose output")

rootCmd.AddCommand(config.Command)

rootCmd.AddCommand(fan.Command)
rootCmd.AddCommand(sensor.Command)
}
Expand Down
9 changes: 8 additions & 1 deletion cmd/sensor/sensor.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/markusressel/fan2go/internal/configuration"
"github.com/markusressel/fan2go/internal/hwmon"
"github.com/markusressel/fan2go/internal/sensors"
"github.com/markusressel/fan2go/internal/ui"
"github.com/pterm/pterm"
"github.com/spf13/cobra"
"regexp"
Expand Down Expand Up @@ -50,7 +51,13 @@ func init() {
}

func getSensor(id string) (sensors.Sensor, error) {
configuration.ReadConfigFile()
configPath := configuration.DetectConfigFile()
ui.Info("Using configuration file at: %s", configPath)
configuration.LoadConfig()
err := configuration.Validate()
if err != nil {
ui.Fatal(err.Error())
}

controllers := hwmon.GetChips()

Expand Down
17 changes: 7 additions & 10 deletions internal/configuration/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,21 +71,18 @@ func setDefaultValues() {
viper.SetDefault("fans", []FanConfig{})
}

func ReadConfigFile() {
// DetectConfigFile detects the path of the first existing config file
func DetectConfigFile() string {
if err := viper.ReadInConfig(); err != nil {
// config file is required, so we fail here
ui.Fatal("Error reading config file, %s", err)
}
// this is only populated _after_ ReadInConfig()
ui.Info("Using configuration file at: %s", viper.ConfigFileUsed())

LoadConfig()
return GetFilePath()
}

err := validateConfig(&CurrentConfig)
if err != nil {
ui.Fatal(err.Error())
}
ui.Fatal("Config validation failed")
// GetFilePath this is only populated _after_ DetectConfigFile()
func GetFilePath() string {
return viper.ConfigFileUsed()
}

func LoadConfig() {
Expand Down
6 changes: 5 additions & 1 deletion internal/configuration/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import (
"github.com/markusressel/fan2go/internal/util"
)

func validateConfig(config *Configuration) error {
func Validate() error {
return ValidateConfig(&CurrentConfig)
}

func ValidateConfig(config *Configuration) error {
err := validateSensors(config)
if err != nil {
return err
Expand Down
Loading