Skip to content

Commit 661543e

Browse files
authored
Merge pull request #267 from jwefers/fix/linearPwmAdjustment
WIP: Fix/linear pwm adjustment
2 parents 3555570 + de1d870 commit 661543e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+766
-339
lines changed

.github/workflows/go.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ jobs:
2222

2323
- uses: actions/setup-go@v5
2424
with:
25-
go-version: '^1.18'
25+
go-version: '^1.23'
2626

2727
- name: Run golangci-lint
2828
uses: golangci/[email protected]
2929
with:
3030
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
31-
version: v1.54.2
31+
version: v1.61.0
3232

3333
# Optional: working directory, useful for monorepos
3434
# working-directory: somedir

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ PACKAGE := github.com/markusressel/$(NAME)
77
GIT_REV ?= $(shell git rev-parse --short HEAD)
88
SOURCE_DATE_EPOCH ?= $(shell date +%s)
99
DATE ?= $(shell date -u -d @${SOURCE_DATE_EPOCH} +"%Y-%m-%dT%H:%M:%SZ")
10-
VERSION ?= 0.8.1
10+
VERSION ?= 0.9.0
1111

1212
test: ## Run all tests
1313
@go clean --testcache && go test -v ./...

README.md

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ curves:
373373

374374
Unlike the other curve types, this one does not use the average of the sensor data
375375
to calculate its value, which allows you to create a completely custom behaviour.
376-
Keep in mind though that the fan controller is also PID based and will also affect
376+
Keep in mind though that the fan controller may also be PID based which could also affect
377377
how the curve is applied to the fan.
378378

379379
#### Function
@@ -441,7 +441,7 @@ After successfully verifying your configuration you can launch fan2go from the C
441441
working as expected. Assuming you put your configuration file in `/etc/fan2go/fan2go.yaml` run:
442442

443443
```shell
444-
> fan2go help 2 (0.032s) < 22:43:49
444+
> fan2go help
445445
fan2go is a simple daemon that controls the fans
446446
on your computer based on temperature sensors.
447447
@@ -654,23 +654,62 @@ sensor value.
654654

655655
## Fan Controllers
656656

657-
Fan speed is controlled by a PID controller per each configured fan. The default
657+
The speed of a Fan is controlled using a combination of its curve, a control algorithm and the properties of
658+
the fan controller itself.
659+
660+
The curve is used as the target value for the control algorithm to reach. The control algorithm then calculates the
661+
next PWM value to apply to the fan to reach this target value. The fan controller then applies this PWM value to the
662+
fan, while respecting constraints like the minimum and maximum PWM values, as well as the `neverStop` flag.
663+
664+
### Control Algorithms
665+
666+
A control algorithm
667+
is a function that returns the next PWM value to apply based on the target value calculated by the curve. The simplest
668+
control algorithm is the direct control algorithm, which simply forwards the target value to the fan.
669+
670+
#### Direct Control Algorithm
671+
672+
The simplest control algorithm is the direct control algorithm. It simply forwards the curve value to the fan
673+
controller.
674+
675+
```yaml
676+
fans:
677+
- id: some_fan
678+
...
679+
controlAlgorithm: direct
680+
```
681+
682+
This control algorithm can also be used to approach the curve value more slowly:
683+
684+
```yaml
685+
fans:
686+
- id: some_fan
687+
...
688+
controlAlgorithm:
689+
direct:
690+
maxPwmChangePerCycle: 10
691+
```
692+
693+
### PID Control Algorithm
694+
695+
The PID control algorithm uses a PID loop to approach the target value. The default
658696
configuration is pretty non-aggressive using the following values:
659697

660-
| P | I | D |
661-
|--------|---------|----------|
662-
| `0.03` | `0.002` | `0.0005` |
698+
| P | I | D |
699+
|-------|--------|---------|
700+
| `0.3` | `0.02` | `0.005` |
663701

664702
If you don't like the default behaviour you can configure your own in the config:
665703

666704
```yaml
667705
fans:
668706
- id: some_fan
669707
...
670-
controlLoop:
671-
p: 0.03
672-
i: 0.002
673-
d: 0.0005
708+
controlAlgorithm:
709+
pid:
710+
p: 0.3
711+
i: 0.02
712+
d: 0.005
674713
```
675714

676715
The loop is advanced at a constant rate, specified by the `controllerAdjustmentTickRate` config option, which

cmd/curve/list.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ var curveCmd = &cobra.Command{
2626

2727
err = configuration.Validate(configPath)
2828
if err != nil {
29-
ui.FatalWithoutStacktrace(err.Error())
29+
ui.FatalWithoutStacktrace("configuration validation failed: %v", err)
3030
}
3131

3232
curveConfigsToPrint := []configuration.CurveConfig{}
@@ -146,7 +146,7 @@ func drawGraph(graphValues map[int]float64, caption string) {
146146
}
147147

148148
graph := asciigraph.Plot(values, asciigraph.Height(15), asciigraph.Width(100), asciigraph.Caption(caption))
149-
ui.Printfln(graph)
149+
ui.Println(graph)
150150
}
151151

152152
func printFunctionCurveInfo(curve curves.SpeedCurve, config *configuration.FunctionCurveConfig) {
@@ -195,7 +195,7 @@ func printInfoTable(headers []string, rows [][]string) {
195195
panic(tableErr)
196196
}
197197
tableString := buf.String()
198-
ui.Printfln(tableString)
198+
ui.Println(tableString)
199199
}
200200

201201
func init() {

cmd/detect.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ var detectCmd = &cobra.Command{
122122
}
123123
tableString := buf.String()
124124
if idx < (len(tables) - 1) {
125-
ui.Printf(tableString)
125+
ui.Print(tableString)
126126
} else {
127-
ui.Printfln(tableString)
127+
ui.Println(tableString)
128128
}
129129
}
130130
}

cmd/fan/curve.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ var curveCmd = &cobra.Command{
2424
configuration.LoadConfig()
2525
err := configuration.Validate(configPath)
2626
if err != nil {
27-
ui.FatalWithoutStacktrace(err.Error())
27+
ui.FatalWithoutStacktrace("%v", err)
2828
}
2929

3030
persistence := persistence.NewPersistence(configuration.CurrentConfig.DbPath)
@@ -45,7 +45,7 @@ var curveCmd = &cobra.Command{
4545

4646
pwmData, fanCurveErr := persistence.LoadFanPwmData(fan)
4747
if fanCurveErr == nil {
48-
_ = fan.AttachFanCurveData(&pwmData)
48+
_ = fan.AttachFanRpmCurveData(&pwmData)
4949
}
5050

5151
if idx > 0 {
@@ -54,7 +54,7 @@ var curveCmd = &cobra.Command{
5454
}
5555

5656
// print table
57-
ui.Printfln(fan.GetId())
57+
ui.Println(fan.GetId())
5858
tab := table.Table{
5959
Headers: []string{"", ""},
6060
Rows: [][]string{
@@ -78,11 +78,11 @@ var curveCmd = &cobra.Command{
7878
panic(tableErr)
7979
}
8080
tableString := buf.String()
81-
ui.Printfln(tableString)
81+
ui.Println(tableString)
8282

8383
// print graph
8484
if fanCurveErr != nil {
85-
ui.Printfln("No fan curve data yet...")
85+
ui.Println("No fan curve data yet...")
8686
continue
8787
}
8888

@@ -99,7 +99,7 @@ var curveCmd = &cobra.Command{
9999

100100
caption := "RPM / PWM"
101101
graph := asciigraph.Plot(values, asciigraph.Height(15), asciigraph.Width(100), asciigraph.Caption(caption))
102-
ui.Printfln(graph)
102+
ui.Println(graph)
103103
}
104104
},
105105
}

cmd/fan/fan.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func getFan(id string) (fans.Fan, error) {
3535
configuration.LoadConfig()
3636
err := configuration.Validate(configPath)
3737
if err != nil {
38-
ui.FatalWithoutStacktrace(err.Error())
38+
ui.FatalWithoutStacktrace("%v", err)
3939
}
4040

4141
controllers := hwmon.GetChips()

cmd/fan/init.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ package fan
22

33
import (
44
"github.com/markusressel/fan2go/internal/configuration"
5+
"github.com/markusressel/fan2go/internal/control_loop"
56
"github.com/markusressel/fan2go/internal/controller"
67
"github.com/markusressel/fan2go/internal/persistence"
78
"github.com/markusressel/fan2go/internal/ui"
8-
"github.com/markusressel/fan2go/internal/util"
99
"github.com/spf13/cobra"
1010
"github.com/spf13/viper"
1111
)
@@ -31,12 +31,9 @@ var initCmd = &cobra.Command{
3131
fanController := controller.NewFanController(
3232
p,
3333
fan,
34-
*util.NewPidLoop(
35-
0.03,
36-
0.002,
37-
0.0005,
38-
),
39-
configuration.CurrentConfig.ControllerAdjustmentTickRate)
34+
control_loop.NewDirectControlLoop(nil),
35+
configuration.CurrentConfig.ControllerAdjustmentTickRate,
36+
)
4037

4138
ui.Info("Deleting existing data for fan '%s'...", fan.GetId())
4239

cmd/root.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ on your computer based on temperature sensors.`,
3333
configuration.LoadConfig()
3434
err := configuration.Validate(configPath)
3535
if err != nil {
36-
ui.ErrorAndNotify("Config Validation Error", err.Error())
36+
ui.ErrorAndNotify("Config Validation Error: %v", "%v", err)
3737
return
3838
}
3939

@@ -75,6 +75,7 @@ func printHeader() {
7575
if err != nil {
7676
fmt.Println("fan2go")
7777
}
78+
ui.Info("Version: %s", global.Version)
7879
}
7980

8081
// Execute adds all child commands to the root command and sets flags appropriately.

cmd/sensor/sensor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func getSensor(id string) (sensors.Sensor, error) {
5252
configuration.LoadConfig()
5353
err := configuration.Validate(configPath)
5454
if err != nil {
55-
ui.FatalWithoutStacktrace(err.Error())
55+
ui.FatalWithoutStacktrace("%v", err)
5656
}
5757

5858
controllers := hwmon.GetChips()

0 commit comments

Comments
 (0)