Docs: introduce product identifier (#21670)
This commit is contained in:
parent
356841f6c6
commit
a04a0cd8c5
10 changed files with 100 additions and 12 deletions
2
go.mod
2
go.mod
|
|
@ -45,6 +45,7 @@ require (
|
|||
github.com/google/uuid v1.6.0
|
||||
github.com/gorilla/handlers v1.5.2
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/gosimple/slug v1.15.0
|
||||
github.com/gregdel/pushover v1.3.1
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79
|
||||
github.com/grid-x/modbus v0.0.0-20250516072809-4b99c910e8e7
|
||||
|
|
@ -151,6 +152,7 @@ require (
|
|||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e // indirect
|
||||
github.com/google/renameio/v2 v2.0.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/gosimple/unidecode v1.0.1 // indirect
|
||||
github.com/grid-x/serial v0.0.0-20211107191517-583c7356b3aa // indirect
|
||||
github.com/huandu/xstrings v1.5.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -308,6 +308,10 @@ github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWS
|
|||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gosimple/slug v1.15.0 h1:wRZHsRrRcs6b0XnxMUBM6WK1U1Vg5B0R7VkIf1Xzobo=
|
||||
github.com/gosimple/slug v1.15.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ=
|
||||
github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o=
|
||||
github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc=
|
||||
github.com/gregdel/pushover v1.3.1 h1:4bMLITOZ15+Zpi6qqoGqOPuVHCwSUvMCgVnN5Xhilfo=
|
||||
github.com/gregdel/pushover v1.3.1/go.mod h1:EcaO66Nn1StkpEm1iKtBTV3d2A16SoMsVER1PthX7to=
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ covers: ["ocpp-abb"]
|
|||
products:
|
||||
- brand: ABB
|
||||
description:
|
||||
generic: Terra AC
|
||||
generic: Terra AC (OCPP)
|
||||
capabilities: ["mA", "rfid"]
|
||||
requirements:
|
||||
evcc: ["sponsorship", "skiptest"]
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ template: ocpp-alfen
|
|||
products:
|
||||
- brand: Alfen
|
||||
description:
|
||||
generic: Eve
|
||||
generic: Eve (OCPP)
|
||||
capabilities: ["mA", "rfid", "1p3p"]
|
||||
requirements:
|
||||
evcc: ["sponsorship", "skiptest"]
|
||||
|
|
|
|||
|
|
@ -3,16 +3,16 @@ covers: ["ocpp-fronius-wattpilot"]
|
|||
products:
|
||||
- brand: go-e
|
||||
description:
|
||||
generic: Charger V3
|
||||
generic: Charger V3 (OCPP)
|
||||
- brand: go-e
|
||||
description:
|
||||
generic: Charger Gemini
|
||||
generic: Charger Gemini (OCPP)
|
||||
- brand: go-e
|
||||
description:
|
||||
generic: Charger PRO
|
||||
generic: Charger PRO (OCPP)
|
||||
- brand: Fronius
|
||||
description:
|
||||
generic: Wattpilot
|
||||
generic: Wattpilot (OCPP)
|
||||
capabilities: ["rfid", "1p3p"]
|
||||
requirements:
|
||||
evcc: ["sponsorship", "skiptest"]
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ template: ocpp-zaptec
|
|||
products:
|
||||
- brand: Zaptec
|
||||
description:
|
||||
generic: Go
|
||||
generic: Go (OCPP)
|
||||
capabilities: ["rfid"]
|
||||
requirements:
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ func (t *Template) RenderDocumentation(product Product, lang string) ([]byte, er
|
|||
}
|
||||
|
||||
var modbusRender string
|
||||
modbusData := make(map[string]interface{})
|
||||
if modbusChoices := t.ModbusChoices(); len(modbusChoices) > 0 {
|
||||
if i, _ := t.ParamByName(ParamModbus); i > -1 {
|
||||
modbusTmpl, err := template.New("yaml").Funcs(sprig.FuncMap()).Parse(documentationModbusTmpl)
|
||||
|
|
@ -50,7 +51,6 @@ func (t *Template) RenderDocumentation(product Product, lang string) ([]byte, er
|
|||
panic(err)
|
||||
}
|
||||
|
||||
modbusData := make(map[string]interface{})
|
||||
t.ModbusValues(RenderModeDocs, modbusData)
|
||||
|
||||
out := new(bytes.Buffer)
|
||||
|
|
@ -91,6 +91,7 @@ func (t *Template) RenderDocumentation(product Product, lang string) ([]byte, er
|
|||
|
||||
data := map[string]interface{}{
|
||||
"Template": t.Template,
|
||||
"ProductIdentifier": product.Identifier(),
|
||||
"ProductBrand": product.Brand,
|
||||
"ProductDescription": product.Description.String(lang),
|
||||
"ProductGroup": t.GroupTitle(lang),
|
||||
|
|
@ -102,6 +103,7 @@ func (t *Template) RenderDocumentation(product Product, lang string) ([]byte, er
|
|||
"AdvancedParams": hasAdvancedParams,
|
||||
"Usages": t.Usages(),
|
||||
"Modbus": modbusRender,
|
||||
"ModbusData": modbusData,
|
||||
}
|
||||
|
||||
out := new(bytes.Buffer)
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
- {{ . }}
|
||||
{{- end }}
|
||||
{{- $unit := .Unit -}}
|
||||
{{- $description := localize .Description | replace "\n" " " -}}
|
||||
{{- $help := localize .Help | replace "\n" " " -}}
|
||||
{{- $description := localize .Description | replace "\n" " " | trim -}}
|
||||
{{- $help := localize .Help | replace "\n" " " | trim -}}
|
||||
{{- $choices := join ", " .Choice -}}
|
||||
{{- $optional := not .IsRequired -}}
|
||||
{{- if or $help $choices $optional $description }} # {{end}}
|
||||
|
|
@ -52,7 +52,9 @@
|
|||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
template: {{ .Template }}
|
||||
product:
|
||||
identifier: {{ .ProductIdentifier }}
|
||||
{{- if .ProductBrand }}
|
||||
brand: {{ .ProductBrand }}
|
||||
{{- end }}
|
||||
|
|
@ -96,3 +98,25 @@ render:
|
|||
{{- include "advanced" . | indent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
params:
|
||||
{{- range .Params }}
|
||||
{{- if and (not (eq .Name "usage")) (not .IsDeprecated) }}
|
||||
- name: {{ .Name | quote }}
|
||||
example: {{ .Example | quote }}
|
||||
default: {{ .Default }}
|
||||
choice: [{{ join ", " .Choice }}]
|
||||
unit: {{ .Unit }}
|
||||
{{- $description := localize .Description | replace "\n" " " | trim }}
|
||||
description: {{ $description | quote }}
|
||||
{{- $help := localize .Help | replace "\n" " " | trim }}
|
||||
help: {{ $help | quote }}
|
||||
advanced: {{ .IsAdvanced }}
|
||||
optional: {{ not .IsRequired }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .ModbusData }}
|
||||
modbus:
|
||||
{{- range $key, $value := .ModbusData }}
|
||||
{{ $key }}: {{ $value }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
|
@ -9,16 +9,20 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/evcc-io/evcc/util/templates"
|
||||
"github.com/gosimple/slug"
|
||||
)
|
||||
|
||||
const (
|
||||
docsPath = "../../../templates/docs"
|
||||
websitePath = "../../../templates/evcc.io"
|
||||
iconsPath = "../../../templates/icons"
|
||||
)
|
||||
|
||||
//go:generate go run main.go
|
||||
|
||||
func main() {
|
||||
slug.CustomSub = map[string]string{"+": "plus"}
|
||||
|
||||
for _, lang := range []string{"de", "en"} {
|
||||
if err := generateDocs(lang); err != nil {
|
||||
panic(err)
|
||||
|
|
@ -28,6 +32,10 @@ func main() {
|
|||
if err := generateBrandJSON(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := generateProductJSON(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func generateDocs(lang string) error {
|
||||
|
|
@ -57,7 +65,7 @@ func generateClass(class templates.Class, lang string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
for index, product := range tmpl.Products {
|
||||
for _, product := range tmpl.Products {
|
||||
fmt.Println(tmpl.Template + ": " + product.Title(lang))
|
||||
|
||||
b, err := tmpl.RenderDocumentation(product, lang)
|
||||
|
|
@ -65,7 +73,12 @@ func generateClass(class templates.Class, lang string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("%s/%s/%s/%s_%d.yaml", docsPath, lang, strings.ToLower(class.String()), tmpl.Template, index)
|
||||
filename := fmt.Sprintf("%s/%s/%s/%s.yaml", docsPath, lang, strings.ToLower(class.String()), product.Identifier())
|
||||
|
||||
if _, err := os.Stat(filename); err == nil {
|
||||
return fmt.Errorf("file already exists: %s - product titles must be unique", filename)
|
||||
}
|
||||
|
||||
if err := os.WriteFile(filename, b, 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -164,3 +177,39 @@ func generateBrandJSON() error {
|
|||
|
||||
return err
|
||||
}
|
||||
|
||||
func generateProductJSON() error {
|
||||
type ProductInfo struct {
|
||||
Brand string `json:"brand"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
products := make(map[string]map[string]ProductInfo)
|
||||
|
||||
for _, class := range templates.ClassValues() {
|
||||
classKey := strings.ToLower(class.String())
|
||||
products[classKey] = make(map[string]ProductInfo)
|
||||
|
||||
for _, tmpl := range templates.ByClass(class) {
|
||||
for _, product := range tmpl.Products {
|
||||
products[classKey][product.Identifier()] = ProductInfo{
|
||||
Brand: product.Brand,
|
||||
Description: product.Description.String("en"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := os.Stat(iconsPath); os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(iconsPath, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
file, err := json.MarshalIndent(products, "", " ")
|
||||
if err == nil {
|
||||
err = os.WriteFile(iconsPath+"/products.json", file, 0o644)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"dario.cat/mergo"
|
||||
"github.com/gosimple/slug"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -259,10 +260,16 @@ type Product struct {
|
|||
Description TextLanguage `json:",omitempty"` // product name
|
||||
}
|
||||
|
||||
// Title returns the product title in the given language
|
||||
func (p Product) Title(lang string) string {
|
||||
return strings.TrimSpace(fmt.Sprintf("%s %s", p.Brand, p.Description.String(lang)))
|
||||
}
|
||||
|
||||
// Identifier returns a unique language-independent identifier for the product
|
||||
func (p Product) Identifier() string {
|
||||
return slug.Make(p.Title("en"))
|
||||
}
|
||||
|
||||
type CountryCode string
|
||||
|
||||
func (c CountryCode) IsValid() bool {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue