server

package
v0.0.0-...-48f08c5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 15, 2026 License: Apache-2.0 Imports: 41 Imported by: 0

Documentation

Overview

Package server provides the HTTP API server for the garden application

Index

Constants

This section is empty.

Variables

View Source
var ErrNotFoundResponse = &ErrResponse{HTTPStatusCode: 404, StatusText: "Resource not found."}

ErrNotFoundResponse is a basic error response for missing resource

Functions

func DisableMock

func DisableMock()

DisableMock will disable mock IDs and reset the mock clock

func EnableMock

func EnableMock()

EnableMock prepares mock IDs and clock

func ErrInvalidRequest

func ErrInvalidRequest(err error) render.Renderer

ErrInvalidRequest creates a 400 ErrResponse for a bad request

func ErrRender

func ErrRender(err error) render.Renderer

ErrRender creates a 422 response for errors encountered while rendering a response

func InternalServerError

func InternalServerError(err error) render.Renderer

InternalServerError creates a generic 500 error for a server-side error

func NewID

func NewID() babyapi.ID

NewID creates a new unique xid by default, but mocking can be enabled to choose from a consistent list of IDs so results are repeatable

Types

type API

type API struct {
	*babyapi.API[*babyapi.NilResource]
	// contains filtered or unexported fields
}

API contains all HTTP API handling and logic

func NewAPI

func NewAPI() *API

NewAPI intializes an API without any integrations or clients. Use api.Setup(...) before running

func (*API) Setup

func (api *API) Setup(cfg Config, validateData bool) error

Setup will prepare to run by setting up clients and doing any final configurations for the API

type ActiveWatering

type ActiveWatering struct {
	ZoneName string
	Progress pkg.WaterHistoryProgress
}

ActiveWatering contains information about a currently-watering zone

type AllGardensResponse

type AllGardensResponse struct {
	babyapi.ResourceList[*GardenResponse]
}

AllGardensResponse is a simple struct being used to render and return a list of all Gardens

func (AllGardensResponse) HTML

func (AllGardensResponse) Render

type AllNotificationClientsResponse

type AllNotificationClientsResponse struct {
	babyapi.ResourceList[*NotificationClientResponse]
}

AllNotificationClientsResponse wraps a list of notification clients

func (AllNotificationClientsResponse) HTML

HTML renders the settings list for HTMX requests

func (AllNotificationClientsResponse) Render

Render delegates to ResourceList's Render

type AllWaterRoutinesResponse

type AllWaterRoutinesResponse struct {
	babyapi.ResourceList[*WaterRoutineResponse]
}

AllWaterRoutinesResponse is a simple struct being used to render and return a list of all WaterRoutines

func (AllWaterRoutinesResponse) HTML

func (AllWaterRoutinesResponse) Render

type AllWaterSchedulesResponse

type AllWaterSchedulesResponse struct {
	babyapi.ResourceList[*WaterScheduleResponse]
}

AllWaterSchedulesResponse is a simple struct being used to render and return a list of all WaterSchedules

func (AllWaterSchedulesResponse) HTML

func (AllWaterSchedulesResponse) Render

type AllWeatherClientsResponse

type AllWeatherClientsResponse struct {
	babyapi.ResourceList[*WeatherClientResponse]
}

func (AllWeatherClientsResponse) HTML

func (AllWeatherClientsResponse) Render

type AllZonesResponse

type AllZonesResponse struct {
	babyapi.ResourceList[*ZoneResponse]
	// contains filtered or unexported fields
}

func (AllZonesResponse) HTML

func (AllZonesResponse) Render

type Config

type Config struct {
	WebConfig      WebConfig       `mapstructure:"web_server" yaml:"web_server"`
	InfluxDBConfig influxdb.Config `mapstructure:"influxdb" yaml:"influxdb"`
	MQTTConfig     mqtt.Config     `mapstructure:"mqtt" yaml:"mqtt"`
	StorageConfig  storage.Config  `mapstructure:"storage" yaml:"storage"`
	LogConfig      LogConfig       `mapstructure:"log" yaml:"log"`
}

Config holds all the options and sub-configs for the server

type ErrResponse

type ErrResponse struct {
	Err            error `json:"-"` // low-level runtime error
	HTTPStatusCode int   `json:"-"` // http response status code

	StatusText string `json:"status"`          // user-level status message
	AppCode    int64  `json:"code,omitempty"`  // application-specific error code
	ErrorText  string `json:"error,omitempty"` // application-level error message, for debugging
}

ErrResponse is a struct used to organize HTTP error responses

func (*ErrResponse) Render

func (e *ErrResponse) Render(_ http.ResponseWriter, r *http.Request) error

Render will verify and render the ErrResponse

type GardenActionResponse

type GardenActionResponse struct{}

func (*GardenActionResponse) Render

type GardenResponse

type GardenResponse struct {
	*pkg.Garden
	NextLightAction         *NextLightAction         `json:"next_light_action,omitempty"`
	Health                  *pkg.GardenHealth        `json:"health,omitempty"`
	TemperatureHumidityData *TemperatureHumidityData `json:"temperature_humidity_data,omitempty"`
	NumZones                uint                     `json:"num_zones"`
	Links                   []Link                   `json:"links,omitempty"`
	ActiveWatering          *ActiveWatering          `json:"-"` // HTML only
	WateringQueue           uint                     `json:"-"` // HTML only
	// contains filtered or unexported fields
}

GardenResponse is used to represent a Garden in the response body with additional data and hypermedia Links fields

func (*GardenResponse) HTML

func (*GardenResponse) Render

Render is used to make this struct compatible with the go-chi webserver for writing the JSON response

type GardensAPI

type GardensAPI struct {
	*babyapi.API[*pkg.Garden]
	// contains filtered or unexported fields
}

GardensAPI encapsulates the structs and dependencies necessary for the "/gardens" API to function, including storage and configurating

func NewGardenAPI

func NewGardenAPI() *GardensAPI

func (*GardensAPI) NewGardenResponse

func (api *GardensAPI) NewGardenResponse(garden *pkg.Garden, links ...Link) *GardenResponse

NewGardenResponse creates a self-referencing GardenResponse

type Link struct {
	Rel  string `json:"rel,omitempty"`
	HRef string `json:"href"`
}

Link is used for HATEOAS-style REST hypermedia

type LogConfig

type LogConfig struct {
	Level  string `mapstructure:"level" yaml:"level"`
	Format string `mapstructure:"format" yaml:"format"`
}

LogConfig holds settings for logger

func (LogConfig) GetLogLevel

func (c LogConfig) GetLogLevel() slog.Level

GetLogLevel returns the Level based on parsed string. Defaults to Info instead of error

func (LogConfig) NewLogger

func (c LogConfig) NewLogger() *slog.Logger

func (LogConfig) NewLoggerWithWriter

func (c LogConfig) NewLoggerWithWriter(writer io.Writer) *slog.Logger

type NextLightAction

type NextLightAction struct {
	Time  *time.Time     `json:"time"`
	State pkg.LightState `json:"state"`
}

NextLightAction contains the time and state for the next scheduled LightAction

type NextWaterDetails

type NextWaterDetails struct {
	Time            *time.Time    `json:"time,omitempty"`
	Duration        *pkg.Duration `json:"duration,omitempty"`
	WaterScheduleID *xid.ID       `json:"water_schedule_id,omitempty"`
	Message         string        `json:"message,omitempty"`
}

NextWaterDetails has information about the next time this WaterSchedule will be used

func GetNextWaterDetails

func GetNextWaterDetails(r *http.Request, ws *pkg.WaterSchedule, worker *worker.Worker, excludeWeatherData bool) NextWaterDetails

GetNextWaterDetails returns the NextWaterDetails for the WaterSchedule

type NotificationClientResponse

type NotificationClientResponse struct {
	*notifications.Client
	Links []Link `json:"links,omitempty"`
}

NotificationClientResponse wraps a notification client for API responses

func (*NotificationClientResponse) Render

Render adds links and sets HTMX triggers for HTML responses

type NotificationClientTestResponse

type NotificationClientTestResponse struct {
	WeatherData
}

NotificationClientTestResponse is used to return WeatherData from testing that the client works

func (*NotificationClientTestResponse) Render

Render ...

type NotificationClientsAPI

type NotificationClientsAPI struct {
	*babyapi.API[*notifications.Client]
	// contains filtered or unexported fields
}

NotificationClientsAPI encapsulates the structs and dependencies necessary for the NotificationClients API to function, including storage and configuring

func NewNotificationClientsAPI

func NewNotificationClientsAPI() *NotificationClientsAPI

NewNotificationClientsAPI creates a new NotificationClientsResource

type OAuthCallbackData

type OAuthCallbackData struct {
	Success bool
	Error   string
}

OAuthCallbackData is passed to the OAuth callback template

type OAuthStartResponse

type OAuthStartResponse struct {
	AuthURL string
}

OAuthStartResponse triggers a client-side event to open the OAuth popup

func (*OAuthStartResponse) HTML

HTML implements the HTMLer interface for babyapi HTML rendering

func (*OAuthStartResponse) Render

Render implements render.Renderer

type OAuthStateCache

type OAuthStateCache struct {
	// contains filtered or unexported fields
}

OAuthStateCache stores temporary state parameters for OAuth flows

func NewOAuthStateCache

func NewOAuthStateCache() *OAuthStateCache

NewOAuthStateCache creates a new OAuth state cache

func (*OAuthStateCache) Cleanup

func (c *OAuthStateCache) Cleanup()

Cleanup removes expired entries

func (*OAuthStateCache) Store

func (c *OAuthStateCache) Store(weatherClientID string, redirectURI string, ttl time.Duration) string

Store generates a random state, stores it with the weather client ID and redirect URI, and returns the state

func (*OAuthStateCache) Validate

func (c *OAuthStateCache) Validate(state string) (string, string, bool)

Validate checks if the state exists and is not expired, returns the weather client ID and redirect URI if valid

type RainData

type RainData struct {
	MM     *float32 `json:"mm,omitempty"`
	Inches *float32 `json:"inches,omitempty"`
}

RainData shows the total rain in both metric and imperial units

type SettingsAPI

type SettingsAPI struct {
	// contains filtered or unexported fields
}

SettingsAPI encapsulates the structs and dependencies necessary for the Settings API

func NewSettingsAPI

func NewSettingsAPI() *SettingsAPI

NewSettingsAPI creates a new SettingsAPI

func (*SettingsAPI) Setup

func (api *SettingsAPI) Setup(storageClient *storage.Client)

Setup wires the storage client

type TemperatureData

type TemperatureData struct {
	Celsius    float32 `json:"celsius,omitempty"`
	Fahrenheit float32 `json:"fahrenheit,omitempty"`
}

TemperatureData shows the average high temperatures in both Celsius and Fahrenheit

type TemperatureHumidityData

type TemperatureHumidityData struct {
	TemperatureCelsius float64 `json:"temperature_celsius"`
	HumidityPercentage float64 `json:"humidity_percentage"`
}

TemperatureHumidityData has the temperature and humidity of the Garden

type TestNotificationClientRequest

type TestNotificationClientRequest struct {
	Title   string `json:"title"`
	Message string `json:"message"`
}

type UserSettingResponse

type UserSettingResponse struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

UserSettingResponse is the JSON response for a user setting

func (*UserSettingResponse) Render

Render implements render.Renderer

type WaterRoutineAPI

type WaterRoutineAPI struct {
	*babyapi.API[*pkg.WaterRoutine]
	// contains filtered or unexported fields
}

func NewWaterRoutineAPI

func NewWaterRoutineAPI() *WaterRoutineAPI

type WaterRoutineResponse

type WaterRoutineResponse struct {
	*pkg.WaterRoutine
}

WaterRoutineResponse is used to represent a WaterRoutine in the response body

func (*WaterRoutineResponse) Render

Render is used to make this struct compatible with the go-chi webserver for writing the JSON response

type WaterScheduleResponse

type WaterScheduleResponse struct {
	*pkg.WaterSchedule
	WeatherData *WeatherData     `json:"weather_data,omitempty"`
	NextWater   NextWaterDetails `json:"next_water,omitzero"`
	Links       []Link           `json:"links,omitempty"`
	// contains filtered or unexported fields
}

WaterScheduleResponse is used to represent a WaterSchedule in the response body with the additional data and hypermedia Links fields

func (*WaterScheduleResponse) Render

Render is used to make this struct compatible with the go-chi webserver for writing the JSON response

type WaterSchedulesAPI

type WaterSchedulesAPI struct {
	*babyapi.API[*pkg.WaterSchedule]
	// contains filtered or unexported fields
}

WaterSchedulesAPI provides and API for interacting with WaterSchedules

func NewWaterSchedulesAPI

func NewWaterSchedulesAPI() *WaterSchedulesAPI

func (*WaterSchedulesAPI) NewWaterScheduleResponse

func (api *WaterSchedulesAPI) NewWaterScheduleResponse(ws *pkg.WaterSchedule, links ...Link) *WaterScheduleResponse

NewWaterScheduleResponse creates a self-referencing WaterScheduleResponse

type WeatherClientResponse

type WeatherClientResponse struct {
	*weather.Config
	WeatherData *WeatherData `json:"weather_data,omitempty"`

	Links []Link `json:"links,omitempty"`
	// contains filtered or unexported fields
}

func (*WeatherClientResponse) HTML

HTML renders the weather client card for HTMX lazy loading

func (*WeatherClientResponse) Render

Render ...

type WeatherClientTestResponse

type WeatherClientTestResponse struct {
	WeatherData
}

func (*WeatherClientTestResponse) Render

type WeatherClientsAPI

type WeatherClientsAPI struct {
	*babyapi.API[*weather.Config]
	// contains filtered or unexported fields
}

WeatherClientsAPI encapsulates the structs and dependencies necessary for the WeatherClients API to function, including storage and configuring

func NewWeatherClientsAPI

func NewWeatherClientsAPI() *WeatherClientsAPI

type WeatherData

type WeatherData struct {
	Rain        *RainData        `json:"rain,omitempty"`
	Temperature *TemperatureData `json:"temperature,omitempty"`
}

WeatherData is used to represent the data used for WeatherControl to a user

type WebConfig

type WebConfig struct {
	Port           int  `mapstructure:"port" yaml:"port"`
	ReadOnly       bool `mapstructure:"readonly" yaml:"readonly"`
	DisableMetrics bool `mapstructure:"disable_metrics" yaml:"disable_metrics"`
}

WebConfig is used to allow reading the "web_server" section into the main Config struct

type ZoneActionResponse

type ZoneActionResponse struct{}

func (*ZoneActionResponse) Render

type ZoneResponse

type ZoneResponse struct {
	*pkg.Zone
	WeatherData *WeatherData     `json:"weather_data,omitempty"`
	NextWater   NextWaterDetails `json:"next_water,omitzero"`
	Links       []Link           `json:"links,omitempty"`

	// History is only used in HTML responses and is excluded from JSON
	History      ZoneWaterHistoryResponse  `json:"-"`
	HistoryError string                    `json:"-"`
	Progress     *pkg.WaterHistoryProgress `json:"-"`
	// contains filtered or unexported fields
}

ZoneResponse is used to represent a Zone in the response body with the additional data and hypermedia Links fields

func (*ZoneResponse) HTML

func (*ZoneResponse) Render

func (zr *ZoneResponse) Render(w http.ResponseWriter, r *http.Request) error

Render is used to make this struct compatible with the go-chi webserver for writing the JSON response

type ZoneWaterHistoryResponse

type ZoneWaterHistoryResponse struct {
	History []pkg.WaterHistory `json:"history"`
	Count   int                `json:"count"`
	Average string             `json:"average"`
	Total   string             `json:"total"`
}

ZoneWaterHistoryResponse wraps a slice of WaterHistory structs plus some aggregate stats for an HTTP response

func NewZoneWaterHistoryResponse

func NewZoneWaterHistoryResponse(history []pkg.WaterHistory, loc *time.Location) ZoneWaterHistoryResponse

NewZoneWaterHistoryResponse creates a response by creating some basic statistics about a list of history events and converting times to the specified location

func (ZoneWaterHistoryResponse) Render

Render is used to make this struct compatible with the go-chi webserver for writing the JSON response

type ZonesAPI

type ZonesAPI struct {
	*babyapi.API[*pkg.Zone]
	// contains filtered or unexported fields
}

ZonesAPI encapsulates the structs and dependencies necessary for the "/zones" API to function, including storage, scheduling, and caching

func NewZonesAPI

func NewZonesAPI() *ZonesAPI

func (*ZonesAPI) NewZoneResponse

func (api *ZonesAPI) NewZoneResponse(zone *pkg.Zone, links ...Link) *ZoneResponse

NewZoneResponse creates a self-referencing ZoneResponse

Directories

Path Synopsis
Package vcr provides VCR recording functionality for tests
Package vcr provides VCR recording functionality for tests

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL