Skip to content

Commit

Permalink
added validation, deprecate ControlLoop
Browse files Browse the repository at this point in the history
  • Loading branch information
markusressel committed Sep 23, 2024
1 parent 98b295d commit cdfd290
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 17 deletions.
6 changes: 1 addition & 5 deletions cmd/fan/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@ var initCmd = &cobra.Command{
fanController := controller.NewFanController(
p,
fan,
control_loop.NewPidControlLoop(
0.03,
0.002,
0.0005,
),
control_loop.NewDirectControlLoop(nil),
configuration.CurrentConfig.ControllerAdjustmentTickRate)

ui.Info("Deleting existing data for fan '%s'...", fan.GetId())
Expand Down
5 changes: 4 additions & 1 deletion internal/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,9 @@ func initializeObjects(pers persistence.Persistence) map[fans.Fan]controller.Fan

var controlLoop control_loop.ControlLoop

// TODO: check compatibility fallback
// compatibility fallback
if config.ControlLoop != nil {

Check failure on line 234 in internal/backend.go

View workflow job for this annotation

GitHub Actions / Generate cross-platform builds

SA1019: config.ControlLoop is deprecated: HeaderMap exists for historical compatibility and should not be used. To access the headers returned by a handler, use the Response.Header map as returned by the Result method. (staticcheck)
ui.Warning("Using deprecated control loop configuration for fan %s. Please update your configuration to use the new control algorithm configuration.", config.ID)
controlLoop = control_loop.NewPidControlLoop(
config.ControlLoop.P,

Check failure on line 237 in internal/backend.go

View workflow job for this annotation

GitHub Actions / Generate cross-platform builds

SA1019: config.ControlLoop is deprecated: HeaderMap exists for historical compatibility and should not be used. To access the headers returned by a handler, use the Response.Header map as returned by the Result method. (staticcheck)
config.ControlLoop.I,

Check failure on line 238 in internal/backend.go

View workflow job for this annotation

GitHub Actions / Generate cross-platform builds

SA1019: config.ControlLoop is deprecated: HeaderMap exists for historical compatibility and should not be used. To access the headers returned by a handler, use the Response.Header map as returned by the Result method. (staticcheck)
Expand All @@ -247,6 +248,8 @@ func initializeObjects(pers persistence.Persistence) map[fans.Fan]controller.Fan
controlLoop = control_loop.NewDirectControlLoop(
&config.ControlAlgorithm.Direct.MaxPwmChangePerCycle,
)
} else {
controlLoop = control_loop.NewDirectControlLoop(nil)
}

fanController := controller.NewFanController(pers, fan, controlLoop, updateRate)
Expand Down
8 changes: 7 additions & 1 deletion internal/configuration/fans.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ type FanConfig struct {
HwMon *HwMonFanConfig `json:"hwMon,omitempty"`
File *FileFanConfig `json:"file,omitempty"`
Cmd *CmdFanConfig `json:"cmd,omitempty"`
ControlLoop *ControlLoopConfig `json:"controlLoop,omitempty"`

// ControlLoop is a configuration for a PID control loop.
//
// Deprecated: HeaderMap exists for historical compatibility
// and should not be used. To access the headers returned by a handler,
// use the Response.Header map as returned by the Result method.
ControlLoop *ControlLoopConfig `json:"controlLoop,omitempty"`
}

type ControlAlgorithm string
Expand Down
15 changes: 15 additions & 0 deletions internal/configuration/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,21 @@ func validateFans(config *Configuration) error {
return fmt.Errorf("fan %s: no curve definition with id '%s' found", fanConfig.ID, fanConfig.Curve)
}

if fanConfig.ControlAlgorithm != nil {
if fanConfig.ControlAlgorithm.Direct != nil {
if fanConfig.ControlAlgorithm.Direct.MaxPwmChangePerCycle <= 0 {
return fmt.Errorf("fan %s: invalid maxPwmChangePerCycle, must be > 0", fanConfig.ID)
}
}

if fanConfig.ControlAlgorithm.Pid != nil {
pidConfig := fanConfig.ControlAlgorithm.Pid
if pidConfig.P == 0 && pidConfig.I == 0 && pidConfig.D == 0 {
return fmt.Errorf("fan %s: all PID constants are zero", fanConfig.ID)
}
}
}

if fanConfig.HwMon != nil {
if (fanConfig.HwMon.Index != 0 && fanConfig.HwMon.RpmChannel != 0) || (fanConfig.HwMon.Index == 0 && fanConfig.HwMon.RpmChannel == 0) {
return fmt.Errorf("fan %s: must have one of index or rpmChannel, must be >= 1", fanConfig.ID)
Expand Down
11 changes: 1 addition & 10 deletions internal/control_loop/pid.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,12 @@ type PidControlLoop struct {
pidLoop *util.PidLoop
}

// NewPidControlLoop creates a PidControlLoop, which is a very simple control that Pidly applies the given
// target pwm. It can also be used to gracefully approach the target by
// utilizing the "maxPwmChangePerCycle" property.
// NewPidControlLoop creates a PidControlLoop, which uses a PID loop to approach the target.
func NewPidControlLoop(
p float64,
i float64,
d float64,
) *PidControlLoop {
// TODO: somehow incorporate default values
//pidLoop = util.NewPidLoop(
// 0.03,
// 0.002,
// 0.0005,
//)

return &PidControlLoop{
pidLoop: util.NewPidLoop(p, i, d),
}
Expand Down

0 comments on commit cdfd290

Please sign in to comment.