cli: add curtail/dim (#28877)

This commit is contained in:
andig 2026-04-06 19:30:20 +02:00 • committed by GitHub
parent c764bbe964
commit 960aeb03eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 96 additions and 0 deletions

54
cmd/capabilities.go Normal file
View file

@ -0,0 +1,54 @@
package cmd
import (
"github.com/evcc-io/evcc/api"
"github.com/spf13/cobra"
)
// handleCurtailFlag handles the --curtail flag for a given device.
// Returns true if the flag was used.
func handleCurtailFlag(cmd *cobra.Command, v any) bool {
if !cmd.Flags().Changed(flagCurtail) {
return false
}
val, err := cmd.Flags().GetInt(flagCurtail)
if err != nil {
log.ERROR.Println("curtail:", err)
return true
}
if vv, ok := api.Cap[api.Curtailer](v); ok {
if err := vv.Curtail(val > 0); err != nil {
log.ERROR.Println("curtail:", err)
}
} else {
log.ERROR.Println("curtail: not implemented")
}
return true
}
// handleDimFlag handles the --dim flag for a given device.
// Returns true if the flag was used.
func handleDimFlag(cmd *cobra.Command, v any) bool {
if !cmd.Flags().Changed(flagDim) {
return false
}
val, err := cmd.Flags().GetInt(flagDim)
if err != nil {
log.ERROR.Println("dim:", err)
return true
}
if vv, ok := api.Cap[api.Dimmer](v); ok {
if err := vv.Dim(val > 0); err != nil {
log.ERROR.Println("dim:", err)
}
} else {
log.ERROR.Println("dim: not implemented")
}
return true
}

View file

@ -28,6 +28,8 @@ func init() {
//lint:ignore SA1019 as Title is safe on ascii
chargerCmd.Flags().BoolP(flagDisable, "d", false, strings.Title(flagDisable))
chargerCmd.Flags().Bool(flagDiagnose, false, flagDiagnoseDescription)
chargerCmd.Flags().IntP(flagCurtail, "u", -1, flagCurtailDescription)
chargerCmd.Flags().IntP(flagDim, "m", -1, flagDimDescription)
chargerCmd.Flags().BoolP(flagWakeup, "w", false, flagWakeupDescription)
chargerCmd.Flags().IntP(flagPhases, "p", 0, flagPhasesDescription)
chargerCmd.Flags().Bool(flagHeartbeat, false, flagHeartbeatDescription)
@ -97,6 +99,14 @@ func runCharger(cmd *cobra.Command, args []string) {
}
}
if handleCurtailFlag(cmd, v) {
flagUsed = true
}
if handleDimFlag(cmd, v) {
flagUsed = true
}
if cmd.Flag(flagWakeup).Changed {
flagUsed = true

View file

@ -164,6 +164,20 @@ func (d *dumper) Dump(name string, v any) {
fmt.Fprintf(w, "Max AC power:\t%.0fW\t\t\n", v.MaxACPower())
}
if v, ok := api.Cap[api.Dimmer](v); ok {
d.measureTime(w, "Dimmed", func() (string, error) {
dimmed, err := v.Dimmed()
return fmt.Sprintf("%t", dimmed), err
})
}
if v, ok := api.Cap[api.Curtailer](v); ok {
d.measureTime(w, "Curtailed", func() (string, error) {
curtailed, err := v.Curtailed()
return fmt.Sprintf("%t", curtailed), err
})
}
// charger
if v, ok := api.Cap[api.ChargeState](v); ok {

View file

@ -51,6 +51,12 @@ const (
flagDiagnose = "diagnose"
flagDiagnoseDescription = "Diagnose"
flagCurtail = "curtail"
flagCurtailDescription = "Curtail (0/1 to switch, only available if supported by device)"
flagDim = "dim"
flagDimDescription = "Dim (0/1 to switch, only available if supported by device)"
flagWakeup = "wakeup"
flagWakeupDescription = "Wake up"

View file

@ -23,6 +23,8 @@ func init() {
meterCmd.Flags().StringP(flagBatteryMode, "b", "", flagBatteryModeDescription)
meterCmd.Flags().DurationP(flagBatteryModeWait, "w", 0, flagBatteryModeWaitDescription)
meterCmd.Flags().Bool(flagDiagnose, false, flagDiagnoseDescription)
meterCmd.Flags().IntP(flagCurtail, "u", -1, flagCurtailDescription)
meterCmd.Flags().IntP(flagDim, "m", -1, flagDimDescription)
meterCmd.Flags().BoolP(flagRepeat, "r", false, flagRepeatDescription)
meterCmd.Flags().Duration(flagRepeatInterval, 0, flagRepeatIntervalDescription)
meterCmd.Flags().Bool(flagHeartbeat, false, flagHeartbeatDescription)
@ -73,6 +75,16 @@ func runMeter(cmd *cobra.Command, args []string) {
}
}
for _, v := range config.Instances(meters) {
if handleCurtailFlag(cmd, v) {
flagUsed = true
}
if handleDimFlag(cmd, v) {
flagUsed = true
}
}
if !flagUsed {
timeout, _ := cmd.Flags().GetDuration(flagTimeout)
d := dumper{len: len(meters), timeout: timeout}