Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update [email protected] #158

Merged
merged 1 commit into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion garden-app/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.21.3

require (
github.com/AlecAivazis/survey/v2 v2.3.7
github.com/calvinmclean/babyapi v0.10.0
github.com/calvinmclean/babyapi v0.12.0
github.com/eclipse/paho.mqtt.golang v1.4.3
github.com/go-chi/render v1.0.3
github.com/go-co-op/gocron v1.35.2
Expand Down
4 changes: 2 additions & 2 deletions garden-app/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE=
github.com/bytedance/sonic v1.10.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
github.com/calvinmclean/babyapi v0.10.0 h1:kZQMeaCqcaxHdijq7qkRQ+xl2itqMqFrco0OjbqAUV0=
github.com/calvinmclean/babyapi v0.10.0/go.mod h1:XVUTIRu0bqXTfx7aUY66YXZUZeIGkNn8GeK+8DpJ59k=
github.com/calvinmclean/babyapi v0.12.0 h1:yisOOKKrZdsmhpSG3gYu6/8OGUrEHCvn+KoYtXTN/qE=
github.com/calvinmclean/babyapi v0.12.0/go.mod h1:XVUTIRu0bqXTfx7aUY66YXZUZeIGkNn8GeK+8DpJ59k=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
Expand Down
14 changes: 7 additions & 7 deletions garden-app/pkg/storage/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/calvinmclean/automated-garden/garden-app/pkg/weather"

"github.com/calvinmclean/babyapi"
"github.com/calvinmclean/babyapi/storage"
"github.com/calvinmclean/babyapi/storage/kv"
"github.com/madflojo/hord"
"github.com/madflojo/hord/drivers/hashmap"
"github.com/madflojo/hord/drivers/redis"
Expand All @@ -34,10 +34,10 @@ func NewClient(config Config) (*Client, error) {
}

return &Client{
Gardens: storage.NewClient[*pkg.Garden](db, "Garden"),
Zones: storage.NewClient[*pkg.Zone](db, "Zone"),
WaterSchedules: storage.NewClient[*pkg.WaterSchedule](db, "WaterSchedule"),
WeatherClientConfigs: storage.NewClient[*weather.Config](db, "WeatherClient"),
Gardens: kv.NewClient[*pkg.Garden](db, "Garden"),
Zones: kv.NewClient[*pkg.Zone](db, "Zone"),
WaterSchedules: kv.NewClient[*pkg.WaterSchedule](db, "WaterSchedule"),
WeatherClientConfigs: kv.NewClient[*weather.Config](db, "WeatherClient"),
}, nil
}

Expand All @@ -52,14 +52,14 @@ func newHordDB(config Config) (hord.Database, error) {
if err != nil {
return nil, fmt.Errorf("error decoding config: %w", err)
}
return storage.NewFileDB(cfg)
return kv.NewFileDB(cfg)
case "redis":
var cfg redis.Config
err := mapstructure.Decode(config.Options, &cfg)
if err != nil {
return nil, fmt.Errorf("error decoding config: %w", err)
}
return storage.NewRedisDB(cfg)
return kv.NewRedisDB(cfg)
default:
return nil, fmt.Errorf("invalid KV driver: %q", config.Driver)
}
Expand Down
16 changes: 10 additions & 6 deletions garden-app/pkg/storage/water_schedules.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
package storage

import (
"context"
"fmt"

"github.com/calvinmclean/automated-garden/garden-app/pkg"
"github.com/calvinmclean/babyapi"
)

// GetZonesUsingWaterSchedule will find all Zones that use this WaterSchedule and return the Zones along with the Gardens they belong to
func (c *Client) GetZonesUsingWaterSchedule(id string) ([]*pkg.ZoneAndGarden, error) {
gardens, err := c.Gardens.GetAll(FilterEndDated[*pkg.Garden](false))
gardens, err := c.Gardens.GetAll(context.Background(), nil)
if err != nil {
return nil, fmt.Errorf("unable to get all Gardens: %w", err)
}
gardens = FilterEndDated[*pkg.Garden](false).Filter(gardens)

results := []*pkg.ZoneAndGarden{}
for _, g := range gardens {
zones, err := c.Zones.GetAll(func(z *pkg.Zone) bool {
zones, err := c.Zones.GetAll(context.Background(), nil)
if err != nil {
return nil, fmt.Errorf("unable to get all Zones for Garden %q: %w", g.ID, err)

Check warning on line 23 in garden-app/pkg/storage/water_schedules.go

View check run for this annotation

Codecov / codecov/patch

garden-app/pkg/storage/water_schedules.go#L23

Added line #L23 was not covered by tests
}
zones = babyapi.FilterFunc[*pkg.Zone](func(z *pkg.Zone) bool {
if z.GardenID != g.ID.ID || z.EndDated() {
return false
}
Expand All @@ -25,10 +32,7 @@
}
}
return false
})
if err != nil {
return nil, fmt.Errorf("unable to get all Zones for Garden %q: %w", g.ID, err)
}
}).Filter(zones)

for _, z := range zones {
results = append(results, &pkg.ZoneAndGarden{Zone: z, Garden: g})
Expand Down
17 changes: 10 additions & 7 deletions garden-app/pkg/storage/weather_clients.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package storage

import (
"context"
"fmt"

"github.com/calvinmclean/automated-garden/garden-app/pkg"
"github.com/calvinmclean/automated-garden/garden-app/pkg/weather"
"github.com/calvinmclean/babyapi"
"github.com/rs/xid"
)

// GetWeatherClient ...
func (c *Client) GetWeatherClient(id xid.ID) (weather.Client, error) {
clientConfig, err := c.WeatherClientConfigs.Get(id.String())
clientConfig, err := c.WeatherClientConfigs.Get(context.Background(), id.String())
if err != nil {
return nil, fmt.Errorf("error getting weather client config: %w", err)
}
Expand All @@ -21,13 +23,17 @@

return weather.NewClient(clientConfig, func(weatherClientOptions map[string]interface{}) error {
clientConfig.Options = weatherClientOptions
return c.WeatherClientConfigs.Set(clientConfig)
return c.WeatherClientConfigs.Set(context.Background(), clientConfig)

Check warning on line 26 in garden-app/pkg/storage/weather_clients.go

View check run for this annotation

Codecov / codecov/patch

garden-app/pkg/storage/weather_clients.go#L26

Added line #L26 was not covered by tests
})
}

// GetWaterSchedulesUsingWeatherClient will return all WaterSchedules that rely on this WeatherClient
func (c *Client) GetWaterSchedulesUsingWeatherClient(id string) ([]*pkg.WaterSchedule, error) {
waterSchedules, err := c.WaterSchedules.GetAll(func(ws *pkg.WaterSchedule) bool {
waterSchedules, err := c.WaterSchedules.GetAll(context.Background(), nil)
if err != nil {
return nil, fmt.Errorf("unable to get all WaterSchedules: %w", err)

Check warning on line 34 in garden-app/pkg/storage/weather_clients.go

View check run for this annotation

Codecov / codecov/patch

garden-app/pkg/storage/weather_clients.go#L34

Added line #L34 was not covered by tests
}
waterSchedules = babyapi.FilterFunc[*pkg.WaterSchedule](func(ws *pkg.WaterSchedule) bool {
if !ws.HasWeatherControl() {
return false
}
Expand All @@ -38,10 +44,7 @@
return true
}
return false
})
if err != nil {
return nil, fmt.Errorf("unable to get all WaterSchedules: %w", err)
}
}).Filter(waterSchedules)

return waterSchedules, nil
}
17 changes: 10 additions & 7 deletions garden-app/server/garden.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package server

import (
"context"
"errors"
"fmt"
"net/http"
Expand Down Expand Up @@ -40,15 +41,17 @@
}

// Initialize light schedules for all Gardens
allGardens, err := gr.storageClient.Gardens.GetAll(storage.FilterEndDated[*pkg.Garden](false))
allGardens, err := gr.storageClient.Gardens.GetAll(context.Background(), nil)
if err != nil {
return gr, err
}
for _, g := range allGardens {
if g.LightSchedule != nil {
if err = gr.worker.ScheduleLightActions(g); err != nil {
return gr, fmt.Errorf("unable to schedule LightAction for Garden %v: %v", g.ID, err)
}
if g.EndDated() || g.LightSchedule == nil {
continue
}
err = gr.worker.ScheduleLightActions(g)
if err != nil {
return gr, fmt.Errorf("unable to schedule LightAction for Garden %v: %v", g.ID, err)

Check warning on line 54 in garden-app/server/garden.go

View check run for this annotation

Codecov / codecov/patch

garden-app/server/garden.go#L54

Added line #L54 was not covered by tests
}
}

Expand Down Expand Up @@ -98,7 +101,7 @@
gardenID := gr.GetIDParam(r)

// Don't allow end-dating a Garden with active Zones
numZones, err := gr.numZones(gardenID)
numZones, err := gr.numZones(r.Context(), gardenID)
if err != nil {
return babyapi.InternalServerError(fmt.Errorf("error getting number of Zones for garden: %w", err))
}
Expand Down Expand Up @@ -132,7 +135,7 @@
func (gr *GardensAPI) onCreateOrUpdate(r *http.Request, garden *pkg.Garden) *babyapi.ErrResponse {
logger := babyapi.GetLoggerFromContext(r.Context())

numZones, err := gr.numZones(garden.ID.String())
numZones, err := gr.numZones(r.Context(), garden.ID.String())
if err != nil {
return babyapi.InternalServerError(err)
}
Expand Down
20 changes: 11 additions & 9 deletions garden-app/server/garden_responses.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package server

import (
"context"
"fmt"
"net/http"
"slices"
Expand Down Expand Up @@ -57,7 +58,7 @@
zonesPath := fmt.Sprintf("%s/%s%s", gardenBasePath, g.Garden.ID, zoneBasePath)

var err error
g.NumZones, err = g.api.numZones(g.ID.String())
g.NumZones, err = g.api.numZones(r.Context(), g.ID.String())
if err != nil {
return fmt.Errorf("error getting number of Zones for garden: %w", err)
}
Expand Down Expand Up @@ -155,23 +156,24 @@
return gardensPageTemplate.Render(r, agr)
}

func (api *GardensAPI) getAllZones(gardenID string, getEndDated bool) ([]*pkg.Zone, error) {
zones, err := api.storageClient.Zones.GetAll(func(z *pkg.Zone) bool {
func (api *GardensAPI) getAllZones(ctx context.Context, gardenID string, getEndDated bool) ([]*pkg.Zone, error) {
zones, err := api.storageClient.Zones.GetAll(ctx, nil)
if err != nil {
return nil, fmt.Errorf("error getting Zones for Garden: %w", err)

Check warning on line 162 in garden-app/server/garden_responses.go

View check run for this annotation

Codecov / codecov/patch

garden-app/server/garden_responses.go#L162

Added line #L162 was not covered by tests
}
zones = babyapi.FilterFunc[*pkg.Zone](func(z *pkg.Zone) bool {
gardenIDFilter := filterZoneByGardenID(gardenID)
endDateFilter := storage.FilterEndDated[*pkg.Zone](getEndDated)

return gardenIDFilter(z) && endDateFilter(z)
})
if err != nil {
return nil, fmt.Errorf("error getting Zones for Garden: %w", err)
}
}).Filter(zones)

return zones, nil
}

// NumZones returns the number of non-end-dated Zones that are part of this Garden
func (api *GardensAPI) numZones(gardenID string) (uint, error) {
zones, err := api.getAllZones(gardenID, false)
func (api *GardensAPI) numZones(ctx context.Context, gardenID string) (uint, error) {
zones, err := api.getAllZones(ctx, gardenID, false)
if err != nil {
return 0, err
}
Expand Down
15 changes: 8 additions & 7 deletions garden-app/server/garden_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package server

import (
"bytes"
"context"
"errors"
"fmt"
"log/slog"
Expand Down Expand Up @@ -244,7 +245,7 @@ func TestUpdateGardenPUT(t *testing.T) {
assert.NoError(t, err)

garden := createExampleGarden()
err = storageClient.Gardens.Set(garden)
err = storageClient.Gardens.Set(context.Background(), garden)
assert.NoError(t, err)

influxdbClient := new(influxdb.MockClient)
Expand Down Expand Up @@ -298,7 +299,7 @@ func TestGetAllGardens(t *testing.T) {
assert.NoError(t, err)

for _, g := range gardens {
err = storageClient.Gardens.Set(g)
err = storageClient.Gardens.Set(context.Background(), g)
assert.NoError(t, err)
}

Expand Down Expand Up @@ -363,11 +364,11 @@ func TestEndDateGarden(t *testing.T) {
})
assert.NoError(t, err)

err = storageClient.Gardens.Set(tt.garden)
err = storageClient.Gardens.Set(context.Background(), tt.garden)
assert.NoError(t, err)

if tt.zone != nil {
err = storageClient.Zones.Set(tt.zone)
err = storageClient.Zones.Set(context.Background(), tt.zone)
assert.NoError(t, err)
}

Expand Down Expand Up @@ -449,7 +450,7 @@ func TestUpdateGarden(t *testing.T) {
storageClient := setupZoneAndGardenStorage(t)

for _, z := range tt.zones {
err := storageClient.Zones.Set(z)
err := storageClient.Zones.Set(context.Background(), z)
assert.NoError(t, err)
}

Expand Down Expand Up @@ -523,7 +524,7 @@ func TestGardenAction(t *testing.T) {
assert.NoError(t, err)

garden := createExampleGarden()
err = storageClient.Gardens.Set(garden)
err = storageClient.Gardens.Set(context.Background(), garden)
assert.NoError(t, err)

r := httptest.NewRequest("POST", fmt.Sprintf("/gardens/%s/action", garden.ID), strings.NewReader(tt.body))
Expand Down Expand Up @@ -625,7 +626,7 @@ func TestGardenActionForm(t *testing.T) {
assert.NoError(t, err)

garden := createExampleGarden()
err = storageClient.Gardens.Set(garden)
err = storageClient.Gardens.Set(context.Background(), garden)
assert.NoError(t, err)

r := httptest.NewRequest(http.MethodPost, fmt.Sprintf("/gardens/%s/action", garden.ID), bytes.NewBufferString(tt.body))
Expand Down
9 changes: 4 additions & 5 deletions garden-app/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"os/signal"
"syscall"

"github.com/calvinmclean/automated-garden/garden-app/pkg"
"github.com/calvinmclean/automated-garden/garden-app/pkg/influxdb"
"github.com/calvinmclean/automated-garden/garden-app/pkg/mqtt"
"github.com/calvinmclean/automated-garden/garden-app/pkg/storage"
Expand Down Expand Up @@ -156,7 +155,7 @@ func (s *Server) Stop() {

// validateAllStoredResources will read all resources from storage and make sure they are valid for the types
func validateAllStoredResources(storageClient *storage.Client) error {
gardens, err := storageClient.Gardens.GetAll(storage.FilterEndDated[*pkg.Garden](true))
gardens, err := storageClient.Gardens.GetAll(context.Background(), nil)
if err != nil {
return fmt.Errorf("unable to get all Gardens: %w", err)
}
Expand All @@ -171,7 +170,7 @@ func validateAllStoredResources(storageClient *storage.Client) error {
}
}

zones, err := storageClient.Zones.GetAll(nil)
zones, err := storageClient.Zones.GetAll(context.Background(), nil)
if err != nil {
return fmt.Errorf("unable to get all Zones: %w", err)
}
Expand All @@ -186,7 +185,7 @@ func validateAllStoredResources(storageClient *storage.Client) error {
}
}

waterSchedules, err := storageClient.WaterSchedules.GetAll(nil)
waterSchedules, err := storageClient.WaterSchedules.GetAll(context.Background(), nil)
if err != nil {
return fmt.Errorf("unable to get all WaterSchedules: %w", err)
}
Expand All @@ -201,7 +200,7 @@ func validateAllStoredResources(storageClient *storage.Client) error {
}
}

weatherClients, err := storageClient.WeatherClientConfigs.GetAll(nil)
weatherClients, err := storageClient.WeatherClientConfigs.GetAll(context.Background(), nil)
if err != nil {
return fmt.Errorf("unable to get all WeatherClients: %w", err)
}
Expand Down
Loading
Loading