Skip to content

Commit a04a0cd

Browse files
authored
Docs: introduce product identifier (#21670)
1 parent 356841f commit a04a0cd

File tree

10 files changed

+100
-12
lines changed

10 files changed

+100
-12
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ require (
4545
github.com/google/uuid v1.6.0
4646
github.com/gorilla/handlers v1.5.2
4747
github.com/gorilla/mux v1.8.1
48+
github.com/gosimple/slug v1.15.0
4849
github.com/gregdel/pushover v1.3.1
4950
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79
5051
github.com/grid-x/modbus v0.0.0-20250516072809-4b99c910e8e7
@@ -151,6 +152,7 @@ require (
151152
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e // indirect
152153
github.com/google/renameio/v2 v2.0.0 // indirect
153154
github.com/gorilla/websocket v1.5.3 // indirect
155+
github.com/gosimple/unidecode v1.0.1 // indirect
154156
github.com/grid-x/serial v0.0.0-20211107191517-583c7356b3aa // indirect
155157
github.com/huandu/xstrings v1.5.0 // indirect
156158
github.com/inconshreveable/mousetrap v1.1.0 // indirect

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,10 @@ github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWS
308308
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
309309
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
310310
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
311+
github.com/gosimple/slug v1.15.0 h1:wRZHsRrRcs6b0XnxMUBM6WK1U1Vg5B0R7VkIf1Xzobo=
312+
github.com/gosimple/slug v1.15.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ=
313+
github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o=
314+
github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc=
311315
github.com/gregdel/pushover v1.3.1 h1:4bMLITOZ15+Zpi6qqoGqOPuVHCwSUvMCgVnN5Xhilfo=
312316
github.com/gregdel/pushover v1.3.1/go.mod h1:EcaO66Nn1StkpEm1iKtBTV3d2A16SoMsVER1PthX7to=
313317
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=

templates/definition/charger/ocpp-abb-tac.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ covers: ["ocpp-abb"]
33
products:
44
- brand: ABB
55
description:
6-
generic: Terra AC
6+
generic: Terra AC (OCPP)
77
capabilities: ["mA", "rfid"]
88
requirements:
99
evcc: ["sponsorship", "skiptest"]

templates/definition/charger/ocpp-alfen.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ template: ocpp-alfen
22
products:
33
- brand: Alfen
44
description:
5-
generic: Eve
5+
generic: Eve (OCPP)
66
capabilities: ["mA", "rfid", "1p3p"]
77
requirements:
88
evcc: ["sponsorship", "skiptest"]

templates/definition/charger/ocpp-goe.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ covers: ["ocpp-fronius-wattpilot"]
33
products:
44
- brand: go-e
55
description:
6-
generic: Charger V3
6+
generic: Charger V3 (OCPP)
77
- brand: go-e
88
description:
9-
generic: Charger Gemini
9+
generic: Charger Gemini (OCPP)
1010
- brand: go-e
1111
description:
12-
generic: Charger PRO
12+
generic: Charger PRO (OCPP)
1313
- brand: Fronius
1414
description:
15-
generic: Wattpilot
15+
generic: Wattpilot (OCPP)
1616
capabilities: ["rfid", "1p3p"]
1717
requirements:
1818
evcc: ["sponsorship", "skiptest"]

templates/definition/charger/ocpp-zaptec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ template: ocpp-zaptec
22
products:
33
- brand: Zaptec
44
description:
5-
generic: Go
5+
generic: Go (OCPP)
66
capabilities: ["rfid"]
77
requirements:
88
description:

util/templates/documentation.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@ func (t *Template) RenderDocumentation(product Product, lang string) ([]byte, er
4343
}
4444

4545
var modbusRender string
46+
modbusData := make(map[string]interface{})
4647
if modbusChoices := t.ModbusChoices(); len(modbusChoices) > 0 {
4748
if i, _ := t.ParamByName(ParamModbus); i > -1 {
4849
modbusTmpl, err := template.New("yaml").Funcs(sprig.FuncMap()).Parse(documentationModbusTmpl)
4950
if err != nil {
5051
panic(err)
5152
}
5253

53-
modbusData := make(map[string]interface{})
5454
t.ModbusValues(RenderModeDocs, modbusData)
5555

5656
out := new(bytes.Buffer)
@@ -91,6 +91,7 @@ func (t *Template) RenderDocumentation(product Product, lang string) ([]byte, er
9191

9292
data := map[string]interface{}{
9393
"Template": t.Template,
94+
"ProductIdentifier": product.Identifier(),
9495
"ProductBrand": product.Brand,
9596
"ProductDescription": product.Description.String(lang),
9697
"ProductGroup": t.GroupTitle(lang),
@@ -102,6 +103,7 @@ func (t *Template) RenderDocumentation(product Product, lang string) ([]byte, er
102103
"AdvancedParams": hasAdvancedParams,
103104
"Usages": t.Usages(),
104105
"Modbus": modbusRender,
106+
"ModbusData": modbusData,
105107
}
106108

107109
out := new(bytes.Buffer)

util/templates/documentation.tpl

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
- {{ . }}
55
{{- end }}
66
{{- $unit := .Unit -}}
7-
{{- $description := localize .Description | replace "\n" " " -}}
8-
{{- $help := localize .Help | replace "\n" " " -}}
7+
{{- $description := localize .Description | replace "\n" " " | trim -}}
8+
{{- $help := localize .Help | replace "\n" " " | trim -}}
99
{{- $choices := join ", " .Choice -}}
1010
{{- $optional := not .IsRequired -}}
1111
{{- if or $help $choices $optional $description }} # {{end}}
@@ -52,7 +52,9 @@
5252
{{- end }}
5353
{{- end -}}
5454

55+
template: {{ .Template }}
5556
product:
57+
identifier: {{ .ProductIdentifier }}
5658
{{- if .ProductBrand }}
5759
brand: {{ .ProductBrand }}
5860
{{- end }}
@@ -96,3 +98,25 @@ render:
9698
{{- include "advanced" . | indent 4 }}
9799
{{- end }}
98100
{{- end }}
101+
params:
102+
{{- range .Params }}
103+
{{- if and (not (eq .Name "usage")) (not .IsDeprecated) }}
104+
- name: {{ .Name | quote }}
105+
example: {{ .Example | quote }}
106+
default: {{ .Default }}
107+
choice: [{{ join ", " .Choice }}]
108+
unit: {{ .Unit }}
109+
{{- $description := localize .Description | replace "\n" " " | trim }}
110+
description: {{ $description | quote }}
111+
{{- $help := localize .Help | replace "\n" " " | trim }}
112+
help: {{ $help | quote }}
113+
advanced: {{ .IsAdvanced }}
114+
optional: {{ not .IsRequired }}
115+
{{- end }}
116+
{{- end }}
117+
{{- if .ModbusData }}
118+
modbus:
119+
{{- range $key, $value := .ModbusData }}
120+
{{ $key }}: {{ $value }}
121+
{{- end }}
122+
{{- end }}

util/templates/generate/main.go

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,20 @@ import (
99
"strings"
1010

1111
"github.com/evcc-io/evcc/util/templates"
12+
"github.com/gosimple/slug"
1213
)
1314

1415
const (
1516
docsPath = "../../../templates/docs"
1617
websitePath = "../../../templates/evcc.io"
18+
iconsPath = "../../../templates/icons"
1719
)
1820

1921
//go:generate go run main.go
2022

2123
func main() {
24+
slug.CustomSub = map[string]string{"+": "plus"}
25+
2226
for _, lang := range []string{"de", "en"} {
2327
if err := generateDocs(lang); err != nil {
2428
panic(err)
@@ -28,6 +32,10 @@ func main() {
2832
if err := generateBrandJSON(); err != nil {
2933
panic(err)
3034
}
35+
36+
if err := generateProductJSON(); err != nil {
37+
panic(err)
38+
}
3139
}
3240

3341
func generateDocs(lang string) error {
@@ -57,15 +65,20 @@ func generateClass(class templates.Class, lang string) error {
5765
return err
5866
}
5967

60-
for index, product := range tmpl.Products {
68+
for _, product := range tmpl.Products {
6169
fmt.Println(tmpl.Template + ": " + product.Title(lang))
6270

6371
b, err := tmpl.RenderDocumentation(product, lang)
6472
if err != nil {
6573
return err
6674
}
6775

68-
filename := fmt.Sprintf("%s/%s/%s/%s_%d.yaml", docsPath, lang, strings.ToLower(class.String()), tmpl.Template, index)
76+
filename := fmt.Sprintf("%s/%s/%s/%s.yaml", docsPath, lang, strings.ToLower(class.String()), product.Identifier())
77+
78+
if _, err := os.Stat(filename); err == nil {
79+
return fmt.Errorf("file already exists: %s - product titles must be unique", filename)
80+
}
81+
6982
if err := os.WriteFile(filename, b, 0o644); err != nil {
7083
return err
7184
}
@@ -164,3 +177,39 @@ func generateBrandJSON() error {
164177

165178
return err
166179
}
180+
181+
func generateProductJSON() error {
182+
type ProductInfo struct {
183+
Brand string `json:"brand"`
184+
Description string `json:"description"`
185+
}
186+
187+
products := make(map[string]map[string]ProductInfo)
188+
189+
for _, class := range templates.ClassValues() {
190+
classKey := strings.ToLower(class.String())
191+
products[classKey] = make(map[string]ProductInfo)
192+
193+
for _, tmpl := range templates.ByClass(class) {
194+
for _, product := range tmpl.Products {
195+
products[classKey][product.Identifier()] = ProductInfo{
196+
Brand: product.Brand,
197+
Description: product.Description.String("en"),
198+
}
199+
}
200+
}
201+
}
202+
203+
if _, err := os.Stat(iconsPath); os.IsNotExist(err) {
204+
if err := os.MkdirAll(iconsPath, 0o755); err != nil {
205+
return err
206+
}
207+
}
208+
209+
file, err := json.MarshalIndent(products, "", " ")
210+
if err == nil {
211+
err = os.WriteFile(iconsPath+"/products.json", file, 0o644)
212+
}
213+
214+
return err
215+
}

util/templates/types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strings"
99

1010
"dario.cat/mergo"
11+
"github.com/gosimple/slug"
1112
)
1213

1314
const (
@@ -259,10 +260,16 @@ type Product struct {
259260
Description TextLanguage `json:",omitempty"` // product name
260261
}
261262

263+
// Title returns the product title in the given language
262264
func (p Product) Title(lang string) string {
263265
return strings.TrimSpace(fmt.Sprintf("%s %s", p.Brand, p.Description.String(lang)))
264266
}
265267

268+
// Identifier returns a unique language-independent identifier for the product
269+
func (p Product) Identifier() string {
270+
return slug.Make(p.Title("en"))
271+
}
272+
266273
type CountryCode string
267274

268275
func (c CountryCode) IsValid() bool {

0 commit comments

Comments
 (0)