From 06ef1e7745a74657df323aad2071d0391727fb99 Mon Sep 17 00:00:00 2001 From: Attilio B Date: Sun, 26 May 2024 17:59:39 +0200 Subject: [PATCH] Fix/cli params (#20) * feat(addons): adding new version * fix(params): fixing flags and env vars --- home-assistant/addons/sbam/config.json | 4 +- pkg/cmd/configure.go | 42 ++++++++--- pkg/cmd/estimate.go | 27 ++++--- pkg/cmd/root.go | 3 + pkg/cmd/schedule.go | 100 ++++++++++++++++++------- 5 files changed, 128 insertions(+), 48 deletions(-) diff --git a/home-assistant/addons/sbam/config.json b/home-assistant/addons/sbam/config.json index 8d9744c..7ae6dee 100644 --- a/home-assistant/addons/sbam/config.json +++ b/home-assistant/addons/sbam/config.json @@ -1,6 +1,6 @@ { "name": "sbam", - "version": "1.3.5", + "version": "1.3.6", "slug": "sbam", "init": "false", "description": "Smart Battery Advanced Manager", @@ -36,4 +36,4 @@ "pw_batt_reserve": "float", "defaults": "bool" } -} \ No newline at end of file +} diff --git a/pkg/cmd/configure.go b/pkg/cmd/configure.go index 16ed45a..1528102 100644 --- a/pkg/cmd/configure.go +++ b/pkg/cmd/configure.go @@ -2,6 +2,7 @@ package cmd import ( "errors" + "os" "sbam/pkg/fronius" u "sbam/src/utils" "strings" @@ -10,13 +11,34 @@ import ( "github.com/spf13/viper" ) + +var c_defaults bool +var force_charge bool +var power int + +const const_pw = 0 + var cfgCmd = &cobra.Command{ Use: "configure", Short: "Configure Battery Storage Charge", Long: `connect via modbus to the fronius inverter and set charging`, Run: func(cmd *cobra.Command, args []string) { - fronius_ip := viper.GetString("fronius_ip") - power := viper.GetViper().GetInt("power") + if len(fronius_ip) == 0 { fronius_ip = viper.GetString("fronius_ip") } + if !c_defaults { + if _, exists := os.LookupEnv("DEFAULTS"); exists { + c_defaults = viper.GetBool("defaults") + } + } + if !force_charge { + if _, exists := os.LookupEnv("FORCE_CHARGE"); exists { + force_charge = viper.GetBool("force_charge") + } + } + if power == const_pw { + if _, exists := os.LookupEnv("POWER"); exists { + power = viper.GetInt("power") + } + } err := checkConfigure(fronius_ip) if err != nil { @@ -30,11 +52,13 @@ var cfgCmd = &cobra.Command{ } func init() { - cfgCmd.Flags().StringP("fronius_ip", "H", "", "FRONIUS_IP") - cfgCmd.Flags().BoolP("defaults", "d", false, "Set defaults") - cfgCmd.Flags().BoolP("force-charge", "f", false, "Force charge") - cfgCmd.Flags().Int16P("power", "p", 0, "Power (percent of nominal power)") + cfgCmd.Flags().StringVarP(&fronius_ip,"fronius_ip", "H", "", "set FRONIUS_IP") + cfgCmd.Flags().BoolVarP(&c_defaults,"defaults", "d", false, "set DEFAULTS") + cfgCmd.Flags().BoolVarP(&force_charge,"force_charge", "f", false, "set FORCE_CHARGE") + cfgCmd.Flags().IntVarP(&power,"power", "p", const_pw, "set percent of nominal POWER") viper.BindPFlag("fronius_ip", cfgCmd.Flags().Lookup("fronius_ip")) + viper.BindPFlag("defaults", scdCmd.Flags().Lookup("defaults")) + viper.BindPFlag("force_charge", cfgCmd.Flags().Lookup("force_charge")) viper.BindPFlag("power", cfgCmd.Flags().Lookup("power")) rootCmd.AddCommand(cfgCmd) } @@ -48,15 +72,15 @@ func checkConfigure(fronius_ip string) error { } func configure(fronius_ip string, power int, cmd *cobra.Command) { - if cmd.Flags().Changed("defaults") { + if c_defaults { err := fronius.Setdefaults(fronius_ip) if err != nil { u.Log.Error(err) panic(err) } - } else if cmd.Flags().Changed("force-charge") { + } else if force_charge { if power == 0 { - u.Log.Error("The --power flag must be set when using --force-charge") + u.Log.Error("The --power flag must be set when using --force_charge") return } err := fronius.ForceCharge(fronius_ip, int16(power)) diff --git a/pkg/cmd/estimate.go b/pkg/cmd/estimate.go index b846c62..9b569b5 100644 --- a/pkg/cmd/estimate.go +++ b/pkg/cmd/estimate.go @@ -2,7 +2,7 @@ package cmd import ( "errors" - "sbam/pkg/power" + pw "sbam/pkg/power" "sbam/pkg/storage" u "sbam/src/utils" "strings" @@ -11,32 +11,37 @@ import ( "github.com/spf13/viper" ) +var e_url string +var e_apiKey string + var estCmd = &cobra.Command{ Use: "estimate", Short: "Estimate Forecast Solar Power", Long: `Print the solar forecast and the battery storage power`, Run: func(cmd *cobra.Command, args []string) { - url := viper.GetString("url") - apiKey := viper.GetString("apikey") - fronius_ip := viper.GetString("fronius_ip") + if len(e_url) == 0 {e_url = viper.GetString("url") } + if len(e_apiKey) == 0 { e_apiKey = viper.GetString("apikey") } + if len(fronius_ip) == 0 { fronius_ip = viper.GetString("fronius_ip") } - err := CheckEstimate(apiKey, url, fronius_ip) + err := CheckEstimate(e_apiKey, e_url, fronius_ip) if err != nil { u.Log.Error(err) return } - estimate(apiKey, url, fronius_ip) + estimate(e_apiKey, e_url, fronius_ip) }, } func init() { - estCmd.Flags().StringP("url", "u", "", "URL") - estCmd.Flags().StringP("apikey", "k", "", "APIKEY") - estCmd.Flags().StringP("fronius_ip", "H", "", "FRONIUS_IP") + estCmd.Flags().StringVarP(&e_url,"url", "u", "", "set URL") + estCmd.Flags().StringVarP(&e_apiKey,"apikey", "k", "", "set APIKEY") + estCmd.Flags().StringVarP(&fronius_ip,"fronius_ip", "H", "", "set FRONIUS_IP") + viper.BindPFlag("url", estCmd.Flags().Lookup("url")) viper.BindPFlag("apikey", estCmd.Flags().Lookup("apikey")) viper.BindPFlag("fronius_ip", estCmd.Flags().Lookup("fronius_ip")) + rootCmd.AddCommand(estCmd) } @@ -45,7 +50,7 @@ func CheckEstimate(apiKey string, url string, fronius_ip string) error { err := errors.New("the --fronius_ip flag must be set") return err } else if len(strings.TrimSpace(apiKey)) == 0 { - err := errors.New("the --apiKey flag must be set") + err := errors.New("the --apikey flag must be set") return err } else if len(strings.TrimSpace(url)) == 0 { err := errors.New("the --url flag must be set") @@ -55,7 +60,7 @@ func CheckEstimate(apiKey string, url string, fronius_ip string) error { } func estimate(apiKey string, url string, fronius_ip string) { - pwr := power.New() + pwr := pw.New() _, err := pwr.Handler(apiKey, url) if err != nil { u.Log.Error(err) diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go index c6e40ca..ae0802c 100644 --- a/pkg/cmd/root.go +++ b/pkg/cmd/root.go @@ -8,6 +8,9 @@ import ( "github.com/spf13/viper" ) + +var fronius_ip string + var rootCmd = &cobra.Command{ Use: "sbam", Short: "sbam", diff --git a/pkg/cmd/schedule.go b/pkg/cmd/schedule.go index 8caf75c..1b46f0e 100644 --- a/pkg/cmd/schedule.go +++ b/pkg/cmd/schedule.go @@ -6,7 +6,7 @@ import ( "os" "os/signal" "sbam/pkg/fronius" - "sbam/pkg/power" + pw "sbam/pkg/power" "sbam/pkg/storage" u "sbam/src/utils" "strconv" @@ -19,49 +19,97 @@ import ( "github.com/spf13/viper" ) +var s_apiKey string +var s_url string +var pw_consumption float64 +var start_hr string +var end_hr string +var max_charge float64 +var pw_batt_reserve float64 +var crontab string +var s_defaults bool + +const ( + const_pc = 0.0 + const_sh = "00:00" + const_eh = "05:55" + const_mc = 3500 + const_pbr = 0 + const_ct = "0 0 0 0 0" +) + + var scdCmd = &cobra.Command{ Use: "schedule", Short: "Schedule Battery Storage Charge", Long: `Workflow to Check Forecast and Battery residual Capacity and decide if it has to be charged in a definited time range`, Run: func(cmd *cobra.Command, args []string) { - url := viper.GetString("url") - apiKey := viper.GetString("apikey") - fronius_ip := viper.GetString("fronius_ip") - pw_consumption := viper.GetFloat64("pw_consumption") - start_hr := viper.GetString("start_hr") - end_hr := viper.GetString("end_hr") - max_charge := viper.GetFloat64("max_charge") - pw_batt_reserve := viper.GetFloat64("pw_batt_reserve") - crontab := viper.GetString("crontab") - defaults := viper.GetBool("defaults") - - err := checkScheduleschedule(crontab, apiKey, url, fronius_ip, pw_consumption, max_charge, pw_batt_reserve, start_hr, end_hr) + if len(s_url) == 0 {s_url = viper.GetString("url")} + if len(s_apiKey) == 0 {s_apiKey = viper.GetString("apikey")} + if len(fronius_ip) == 0 {fronius_ip = viper.GetString("fronius_ip")} + if pw_consumption == const_pc { + if _, exists := os.LookupEnv("PW_CONSUMPTION"); exists { + pw_consumption= viper.GetFloat64("pw_consumption") + } + } + if start_hr == const_sh { + if _, exists := os.LookupEnv("START_HR"); exists { + start_hr = viper.GetString("start_hr") + } + } + if end_hr == const_eh { + if _, exists := os.LookupEnv("END_HR"); exists { + start_hr = viper.GetString("end_hr") + } + } + if max_charge == const_mc { + if _, exists := os.LookupEnv("MAX_CHARGE"); exists { + max_charge = viper.GetFloat64("max_charge") + } + } + if pw_batt_reserve == const_pbr { + if _, exists := os.LookupEnv("PW_BATT_RESERVE"); exists { + pw_batt_reserve = viper.GetFloat64("pw_batt_reserve") + } + } + if crontab == const_ct { + if _, exists := os.LookupEnv("CRONTAB"); exists { + crontab = viper.GetString("crontab") + } + } + if s_defaults { + if _, exists := os.LookupEnv("DEFAULTS"); exists { + s_defaults = viper.GetBool("defaults") + } + } + + err := checkScheduleschedule(crontab, s_apiKey, s_url, fronius_ip, pw_consumption, max_charge, pw_batt_reserve, start_hr, end_hr) if err != nil { u.Log.Error(err) return } if crontab != "0 0 0 0 0" { - crontabSchedule(apiKey, url, fronius_ip, pw_consumption, max_charge, pw_batt_reserve, start_hr, end_hr, crontab, defaults) + crontabSchedule(s_apiKey, s_url, fronius_ip, pw_consumption, max_charge, pw_batt_reserve, start_hr, end_hr, crontab, s_defaults) } else { - schedule(apiKey, url, fronius_ip, pw_consumption, max_charge, pw_batt_reserve, start_hr, end_hr) + schedule(s_apiKey, s_url, fronius_ip, pw_consumption, max_charge, pw_batt_reserve, start_hr, end_hr) } }, } func init() { - scdCmd.Flags().StringP("url", "u", "", "URL") - scdCmd.Flags().StringP("apikey", "k", "", "APIKEY") - scdCmd.Flags().StringP("fronius_ip", "H", "", "FRONIUS_IP") - scdCmd.Flags().StringP("start_hr", "s", "00:00", "START_HR") - scdCmd.Flags().StringP("end_hr", "e", "05:55", "END_HR") - scdCmd.Flags().StringP("crontab", "t", "0 0 0 0 0", "crontab") - scdCmd.Flags().Float64P("pw_consumption", "c", 0.0, "PW_CONSUMPTION") - scdCmd.Flags().Float64P("max_charge", "m", 3500, "MAX_CHARGE") - scdCmd.Flags().Float64P("pw_batt_reserve", "r", 0, "PW_BATT_RESERVE") - scdCmd.Flags().BoolP("defaults", "d", true, "DEFAULTS") + scdCmd.Flags().StringVarP(&s_url,"url", "u", "", "URL") + scdCmd.Flags().StringVarP(&s_apiKey,"apikey", "k", "", "APIKEY") + scdCmd.Flags().StringVarP(&fronius_ip,"fronius_ip", "H", "", "FRONIUS_IP") + scdCmd.Flags().StringVarP(&start_hr,"start_hr", "s", const_sh, "START_HR") + scdCmd.Flags().StringVarP(&end_hr,"end_hr", "e", const_eh, "END_HR") + scdCmd.Flags().StringVarP(&crontab,"crontab", "t", const_ct, "CRONTAB") + scdCmd.Flags().Float64VarP(&pw_consumption,"pw_consumption", "c", const_pc, "PW_CONSUMPTION") + scdCmd.Flags().Float64VarP(&max_charge,"max_charge", "m", const_mc, "MAX_CHARGE") + scdCmd.Flags().Float64VarP(&pw_batt_reserve,"pw_batt_reserve", "r", const_pbr, "PW_BATT_RESERVE") + scdCmd.Flags().BoolVarP(&s_defaults,"defaults", "d", true, "DEFAULTS") viper.BindPFlag("url", scdCmd.Flags().Lookup("url")) viper.BindPFlag("apikey", scdCmd.Flags().Lookup("apikey")) @@ -156,7 +204,7 @@ func schedule(apiKey string, url string, fronius_ip string, pw_consumption float if !CheckTimeRange(start_hr, end_hr) { u.Log.Info("not in time range: " + start_hr + " <= t <= " + end_hr) } else { - pwr := power.New() + pwr := pw.New() solarPowerProduction, err := pwr.Handler(apiKey, url) if err != nil { u.Log.Error(err)