Skip to content

Indicate protocol for devices #15293

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

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
cab9aee
wip
premultiply Aug 7, 2024
1d9e1ac
wip
premultiply Aug 7, 2024
821de35
wip
premultiply Aug 8, 2024
e926708
wip
premultiply Aug 8, 2024
1c88a13
wip
premultiply Aug 8, 2024
d63b9a3
wip
premultiply Aug 8, 2024
846779c
wip
premultiply Aug 8, 2024
1d15033
wip
premultiply Aug 8, 2024
5b31b21
wip
premultiply Aug 8, 2024
98c8a62
add protocol field to template; add requirements (sponsor, descriptio…
naltatis Aug 9, 2024
23f6cfd
Merge branch 'master' into device/ocpp-new-templates
naltatis Aug 9, 2024
e6f14e3
Merge branch 'master' into device/ocpp-new-templates
premultiply Aug 13, 2024
bada07e
remove dup
premultiply Aug 13, 2024
1cd31eb
covers wattpilot
premultiply Aug 14, 2024
0c899c3
add chargers
premultiply Aug 18, 2024
3aa20ce
wip
premultiply Aug 18, 2024
39e568c
wip
premultiply Aug 20, 2024
c2e07ba
Merge branch 'master' into device/ocpp-new-templates
premultiply Sep 5, 2024
58030dd
Merge branch 'master' of https://github.com/evcc-io/evcc into device/…
premultiply Oct 16, 2024
ee34ef0
wip
premultiply Oct 16, 2024
7bd6921
Merge branch 'master' into device/ocpp-new-templates
premultiply Feb 12, 2025
754904d
Merge branch 'master' into device/ocpp-new-templates
premultiply Apr 13, 2025
4b8f40a
wip
premultiply Apr 13, 2025
05552f4
Merge branch 'master' into device/ocpp-new-templates
naltatis Apr 14, 2025
0039315
template consistancy; add protocol to name if needed
naltatis Apr 15, 2025
e634c8b
Merge branch 'master' into device/ocpp-new-templates
premultiply May 4, 2025
eea0147
Merge branch 'master' into device/ocpp-new-templates
premultiply May 16, 2025
63a6b77
Merge branch 'master' into device/ocpp-new-templates
premultiply May 16, 2025
59bf40a
wip
premultiply May 16, 2025
08db3b7
wip
premultiply May 16, 2025
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
20 changes: 16 additions & 4 deletions assets/js/components/Config/ChargerModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -221,17 +221,29 @@ export default {
}
return this.$t(`config.charger.titleEdit`);
},
uniqueProducts() {
// append protocol if multiple products with same name exist
const names = this.products.map((p) => p.name);
return this.products.map((p) => {
if (names.filter((n) => n === p.name).length > 1 && p.protocol) {
const protocol = this.$t(`config.deviceProtocol.${p.protocol}`);
const name = `${p.name} (${protocol})`;
return { ...p, name };
}
return p;
});
},
chargerOptions() {
return this.products.filter((p) => !p.group);
return this.uniqueProducts.filter((p) => !p.group);
},
genericOptions() {
return this.products.filter((p) => p.group === "generic");
return this.uniqueProducts.filter((p) => p.group === "generic");
},
switchSocketOptions() {
return this.products.filter((p) => p.group === "switchsockets");
return this.uniqueProducts.filter((p) => p.group === "switchsockets");
},
heatingdevicesOptions() {
return this.products.filter((p) => p.group === "heating");
return this.uniqueProducts.filter((p) => p.group === "heating");
},
templateParams() {
const params = this.template?.Params || [];
Expand Down
1 change: 1 addition & 0 deletions server/http_config_metadata_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func productsHandler(w http.ResponseWriter, r *http.Request) {
Name: p.Title(lang),
Template: t.TemplateDefinition.Template,
Group: t.Group,
Protocol: t.Protocol,
})
}
}
Expand Down
1 change: 1 addition & 0 deletions server/product.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ type product struct {
Name string `json:"name"`
Template string `json:"template"`
Group string `json:"group,omitempty"`
Protocol string `json:"protocol,omitempty"`
}

type products []product
1 change: 1 addition & 0 deletions templates/definition/charger/abb.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
template: abb
protocol: modbus
products:
- brand: ABB
description:
Expand Down
1 change: 1 addition & 0 deletions templates/definition/charger/abl-em4.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
template: abl-em4
protocol: modbus
products:
- brand: ABL
description:
Expand Down
1 change: 1 addition & 0 deletions templates/definition/charger/alfen.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
template: alfen
protocol: modbus
products:
- brand: Alfen
description:
Expand Down
1 change: 1 addition & 0 deletions templates/definition/charger/daheimladen-mb.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
template: daheimladen-mb
protocol: modbus
products:
- brand: DaheimLaden
description:
Expand Down
1 change: 1 addition & 0 deletions templates/definition/charger/fronius-wattpilot.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
template: fronius-wattpilot
protocol: localapi
deprecated: true
products:
- brand: Fronius
Expand Down
1 change: 1 addition & 0 deletions templates/definition/charger/go-e-v3.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
template: go-e-v3
protocol: localapi
covers: ["go-e-gemini"]
products:
- brand: go-e
Expand Down
1 change: 1 addition & 0 deletions templates/definition/charger/go-e.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
template: go-e
protocol: localapi
products:
- brand: go-e
description:
Expand Down
1 change: 1 addition & 0 deletions templates/definition/charger/phoenix-ev-ser.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
template: phoenix-ev-ser
protocol: modbus
products:
- brand: Phoenix Contact
description:
Expand Down
2 changes: 1 addition & 1 deletion templates/definition/charger/tessie.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
template: tessie
group: generic
protocol: cloudapi
products:
- description:
generic: Tessie
Expand Down
1 change: 1 addition & 0 deletions templates/definition/charger/zaptec.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
template: zaptec
protocol: localapi
products:
- brand: Zaptec
description:
Expand Down
4 changes: 3 additions & 1 deletion util/templates/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ var defaults []byte
type configDefaults struct {
Params []Param // Default values for common parameters
Presets map[string]struct {
Params []Param
Params []Param
Protocol string
Requirements Requirements
}
Modbus struct { // Details about possible ModbusInterfaces and ModbusConnectionTypes
Interfaces map[string][]string // Information about physical modbus interface types (rs485, tcpip)
Expand Down
5 changes: 5 additions & 0 deletions util/templates/defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ presets:
required: true

eebus:
protocol: eebus
params:
- name: ski
help:
Expand All @@ -480,6 +481,9 @@ presets:
- name: icon
advanced: true
ocpp:
protocol: ocpp
requirements:
evcc: ["sponsorship"]
params:
- name: stationid
type: string
Expand Down Expand Up @@ -538,6 +542,7 @@ presets:
example: Energy.Active.Import.Register,Power.Active.Import,SoC,Current.Offered,Power.Offered,Current.Import,Voltage

mqtt:
protocol: mqtt
params:
- name: host
help:
Expand Down
1 change: 1 addition & 0 deletions util/templates/documentation.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ func (t *Template) RenderDocumentation(product Product, lang string) ([]byte, er
"Capabilities": t.Capabilities,
"Countries": t.Countries,
"Requirements": t.Requirements.EVCC,
"Protocol": t.Protocol,
"RequirementDescription": t.Requirements.Description.String(lang),
"Params": filteredParams,
"AdvancedParams": hasAdvancedParams,
Expand Down
3 changes: 3 additions & 0 deletions util/templates/documentation.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ product:
{{- if .ProductGroup }}
group: {{ .ProductGroup }}
{{- end }}
{{- if .Protocol }}
protocol: {{ .Protocol }}
{{- end }}
{{- if .Capabilities }}
capabilities: ["{{ join "\", \"" .Capabilities }}"]
{{- end }}
Expand Down
27 changes: 25 additions & 2 deletions util/templates/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (t *Template) UpdateParamsWithDefaults() error {
func (t *Template) Validate() error {
for _, c := range t.Capabilities {
if !slices.Contains(ValidCapabilities, c) {
return fmt.Errorf("invalid capability '%s' in template %s", c, t.Template)
return fmt.Errorf("invalid capability '%s' in template %s. valid options: %s", c, t.Template, ValidCapabilities)
}
}

Expand All @@ -53,10 +53,14 @@ func (t *Template) Validate() error {

for _, r := range t.Requirements.EVCC {
if !slices.Contains(ValidRequirements, r) {
return fmt.Errorf("invalid requirement '%s' in template %s", r, t.Template)
return fmt.Errorf("invalid requirement '%s' in template %s. valid options: %s", r, t.Template, ValidCapabilities)
}
}

if t.Protocol != "" && !slices.Contains(ValidProtocols, t.Protocol) {
return fmt.Errorf("invalid protocol '%s' in template %s. valid options: %s", t.Protocol, t.Template, ValidProtocols)
}

for _, p := range t.Params {
switch p.Name {
case ParamUsage:
Expand Down Expand Up @@ -124,7 +128,26 @@ func (t *Template) ResolvePresets() error {
return fmt.Errorf("could not find preset definition: %s", p.Preset)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider refactoring the inline preset merging logic into smaller helper functions to improve readability and reduce nesting.

The inline preset merging logic now handles several responsibilities at once. Consider breaking out the logic into small helper functions to reduce nesting and increase clarity. For example:

func mergePreset(t *Template, base PresetDefinition) error {
	// Merge params
	t.Params = append(t.Params, base.Params...)
	applyProtocol(t, base)
	applyDescription(t, base)
	appendRequirements(t, base)
	return nil
}

func applyProtocol(t *Template, base PresetDefinition) {
	if t.Protocol == "" && base.Protocol != "" {
		t.Protocol = base.Protocol
	}
}

func applyDescription(t *Template, base PresetDefinition) {
	if t.Requirements.Description.DE == "" &&
		t.Requirements.Description.EN == "" &&
		t.Requirements.Description.Generic == "" {
		t.Requirements.Description = base.Requirements.Description
	}
}

func appendRequirements(t *Template, base PresetDefinition) {
	for _, r := range base.Requirements.EVCC {
		if !slices.Contains(t.Requirements.EVCC, r) {
			t.Requirements.EVCC = append(t.Requirements.EVCC, r)
		}
	}
}

Then update your loop in ResolvePresets() to simply call:

if p.Preset != "" {
	base, ok := ConfigDefaults.Presets[p.Preset]
	if !ok {
		return fmt.Errorf("could not find preset definition: %s", p.Preset)
	}
	if err := mergePreset(t, base); err != nil {
		return err
	}
	continue
}

This refactor reduces inline complexity while keeping functionality intact.


// add preset params
t.Params = append(t.Params, base.Params...)

// apply protocol if not already set
if t.Protocol == "" && base.Protocol != "" {
t.Protocol = base.Protocol
}

// set description if not already set
if t.Requirements.Description.DE == "" && t.Requirements.Description.EN == "" && t.Requirements.Description.Generic == "" {
t.Requirements.Description = base.Requirements.Description
}

// append requirements if not already present
for _, r := range base.Requirements.EVCC {
if !slices.Contains(t.Requirements.EVCC, r) {
t.Requirements.EVCC = append(t.Requirements.EVCC, r)
}
}

continue
}

Expand Down
12 changes: 12 additions & 0 deletions util/templates/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ const (

var ValidRequirements = []string{RequirementEEBUS, RequirementMQTT, RequirementSponsorship, RequirementSkipTest}

const (
ProtocolOCPP = "ocpp" // Open Charge Point Protocol
ProtocolLocalApi = "localapi" // local vendor-specific API
ProtocolCloudApi = "cloudapi" // cloud-based vendor API
ProtocolModbus = "modbus" // Modbus RTU or TCP
ProtocolMQTT = "mqtt" // MQTT
ProtocolEEBUS = "eebus" // EEBUS
)

var ValidProtocols = []string{ProtocolOCPP, ProtocolLocalApi, ProtocolCloudApi, ProtocolModbus, ProtocolMQTT, ProtocolEEBUS}

var predefinedTemplateProperties = []string{
"type", "template", "name",
ModbusParamNameId, ModbusParamNameDevice, ModbusParamNameBaudrate, ModbusParamNameComset,
Expand Down Expand Up @@ -277,6 +288,7 @@ type TemplateDefinition struct {
Group string `json:",omitempty"` // the group this template belongs to, references groupList entries
Covers []string `json:",omitempty"` // list of covered outdated template names
Products []Product `json:",omitempty"` // list of products this template is compatible with
Protocol string `json:",omitempty"` // communication protocol used in this template. used do differentiate templates for the same device
Capabilities []string `json:",omitempty"`
Countries []CountryCode `json:",omitempty"` // list of countries supported by this template
Requirements Requirements `json:",omitempty"`
Expand Down
Loading