diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d501418..9a61233 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,9 +7,11 @@ on: permissions: contents: write + packages: write + id-token: write jobs: - goreleaser: + release: runs-on: ubuntu-latest steps: - name: Checkout @@ -25,4 +27,21 @@ jobs: version: latest args: release --clean env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" \ No newline at end of file + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + - name: copy binary to local ha folder + run: | + mkdir home-assistant/addons/sbam/bin/ + cp -v dist/sbam_linux_amd64_v1/bin/sbam home-assistant/addons/sbam/bin/ + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Publish build - Home Assistant builder + uses: home-assistant/builder@2024.01.0 + with: + args: | + --amd64 \ + --target /data/home-assistant/addons/sbam \ + --addon \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8c5ed2d..2ddef7c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,7 @@ *.so *.dylib bin/ - +home-assistant/addons/sbam/bin/ # Test binary, built with `go test -c` *.test diff --git a/.goreleaser.yml b/.goreleaser.yml index 00be91c..71ab971 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -7,6 +7,7 @@ builds: binary: bin/sbam env: - CGO_ENABLED=0 + changelog: sort: asc filters: diff --git a/README.md b/README.md index f2b234a..4e8b652 100644 --- a/README.md +++ b/README.md @@ -63,14 +63,16 @@ Usage: sbam schedule [flags] Flags: - -k, --apikey string APIKEY - -e, --end_hr string END_HR (default "06:00") - -H, --fronius_ip string FRONIUS_IP - -h, --help help for schedule - -m, --max_charge float MAX_CHARGE (default 3500) + -k, --apikey string APIKEY + -t, --crontab string crontab (default "0 0 0 0 0") + -d, --defaults DEFAULTS (default true) + -e, --end_hr string END_HR (default "05:55") + -H, --fronius_ip string FRONIUS_IP + -h, --help help for schedule + -m, --max_charge float MAX_CHARGE (default 3500) -r, --pw_batt_reserve float PW_BATT_RESERVE - -c, --pw_consumption float PW_CONSUMPTION - -s, --start_hr string START_HR (default "00:00") - -u, --url string URL + -c, --pw_consumption float PW_CONSUMPTION + -s, --start_hr string START_HR (default "00:00") + -u, --url string URL ``` \ No newline at end of file diff --git a/go.mod b/go.mod index 7a7a7dc..5a50e74 100644 --- a/go.mod +++ b/go.mod @@ -33,6 +33,7 @@ require ( require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/robfig/cron/v3 v3.0.1 github.com/simonvetter/modbus v1.6.0 github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.18.2 diff --git a/go.sum b/go.sum index 2540ba5..89b3688 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,8 @@ github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdU github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= diff --git a/config.yml b/ha similarity index 100% rename from config.yml rename to ha diff --git a/home-assistant/addons/sbam/CHANGELOG.md b/home-assistant/addons/sbam/CHANGELOG.md new file mode 100644 index 0000000..eef665f --- /dev/null +++ b/home-assistant/addons/sbam/CHANGELOG.md @@ -0,0 +1 @@ +[sbam](https://github.com/atbore-phx/sbam/releases/latest) \ No newline at end of file diff --git a/home-assistant/addons/sbam/DOCS.md b/home-assistant/addons/sbam/DOCS.md new file mode 100644 index 0000000..68711f4 --- /dev/null +++ b/home-assistant/addons/sbam/DOCS.md @@ -0,0 +1 @@ +[sbam](https://github.com/atbore-phx/sbam) \ No newline at end of file diff --git a/home-assistant/addons/sbam/Dockerfile b/home-assistant/addons/sbam/Dockerfile new file mode 100644 index 0000000..4affba1 --- /dev/null +++ b/home-assistant/addons/sbam/Dockerfile @@ -0,0 +1,11 @@ +ARG BUILD_FROM +FROM $BUILD_FROM + +# Copy data for add-on +COPY run.sh / +RUN chmod a+x /run.sh + +COPY bin/sbam /usr/bin/ +RUN chmod a+x /usr/bin/sbam + +CMD [ "/run.sh" ] \ No newline at end of file diff --git a/home-assistant/addons/sbam/README.md b/home-assistant/addons/sbam/README.md new file mode 100644 index 0000000..68711f4 --- /dev/null +++ b/home-assistant/addons/sbam/README.md @@ -0,0 +1 @@ +[sbam](https://github.com/atbore-phx/sbam) \ No newline at end of file diff --git a/home-assistant/addons/sbam/build.json b/home-assistant/addons/sbam/build.json new file mode 100644 index 0000000..ad28876 --- /dev/null +++ b/home-assistant/addons/sbam/build.json @@ -0,0 +1,5 @@ +{ + "build_from": { + "amd64": "ghcr.io/home-assistant/amd64-base:3.19" + } +} \ No newline at end of file diff --git a/home-assistant/addons/sbam/config.json b/home-assistant/addons/sbam/config.json new file mode 100644 index 0000000..6d7f634 --- /dev/null +++ b/home-assistant/addons/sbam/config.json @@ -0,0 +1,36 @@ +{ + "name": "sbam", + "version": "latest", + "slug": "sbam", + "init": "false", + "description": "Smart Battery Avanced Manager", + "arch": [ + "amd64" + ], + "url": "https://github.com/atbore-phx/sbam", + "image": "ghcr.io/atbore-phx/ha-sbam", + "options": { + "url": "https://api.solcast.com.au/rooftop_sites//forecasts?format=json", + "apikey": "", + "fronius_ip": "", + "start_hr": "00:00", + "end_hr": "06:00", + "crontab": "00 00-05 * * *", + "pw_consumption": "11000", + "max_charge": "3500", + "pw_batt_reserve": "4000", + "defaults": "true" + }, + "schema": { + "url": "str", + "apikey": "password", + "fronius_ip": "match(^((25[0-5]|(2[0-4]|1\\d|[1-9]|)\\d)(\\.(?!$)|$)){4}$)", + "start_hr": "match(^([01]?[0-9]|2[0-3]):[0-5][0-9]$)", + "end_hr": "match(^([01]?[0-9]|2[0-3]):[0-5][0-9]$)", + "crontab": "match(^((((\\d+,)+\\d+|(\\d+(\/|-|#)\\d+)|\\d+L?|\\*(\/\\d+)?|L(-\\d+)?|\\?|[A-Z]{3}(-[A-Z]{3})?) ?){5,7})|(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\\d+(ns|us|µs|ms|s|m|h))+)$)", + "pw_consumption": "float", + "max_charge": "float", + "pw_batt_reserve": "float", + "defaults": "bool" + } +} \ No newline at end of file diff --git a/home-assistant/addons/sbam/icon.png b/home-assistant/addons/sbam/icon.png new file mode 100644 index 0000000..952753e Binary files /dev/null and b/home-assistant/addons/sbam/icon.png differ diff --git a/home-assistant/addons/sbam/logo.png b/home-assistant/addons/sbam/logo.png new file mode 100644 index 0000000..ef7c0e3 Binary files /dev/null and b/home-assistant/addons/sbam/logo.png differ diff --git a/home-assistant/addons/sbam/run.sh b/home-assistant/addons/sbam/run.sh new file mode 100755 index 0000000..0891333 --- /dev/null +++ b/home-assistant/addons/sbam/run.sh @@ -0,0 +1,14 @@ +#!/usr/bin/with-contenv bashio + +export URL=$(bashio::config 'url') +export APIKEY=$(bashio::config 'apikey') +export FRONIUS_IP=$(bashio::config 'fronius_ip') +export START_HR=$(bashio::config 'start_hr') +export END_HR=$(bashio::config 'end_hr') +export CRONTAB=$(bashio::config 'crontab') +export PW_CONSUMPTION=$(bashio::config 'pw_consumption') +export MAX_CHARGE=$(bashio::config 'max_charge') +export PW_BATT_RESERVE=$(bashio::config 'pw_batt_reserve') +export DEFAULTS=$(bashio::config 'defaults') + +sbam schedule \ No newline at end of file diff --git a/home-assistant/addons/test_local.sh b/home-assistant/addons/test_local.sh new file mode 100755 index 0000000..294dfc4 --- /dev/null +++ b/home-assistant/addons/test_local.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +BUILDCONTAINER_DATA_PATH="/data" +PATHTOBUILD="$BUILDCONTAINER_DATA_PATH" +ARCH=amd64 + + +PROJECTDIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )/sbam +ROOTDIR=$PROJECTDIR/../../../ +cd $PRROOTDIROJECTDIR/../../../ +make build +cd - + + +rm -rf $PROJECTDIR/bin +mkdir -p $PROJECTDIR/bin +cp $ROOTDIR/bin/sbam $PROJECTDIR/bin/ + +echo "project directory is $PROJECTDIR" +echo "build container data path is $BUILDCONTAINER_DATA_PATH" +echo "build container target build path is $PATHTOBUILD" +CMD="docker run --rm -ti --name hassio-builder --privileged -v $PROJECTDIR:$BUILDCONTAINER_DATA_PATH -v /var/run/docker.sock:/var/run/docker.sock:ro homeassistant/amd64-builder --target $PATHTOBUILD --$ARCH --test --docker-hub local" +echo "$CMD" +$CMD \ No newline at end of file diff --git a/pkg/cmd/configure.go b/pkg/cmd/configure.go index dc3076a..16ed45a 100644 --- a/pkg/cmd/configure.go +++ b/pkg/cmd/configure.go @@ -1,8 +1,9 @@ package cmd import ( - "fmt" + "errors" "sbam/pkg/fronius" + u "sbam/src/utils" "strings" "github.com/spf13/cobra" @@ -15,20 +16,15 @@ var cfgCmd = &cobra.Command{ Long: `connect via modbus to the fronius inverter and set charging`, Run: func(cmd *cobra.Command, args []string) { fronius_ip := viper.GetString("fronius_ip") - if len(strings.TrimSpace(fronius_ip)) == 0 { - fmt.Println("The --fronius_ip flag must be set") + power := viper.GetViper().GetInt("power") + + err := checkConfigure(fronius_ip) + if err != nil { + u.Log.Error(err) return } - if cmd.Flags().Changed("defaults") { - fronius.Setdefaults(fronius_ip) - } else if cmd.Flags().Changed("force-charge") { - power := viper.GetViper().GetInt("power") - if power == 0 { - fmt.Println("The --power flag must be set when using --force-charge") - return - } - fronius.ForceCharge(fronius_ip, int16(power)) - } + + configure(fronius_ip, power, cmd) }, } @@ -42,3 +38,32 @@ func init() { viper.BindPFlag("power", cfgCmd.Flags().Lookup("power")) rootCmd.AddCommand(cfgCmd) } + +func checkConfigure(fronius_ip string) error { + if len(strings.TrimSpace(fronius_ip)) == 0 { + err := errors.New("the --fronius_ip flag must be set") + return err + } + return nil +} + +func configure(fronius_ip string, power int, cmd *cobra.Command) { + if cmd.Flags().Changed("defaults") { + err := fronius.Setdefaults(fronius_ip) + if err != nil { + u.Log.Error(err) + panic(err) + } + } else if cmd.Flags().Changed("force-charge") { + if power == 0 { + u.Log.Error("The --power flag must be set when using --force-charge") + return + } + err := fronius.ForceCharge(fronius_ip, int16(power)) + if err != nil { + u.Log.Error(err) + panic(err) + } + } + +} diff --git a/pkg/cmd/estimate.go b/pkg/cmd/estimate.go index 2978ddd..b846c62 100644 --- a/pkg/cmd/estimate.go +++ b/pkg/cmd/estimate.go @@ -1,9 +1,10 @@ package cmd import ( - "fmt" + "errors" "sbam/pkg/power" "sbam/pkg/storage" + u "sbam/src/utils" "strings" "github.com/spf13/cobra" @@ -18,28 +19,14 @@ var estCmd = &cobra.Command{ url := viper.GetString("url") apiKey := viper.GetString("apikey") fronius_ip := viper.GetString("fronius_ip") - if len(strings.TrimSpace(fronius_ip)) == 0 { - fmt.Println("The --fronius_ip flag must be set") - return - } else if len(strings.TrimSpace(apiKey)) == 0 { - fmt.Println("The --apiKey flag must be set") - return - } else if len(strings.TrimSpace(url)) == 0 { - fmt.Println("The --url flag must be set") - return - } - pwr := power.New() - _, err := pwr.Handler(apiKey, url) + err := CheckEstimate(apiKey, url, fronius_ip) if err != nil { - panic(err) + u.Log.Error(err) + return } + estimate(apiKey, url, fronius_ip) - str := storage.New() - _, _, err = str.Handler(fronius_ip) - if err != nil { - panic(err) - } }, } @@ -52,3 +39,33 @@ func init() { viper.BindPFlag("fronius_ip", estCmd.Flags().Lookup("fronius_ip")) rootCmd.AddCommand(estCmd) } + +func CheckEstimate(apiKey string, url string, fronius_ip string) error { + if len(strings.TrimSpace(fronius_ip)) == 0 { + 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") + return err + } else if len(strings.TrimSpace(url)) == 0 { + err := errors.New("the --url flag must be set") + return err + } + return nil +} + +func estimate(apiKey string, url string, fronius_ip string) { + pwr := power.New() + _, err := pwr.Handler(apiKey, url) + if err != nil { + u.Log.Error(err) + panic(err) + } + + str := storage.New() + _, _, err = str.Handler(fronius_ip) + if err != nil { + u.Log.Error(err) + panic(err) + } +} diff --git a/pkg/cmd/schedule.go b/pkg/cmd/schedule.go index aaa720b..8caf75c 100644 --- a/pkg/cmd/schedule.go +++ b/pkg/cmd/schedule.go @@ -1,14 +1,20 @@ package cmd import ( + "errors" "fmt" + "os" + "os/signal" "sbam/pkg/fronius" "sbam/pkg/power" "sbam/pkg/storage" u "sbam/src/utils" + "strconv" "strings" + "syscall" "time" + "github.com/robfig/cron/v3" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -26,38 +32,21 @@ var scdCmd = &cobra.Command{ 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") - if len(strings.TrimSpace(fronius_ip)) == 0 { - fmt.Println("The --fronius_ip flag must be set") - return - } else if len(strings.TrimSpace(apiKey)) == 0 { - fmt.Println("The --apiKey flag must be set") - return - } else if len(strings.TrimSpace(url)) == 0 { - fmt.Println("The --url flag must be set") - return - } else if !isStartBeforeEnd(start_hr, end_hr) { - fmt.Printf("start_hr %s is not before end_hr %s", start_hr, end_hr) + err := checkScheduleschedule(crontab, apiKey, url, fronius_ip, pw_consumption, max_charge, pw_batt_reserve, start_hr, end_hr) + if err != nil { + u.Log.Error(err) return } - pwr := power.New() - solarPowerProduction, err := pwr.Handler(apiKey, url) - if err != nil { - panic(err) - } + 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) - str := storage.New() - capacity2charge, capacity_max, err := str.Handler(fronius_ip) - if err != nil { - panic(err) - } - u.Log.Infof("your Daily consumption is:%d W", int(pw_consumption)) + } else { + schedule(apiKey, url, fronius_ip, pw_consumption, max_charge, pw_batt_reserve, start_hr, end_hr) - scd := fronius.New() - _, err = scd.Handler(solarPowerProduction, capacity2charge, capacity_max, pw_consumption, max_charge, pw_batt_reserve, start_hr, end_hr, fronius_ip) - if err != nil { - panic(err) } }, } @@ -67,10 +56,12 @@ func init() { 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", "06:00", "END_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") viper.BindPFlag("url", scdCmd.Flags().Lookup("url")) viper.BindPFlag("apikey", scdCmd.Flags().Lookup("apikey")) @@ -78,8 +69,10 @@ func init() { viper.BindPFlag("pw_consumption", scdCmd.Flags().Lookup("pw_consumption")) viper.BindPFlag("start_hr", scdCmd.Flags().Lookup("start_hr")) viper.BindPFlag("end_hr", scdCmd.Flags().Lookup("end_hr")) + viper.BindPFlag("crontab", scdCmd.Flags().Lookup("crontab")) viper.BindPFlag("max_charge", scdCmd.Flags().Lookup("max_charge")) viper.BindPFlag("pw_batt_reserve", scdCmd.Flags().Lookup("pw_batt_reserve")) + viper.BindPFlag("defaults", scdCmd.Flags().Lookup("defaults")) rootCmd.AddCommand(scdCmd) } @@ -104,3 +97,115 @@ func isStartBeforeEnd(start, end string) bool { // Compare the times return startTime.Before(endTime) } + +func CheckTimeRange(start_hr string, end_hr string) bool { + now := time.Now() + + layout := "15:04" + startTime, err := time.Parse(layout, start_hr) + if err != nil { + u.Log.Error("Something goes wrong parsing start time") + panic(err) + } + + endTime, err := time.Parse(layout, end_hr) + if err != nil { + u.Log.Error("Something goes wrong parsing end time") + panic(err) + } + + // Convert the current time to a time.Time value for today's date with the hour and minute set to the parsed start and end times + startTime = time.Date(now.Year(), now.Month(), now.Day(), startTime.Hour(), startTime.Minute(), 0, 0, now.Location()) + endTime = time.Date(now.Year(), now.Month(), now.Day(), endTime.Hour(), endTime.Minute(), 0, 0, now.Location()) + + return (now.After(startTime) || now.Equal(startTime)) && (now.Before(endTime) || now.Equal(endTime)) +} + +func checkScheduleschedule(crontab string, apiKey string, url string, fronius_ip string, pw_consumption float64, max_charge float64, pw_batt_reserve float64, start_hr string, end_hr string) error { + if len(strings.TrimSpace(fronius_ip)) == 0 { + 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") + return err + } else if len(strings.TrimSpace(url)) == 0 { + err := errors.New("the --url flag must be set") + return err + } else if !isStartBeforeEnd(start_hr, end_hr) { + err := errors.New("start_hr: " + start_hr + " is not before end_hr: " + end_hr) + return err + } else if len(crontab) == 0 { + fmt.Printf("the --crontab must be set") + err := errors.New("crontab must to be integer > 0") + return err + } else if pw_consumption < 0 { + err := errors.New("pw_consumption must to be float > 0") + return err + } else if max_charge < 0 { + err := errors.New("max_charge must to be float > 0") + return err + } else if pw_batt_reserve < 0 { + err := errors.New("pw_batt_reserve must to be float > 0") + return err + } + + return nil +} + +func schedule(apiKey string, url string, fronius_ip string, pw_consumption float64, max_charge float64, pw_batt_reserve float64, start_hr string, end_hr string) { + if !CheckTimeRange(start_hr, end_hr) { + u.Log.Info("not in time range: " + start_hr + " <= t <= " + end_hr) + } else { + pwr := power.New() + solarPowerProduction, err := pwr.Handler(apiKey, url) + if err != nil { + u.Log.Error(err) + panic(err) + } + + str := storage.New() + capacity2charge, capacity_max, err := str.Handler(fronius_ip) + if err != nil { + u.Log.Error(err) + panic(err) + } + u.Log.Infof("your Daily consumption is:%d W", int(pw_consumption)) + + scd := fronius.New() + _, err = scd.Handler(solarPowerProduction, capacity2charge, capacity_max, pw_consumption, max_charge, pw_batt_reserve, start_hr, end_hr, fronius_ip) + if err != nil { + u.Log.Error(err) + panic(err) + } + } +} + +func crontabSchedule(apiKey string, url string, fronius_ip string, pw_consumption float64, max_charge float64, pw_batt_reserve float64, start_hr string, end_hr string, crontab string, defaults bool) { + layout := "15:04" + endTime, _ := time.Parse(layout, end_hr) + endTime = endTime.Add(-5 * time.Minute) + end_crontab := strconv.Itoa(endTime.Minute()) + " " + strconv.Itoa(endTime.Hour()) + " * * *" + + c := cron.New() + _, err := c.AddFunc(crontab, func() { + schedule(apiKey, url, fronius_ip, pw_consumption, max_charge, pw_batt_reserve, start_hr, end_hr) + }) + if err != nil { + u.Log.Error(err) + panic(err) + } + if defaults { + _, err = c.AddFunc(end_crontab, func() { + fronius.Setdefaults(fronius_ip) + }) + if err != nil { + u.Log.Error(err) + panic(err) + } + } + c.Start() + done := make(chan os.Signal, 1) + signal.Notify(done, syscall.SIGINT, syscall.SIGTERM) + fmt.Println("Running, press ctrl+c to exit...") + <-done // Will block here until user hits ctrl+c +} diff --git a/pkg/fronius/fronius_test.go b/pkg/fronius/fronius_test.go index aa54627..3179ac7 100644 --- a/pkg/fronius/fronius_test.go +++ b/pkg/fronius/fronius_test.go @@ -193,18 +193,6 @@ func TestSetChargePower(t *testing.T) { } -func TestCheckTimeRange(t *testing.T) { - assert := assert.New(t) - - isInRange, err := fronius.CheckTimeRange("00:00", "23:59") - assert.NoError(err, "CheckTimeRange returned an error") - assert.True(isInRange, "CheckTimeRange returned false when it should return true") - - isInRange, err = fronius.CheckTimeRange("23:59", "00:00") - assert.NoError(err, "CheckTimeRange returned an error") - assert.False(isInRange, "CheckTimeRange returned true when it should return false") -} - func TestBatteryChargeMode1(t *testing.T) { assert := assert.New(t) setup() @@ -274,28 +262,6 @@ func TestBatteryChargeError(t *testing.T) { assert := assert.New(t) setup() - result, err := fronius.SetFroniusChargeBatteryMode(1000, 11000, 11000, 9000, 3500, 2500, "25:59", "00:00", modbus_ip, modbus_port) - assert.Equal(int16(0), result, "SetFroniusChargeBatteryMode returned wrong value") - assert.Error(err) - - teardown() -} - -func TestBatteryChargeError2(t *testing.T) { - assert := assert.New(t) - setup() - - result, err := fronius.SetFroniusChargeBatteryMode(1000, 11000, 11000, 9000, 3500, 2500, "00:00", "25:00", modbus_ip, modbus_port) - assert.Equal(int16(0), result, "SetFroniusChargeBatteryMode returned wrong value") - assert.Error(err) - - teardown() -} - -func TestBatteryChargeError3(t *testing.T) { - assert := assert.New(t) - setup() - result, err := fronius.SetFroniusChargeBatteryMode(1000, 11000, -11000, 9000, 3500, 0, "00:00", "23:59", modbus_ip, modbus_port) assert.Equal(int16(-200), result, "SetFroniusChargeBatteryMode returned wrong value") assert.Error(err) diff --git a/pkg/fronius/schedule.go b/pkg/fronius/schedule.go index 647449d..8f7a9dc 100644 --- a/pkg/fronius/schedule.go +++ b/pkg/fronius/schedule.go @@ -2,7 +2,6 @@ package fronius import ( u "sbam/src/utils" - "time" ) func SetFroniusChargeBatteryMode(pw_forecast float64, pw_batt2charge float64, pw_batt_max float64, pw_consumption float64, max_charge float64, pw_batt_reserve float64, start_hr string, end_hr string, fronius_ip string, fronius_port ...string) (int16, error) { @@ -14,14 +13,7 @@ func SetFroniusChargeBatteryMode(pw_forecast float64, pw_batt2charge float64, pw pw_pv_net := pw_forecast - pw_consumption // Net solar power pw_batt := pw_batt_max - pw_batt2charge // actual battery power - time, err := CheckTimeRange(start_hr, end_hr) - if err != nil { - u.Log.Errorln("Error checking time range: %s ", err) - return ch_pc, err - } switch { - case !time: // out of the time range => do not charge - u.Log.Infof("Out time range start_time: %s - end_time: %s", start_hr, end_hr) case pw_batt2charge == 0: // battery 100% => do not charge u.Log.Info("Battery is full charged") case pw_batt < pw_batt_reserve: // battery is less than reserve => charge @@ -75,26 +67,3 @@ func ChargeBattery(pw_pv_net float64, pw_batt float64) (float64, bool) { return pw_grid, enabled } - -func CheckTimeRange(start_hr string, end_hr string) (bool, error) { - now := time.Now() - - layout := "15:04" - startTime, err := time.Parse(layout, start_hr) - if err != nil { - u.Log.Error("Something goes wrong parsing start time") - return false, err - } - - endTime, err := time.Parse(layout, end_hr) - if err != nil { - u.Log.Error("Something goes wrong parsing end time") - return false, err - } - - // Convert the current time to a time.Time value for today's date with the hour and minute set to the parsed start and end times - startTime = time.Date(now.Year(), now.Month(), now.Day(), startTime.Hour(), startTime.Minute(), 0, 0, now.Location()) - endTime = time.Date(now.Year(), now.Month(), now.Day(), endTime.Hour(), endTime.Minute(), 0, 0, now.Location()) - - return (now.After(startTime) || now.Equal(startTime)) && (now.Before(endTime) || now.Equal(endTime)), nil -} diff --git a/repository.json b/repository.json new file mode 100644 index 0000000..2718285 --- /dev/null +++ b/repository.json @@ -0,0 +1,5 @@ +{ + "name": "sbam Smart Battery Manager", + "url": "https://github.com/atbore-phx/sbam", + "maintainer": "atbore-phx" +} \ No newline at end of file