diff --git a/cmd/capabilities.go b/cmd/capabilities.go new file mode 100644 index 000000000..69626974a --- /dev/null +++ b/cmd/capabilities.go @@ -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 +} diff --git a/cmd/charger.go b/cmd/charger.go index 6c87e6318..55467c443 100644 --- a/cmd/charger.go +++ b/cmd/charger.go @@ -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 diff --git a/cmd/dumper.go b/cmd/dumper.go index f39046979..6d6e17521 100644 --- a/cmd/dumper.go +++ b/cmd/dumper.go @@ -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 { diff --git a/cmd/flags.go b/cmd/flags.go index 7b14b5f10..c3e49f990 100644 --- a/cmd/flags.go +++ b/cmd/flags.go @@ -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" diff --git a/cmd/meter.go b/cmd/meter.go index 2bf06b82b..e52d2e8c2 100644 --- a/cmd/meter.go +++ b/cmd/meter.go @@ -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}