Add products api (#6205)
This commit is contained in:
parent
cc85ed8efd
commit
e6f8939ee7
4 changed files with 111 additions and 0 deletions
|
|
@ -98,6 +98,7 @@ func (s *HTTPd) RegisterSiteHandlers(site site.API, cache *util.Cache) {
|
|||
"health": {[]string{"GET"}, "/health", healthHandler(site)},
|
||||
"state": {[]string{"GET"}, "/state", stateHandler(cache)},
|
||||
"config": {[]string{"GET"}, "/config/templates/{class:[a-z]+}", templatesHandler},
|
||||
"products": {[]string{"GET"}, "/config/products/{class:[a-z]+}", productsHandler},
|
||||
"test": {[]string{"POST"}, "/config/test/{class:[a-z]+}", testHandler},
|
||||
"buffersoc": {[]string{"POST", "OPTIONS"}, "/buffersoc/{value:[0-9.]+}", floatHandler(site.SetBufferSoc, site.GetBufferSoc)},
|
||||
"prioritysoc": {[]string{"POST", "OPTIONS"}, "/prioritysoc/{value:[0-9.]+}", floatHandler(site.SetPrioritySoc, site.GetPrioritySoc)},
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ package server
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/charger"
|
||||
|
|
@ -10,6 +12,7 @@ import (
|
|||
"github.com/evcc-io/evcc/util/templates"
|
||||
"github.com/evcc-io/evcc/vehicle"
|
||||
"github.com/gorilla/mux"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
// templatesHandler returns the list of templates by class
|
||||
|
|
@ -23,6 +26,93 @@ func templatesHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
res := templates.ByClass(class)
|
||||
|
||||
lang := r.URL.Query().Get("lang")
|
||||
templates.EncoderLanguage(lang)
|
||||
|
||||
if name := r.URL.Query().Get("name"); name != "" {
|
||||
for _, t := range res {
|
||||
if t.TemplateDefinition.Template == name {
|
||||
jsonResult(w, t)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
jsonError(w, http.StatusBadRequest, errors.New("template not found"))
|
||||
return
|
||||
}
|
||||
|
||||
jsonResult(w, res)
|
||||
}
|
||||
|
||||
type product struct {
|
||||
Name string `json:"name"`
|
||||
Template string `json:"template"`
|
||||
}
|
||||
|
||||
type products []product
|
||||
|
||||
func (p products) MarshalJSON() (out []byte, err error) {
|
||||
if p == nil {
|
||||
return []byte(`null`), nil
|
||||
}
|
||||
if len(p) == 0 {
|
||||
return []byte(`{}`), nil
|
||||
}
|
||||
|
||||
out = append(out, '{')
|
||||
for _, e := range p {
|
||||
key, err := json.Marshal(e.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
val, err := json.Marshal(e.Template)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, key...)
|
||||
out = append(out, ':')
|
||||
out = append(out, val...)
|
||||
out = append(out, ',')
|
||||
}
|
||||
|
||||
// replace last ',' with '}'
|
||||
if len(out) > 1 {
|
||||
out[len(out)-1] = '}'
|
||||
} else {
|
||||
out = append(out, '}')
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// productsHandler returns the list of products by class
|
||||
func productsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
|
||||
class, err := templates.ClassString(vars["class"])
|
||||
if err != nil {
|
||||
jsonError(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
tmpl := templates.ByClass(class)
|
||||
lang := r.URL.Query().Get("lang")
|
||||
|
||||
res := make(products, 0)
|
||||
for _, t := range tmpl {
|
||||
for _, p := range t.Products {
|
||||
res = append(res, product{
|
||||
Name: p.Title(lang),
|
||||
Template: t.TemplateDefinition.Template,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
slices.SortFunc(res, func(a, b product) bool {
|
||||
return strings.ToLower(a.Name) < strings.ToLower(b.Name)
|
||||
})
|
||||
|
||||
jsonResult(w, res)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"io/fs"
|
||||
"path"
|
||||
"sync"
|
||||
|
||||
"github.com/evcc-io/evcc/templates/definition"
|
||||
"golang.org/x/exp/slices"
|
||||
|
|
@ -14,6 +15,9 @@ import (
|
|||
var (
|
||||
templates = make(map[Class][]Template)
|
||||
configDefaults = ConfigDefaults{}
|
||||
|
||||
mu sync.Mutex
|
||||
encoderLanguage string
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
@ -98,6 +102,13 @@ func loadTemplates(class Class) {
|
|||
}
|
||||
}
|
||||
|
||||
// EncoderLanguage sets the template language for encoding json
|
||||
func EncoderLanguage(lang string) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
encoderLanguage = lang
|
||||
}
|
||||
|
||||
func ByClass(class Class) []Template {
|
||||
return templates[class]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package templates
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
|
@ -145,6 +146,14 @@ func (t *TextLanguage) Update(new TextLanguage, always bool) {
|
|||
}
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface
|
||||
func (t *TextLanguage) MarshalJSON() (out []byte, err error) {
|
||||
mu.Lock()
|
||||
s := t.String(encoderLanguage)
|
||||
mu.Unlock()
|
||||
return json.Marshal(s)
|
||||
}
|
||||
|
||||
// Requirements
|
||||
type Requirements struct {
|
||||
EVCC []string // EVCC requirements, e.g. sponsorship
|
||||
Loading…
Add table
Add a link
Reference in a new issue