Skip to content
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

Template improvements #2019

Merged
merged 26 commits into from
Dec 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
865412d
Update go-e firmware requirements
DerAndereAndi Dec 11, 2021
3c3064e
Add support for onIdentify params of vehicles
DerAndereAndi Dec 11, 2021
0976a77
Add support for resetOnDisconnect on loadpoints
DerAndereAndi Dec 11, 2021
0a790d1
Fix display of nil exampleValue
DerAndereAndi Dec 11, 2021
d61eb28
Update README
DerAndereAndi Dec 11, 2021
1684164
Fix invalid assignment
DerAndereAndi Dec 11, 2021
04f63b1
Add default value for valuetypechargemodes
DerAndereAndi Dec 11, 2021
cc79d20
Add support to predefine modbus port
DerAndereAndi Dec 11, 2021
cf3dda5
Set modbus defaults for some devices
DerAndereAndi Dec 11, 2021
e61d297
Fix cfos meter not being provided as charge meter
DerAndereAndi Dec 11, 2021
fdc1240
Fix build
DerAndereAndi Dec 11, 2021
72318e2
Fix templates using modbus creating invalid yaml
DerAndereAndi Dec 11, 2021
7220618
Fix linter warning
DerAndereAndi Dec 11, 2021
b6de7ee
A fix for modbus
DerAndereAndi Dec 11, 2021
7e87365
Some code cleanup
DerAndereAndi Dec 11, 2021
3ef5017
Fix linter warning
DerAndereAndi Dec 11, 2021
6dcf9a8
Check for write permissions
DerAndereAndi Dec 11, 2021
431f829
Change cfos devices not to use modbus config
DerAndereAndi Dec 11, 2021
fe70ab2
Improve file permissions handling
DerAndereAndi Dec 11, 2021
088ab38
cfos meter setup needs port and id
DerAndereAndi Dec 11, 2021
1199914
Review changes
DerAndereAndi Dec 12, 2021
2c768d3
Add modbus and usage choice validation
DerAndereAndi Dec 12, 2021
8932932
Add support for overwriting modbus default id
DerAndereAndi Dec 12, 2021
a4bbcbe
Migrate some templates to use modbus param
DerAndereAndi Dec 12, 2021
b15438c
Add fritzdect meter template
DerAndereAndi Dec 12, 2021
ac66ed0
Update cfos meter template
DerAndereAndi Dec 12, 2021
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
17 changes: 9 additions & 8 deletions cmd/configure/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ type device struct {
}

type loadpoint struct {
Title string // TODO Perspektivisch können wir was aus core wiederverwenden, für später
Charger string
ChargeMeter string
Vehicles []string
Mode string
MinCurrent int
MaxCurrent int
Phases int
Title string // TODO Perspektivisch können wir was aus core wiederverwenden, für später
Charger string
ChargeMeter string
Vehicles []string
Mode string
MinCurrent int
MaxCurrent int
Phases int
ResetOnDisconnect string
}

type config struct {
Expand Down
1 change: 1 addition & 0 deletions cmd/configure/configure.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ loadpoints:
phases: {{ .Phases }}
mincurrent: {{ .MinCurrent }}
maxcurrent: {{ .MaxCurrent }}
resetOnDisconnect: {{ .ResetOnDisconnect }}
{{- end }}
{{- end }}

Expand Down
17 changes: 13 additions & 4 deletions cmd/configure/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,12 +307,21 @@ func (c *CmdConfigure) processModbusConfig(param templates.Param, deviceCategory

// baudrate and comset defaults can be overwritten, as they are device specific
deviceDefaultBaudrate := templates.ModbusParamValueBaudrate
deviceDefaultComset := templates.ModbusParamValueComset
deviceDefaultPort := templates.ModbusParamValuePort
deviceDefaultId := templates.ModbusParamValueId

if param.Baudrate != 0 {
deviceDefaultBaudrate = param.Baudrate
}
deviceDefaultComset := templates.ModbusParamValueComset
if param.Comset != "" {
deviceDefaultBaudrate = param.Baudrate
deviceDefaultComset = param.Comset
}
if param.Port != 0 {
deviceDefaultPort = param.Port
}
if param.ID != 0 {
deviceDefaultId = param.ID
}

var choices []string
Expand All @@ -336,7 +345,7 @@ func (c *CmdConfigure) processModbusConfig(param templates.Param, deviceCategory
id := c.askValue(question{
label: "ID",
help: "Modbus ID",
defaultValue: 1,
defaultValue: deviceDefaultId,
valueType: templates.ParamValueTypeNumber,
required: true})
additionalConfig[templates.ModbusParamNameId] = id
Expand Down Expand Up @@ -383,7 +392,7 @@ func (c *CmdConfigure) processModbusConfig(param templates.Param, deviceCategory

port := c.askValue(question{
label: c.localizedString("UserFriendly_Port_Name", nil),
defaultValue: templates.ModbusParamValuePort,
defaultValue: deviceDefaultPort,
valueType: templates.ParamValueTypeNumber,
required: true})
additionalConfig[templates.ModbusParamNamePort] = port
Expand Down
24 changes: 19 additions & 5 deletions cmd/configure/localization/de.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Error_EEBUS_Certificate_Create = "Konnte das EEBUS Zertifikat nicht erstellen"
Error_EEBUS_Certificate_Use = "Konnte das EEBUS Zertifikat nicht verwenden"

File_Exists = "Die Datei {{ .FileName }} existiert bereits. Soll die Datei überschrieben werden?"
File_Permissions = "Die Datei {{ .FileName }} existiert bereits und kann nicht überschrieben werden."
File_NewFilename = "Bitte gib einen neuen Dateinamen an"
File_Error_SaveFailed = "Die Konfiguration konnte nicht in der Datei {{ .FileName }} gespeichert werden"
File_SaveSuccess = "Die Konfiguration wurde erfolgreich in der Datei {{ .FileName }} gespeichert"
Expand All @@ -45,6 +46,16 @@ UserFriendly_Password_Name = "Passwort"
UserFriendly_Capacity_Name = "Akku-Kapazität in kWh"
UserFriendly_Vin_Name = "Fahrzeugidentifikationsnummer"
UserFriendly_Vin_Help = "Erforderlich, wenn mehrere Fahrzeuge des Herstellers vorhanden sind"
UserFriendly_Cache_Name = "Cache"
UserFriendly_Cache_Help = "Das zeitliche Interval, in welchem Daten vom Fahrzeug neu geladen werden soll"
UserFriendly_MinSoC_Name = "Minimaler Ladestand (SoC) in %"
UserFriendly_MinSoC_Help = "Lade sofort mit maximaler Geschwindigkeit bis zu dem angegeben Ladestand, wenn der Lademodus nicht auf 'Aus' steht"
UserFriendly_TargetSoC_Name = "Ziel-Ladestand (SoC) in %"
UserFriendly_TargetSoC_Help = "Bis zu welchem Ladestand (SoC) soll das Fahrzeug geladen werden"
UserFriendly_MinCurrent_Name = "Minimale Stromstärke in Ampere (A)"
UserFriendly_MinCurrent_Help = "Definiert die minimale Stromstärke pro angeschlossener Phase mit welcher das Fahrzeug geladen werden soll"
UserFriendly_MaxCurrent_Name = "Maximale Stromstärke in Ampere (A)"
UserFriendly_MaxCurrent_Help = "Definiert die maximale Stromstärke pro angeschlossener Phase mit welcher das Fahrzeug geladen werden soll"
UserFriendly_Identifier_Name = "Identifikationsnummer"
UserFriendly_Identifier_Help = "Kann meist erst später eingetragen werden, siehe: https://docs.evcc.io/docs/guides/vehicles/#erkennung-des-fahrzeugs-an-der-wallbox"
UserFriendly_StandByPower_Name = "Standby-Leistung in W"
Expand Down Expand Up @@ -113,6 +124,8 @@ Loadpoint_Title = "Titel des Ladepunktes"
Loadpoint_AddAnother = "Möchtest du einen weiteren Ladepunkt hinzufügen?"
Loadpoint_DefaultTitle = "Garage"

Loadpoint_ResetOnDisconnect = "Soll beim Abstecken des Ladekables von einem Fahrzeug, die Lade-Standardeinstellungen wieder hergestellt werden?"

Loadpoint_WallboxWOMeter = "Die Wallbox hat keinen Ladestromzähler. Hast du einen externen Zähler dafür installiert, der verwendet werden kann?"
Loadpoint_WallboxMaxPower = "Was ist die maximale Leistung, welche die Wallbox zur Verfügung stellen kann?"
Loadpoint_WallboxMaxAmperage = "Was ist die maximale Stromstärke, welche die Wallbox auf einer Phase zur Verfügung stellen kann?"
Expand All @@ -124,11 +137,12 @@ Loadpoint_WallboxPowerOther = "Andere Leistung"

Loadpoint_VehicleChargeHere = "Wird das Fahrzeug {{ .Vehicle }} hier laden?"

Loadpoint_DefaultChargeMode = "Was sollte der Standard-Lademodus sein, wenn ein Fahrzeug angeschlossen wird?"
Loadpoint_ChargeModeOff = "Aus"
Loadpoint_ChargeModeNow = "Sofort (mit größtmöglicher Leistung)"
Loadpoint_ChargeModeMinPV = "Min+PV (mit der kleinstmöglichen Leistung, schneller wenn genügend PV Überschuss vorhanden ist)"
Loadpoint_ChargeModePV = "PV (Nur mit PV Überschuss)"
ChargeMode_Question = "Was sollte der Standard-Lademodus sein, wenn ein Fahrzeug angeschlossen wird?"
ChargeModeOff = "Stop"
ChargeModeNow = "Sofort (mit größtmöglicher Leistung)"
ChargeModeMinPV = "Min+PV (mit der kleinstmöglichen Leistung, schneller wenn genügend PV Überschuss vorhanden ist)"
ChargeModePV = "PV (Nur mit PV Überschuss)"
ChargeModeNone = "Keinen (Benutzt den im Ladepunkt gesetzten Lademodus)"

Site_Setup = "- Standort einrichten"
Site_Title = "Titel des Standortes"
Expand Down
24 changes: 19 additions & 5 deletions cmd/configure/localization/en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Error_EEBUS_Certificate_Create = "Could not create the EEBUS certificate"
Error_EEBUS_Certificate_Use = "Could not process teh generated EEBUS certificate"

File_Exists = "The file {{ .FileName }} already exists. Do you want to replace it?"
File_Permissions = "The file {{ .FileName }} already exists and can not be overwritten."
File_NewFilename = "Please provide a new filename"
File_Error_SaveFailed = "The configuration could not be saved in the file {{ .FileName }}"
File_SaveSuccess = "The configuration was successfully saved in the file {{ .FileName }}"
Expand All @@ -45,6 +46,16 @@ UserFriendly_Password_Name = "Password"
UserFriendly_Capacity_Name = "Battery-Capacity in kWh"
UserFriendly_Vin_Name = "Vehicle Identification Number"
UserFriendly_Vin_Help = "Required if you own multiple vehicles of the same brand"
UserFriendly_Cache_Name = "Cache"
UserFriendly_Cache_Help = "Time interval with when data should be reloaded from the vehicle"
UserFriendly_MinSoC_Name = "Minimum state of charge (SoC) in %"
UserFriendly_MinSoC_Help = "Charge immediately with maximum power up to the defined state of charge, if the charge mode is not set to 'OFF'"
UserFriendly_TargetSoC_Name = "Target state of charge (SoC) in %"
UserFriendly_TargetSoC_Help = "Until which sate of charge (SoC) should the vehicle be charged"
UserFriendly_MinCurrent_Name = "Minimum amperage (A)"
UserFriendly_MinCurrent_Help = "The minimum amperage per connected phase with which the car should be charged"
UserFriendly_MaxCurrent_Name = "Maximum amperage (A)"
UserFriendly_MaxCurrent_Help = "The maximum amperage per connected phase with which the car shuold be charged"
UserFriendly_Identifier_Name = "Identification"
UserFriendly_Identifier_Help = "Mostly this can be added later, see: https://docs.evcc.io/docs/guides/vehicles/#erkennung-des-fahrzeugs-an-der-wallbox"
UserFriendly_StandByPower_Name = "Standby power in W"
Expand Down Expand Up @@ -113,6 +124,8 @@ Loadpoint_Title = "Loadpoint title"
Loadpoint_AddAnother = "Do you want to add another loadpoint?"
Loadpoint_DefaultTitle = "Garage"

Loadpoint_ResetOnDisconnect = "Shall disconnecting the charging cable from the vehicle reset the charging settings to the defaults?"

Loadpoint_WallboxWOMeter = "The wallbox does not provide power data. Do you have an external meter that can be used?"
Loadpoint_WallboxMaxPower = "What is the maximum power your wallbox can provide?"
Loadpoint_WallboxMaxAmperage = "What is the maximum amperage your wallbox can provide on a single phase?"
Expand All @@ -124,11 +137,12 @@ Loadpoint_WallboxPowerOther = "Other option"

Loadpoint_VehicleChargeHere = "Will the vehicle {{ .Vehicle }} be charging here?"

Loadpoint_DefaultChargeMode = "Was sollte der Standard-Lademodus sein, wenn ein Fahrzeug angeschlossen wird?"
Loadpoint_ChargeModeOff = "Off"
Loadpoint_ChargeModeNow = "Now (charging with maximum power)"
Loadpoint_ChargeModeMinPV = "Min+PV (charging with minimum power, faster if enough PV power surplus is available)"
Loadpoint_ChargeModePV = "PV (Only with PV power surplus)"
ChargeMode_Question = "What should be the default charging mode when a vehicle is connected?"
ChargeModeOff = "Off"
ChargeModeNow = "Now (charging with maximum power)"
ChargeModeMinPV = "Min+PV (charging with minimum power, faster if enough PV power surplus is available)"
ChargeModePV = "PV (Only with PV power surplus)"
ChargeModeNone = "None (Use what is set at the loadpoint)"

Site_Setup = "- Setup site"
Site_Title = "Site title"
Expand Down
29 changes: 15 additions & 14 deletions cmd/configure/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (

"github.com/BurntSushi/toml"
"github.com/cloudfoundry/jibber_jabber"
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/server"
"github.com/evcc-io/evcc/util"
"github.com/evcc-io/evcc/util/templates"
Expand Down Expand Up @@ -149,13 +148,18 @@ func (c *CmdConfigure) flowNewConfigFile() {
filename := DefaultConfigFilename

for ok := true; ok; {
_, err := os.Open(filename)
file, err := os.OpenFile(filename, os.O_WRONLY, 0666)
if errors.Is(err, os.ErrNotExist) {
break
}

if c.askYesNo(c.localizedString("File_Exists", localizeMap{"FileName": filename})) {
break
file.Close()
// in case of permission error, we can't write to the file anyway
if os.IsPermission(err) {
fmt.Println(c.localizedString("File_Permissions", localizeMap{"FileName": filename}))
} else {
if c.askYesNo(c.localizedString("File_Exists", localizeMap{"FileName": filename})) {
break
}
}

filename = c.askValue(question{
Expand Down Expand Up @@ -302,17 +306,14 @@ func (c *CmdConfigure) configureLoadpoints() {
}
}

chargingModes := []string{string(api.ModeOff), string(api.ModeNow), string(api.ModeMinPV), string(api.ModePV)}
chargeModes := []string{
c.localizedString("Loadpoint_ChargeModeOff", nil),
c.localizedString("Loadpoint_ChargeModeNow", nil),
c.localizedString("Loadpoint_ChargeModeMinPV", nil),
c.localizedString("Loadpoint_ChargeModePV", nil),
}
fmt.Println()
modeChoice, _ := c.askChoice(c.localizedString("Loadpoint_DefaultChargeMode", nil), chargeModes)
loadpoint.Mode = chargingModes[modeChoice]
loadpoint.Mode = c.askValue(question{valueType: templates.ParamValueTypeChargeModes, excludeNone: true})

fmt.Println()
loadpoint.ResetOnDisconnect = c.askValue(question{
label: c.localizedString("Loadpoint_ResetOnDisconnect", nil),
valueType: templates.ParamValueTypeBool,
})
c.configuration.AddLoadpoint(loadpoint)

fmt.Println()
Expand Down
20 changes: 19 additions & 1 deletion cmd/configure/survey.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/AlecAivazis/survey/v2"
"github.com/AlecAivazis/survey/v2/terminal"
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/util/templates"
"github.com/thoas/go-funk"
)
Expand Down Expand Up @@ -115,6 +116,7 @@ type question struct {
invalidValues []string
valueType string
mask, required bool
excludeNone bool
}

// askBoolValue asks for a boolean value selection for a given question
Expand All @@ -137,6 +139,22 @@ func (c *CmdConfigure) askValue(q question) string {
return c.askBoolValue(label)
}

if q.valueType == templates.ParamValueTypeChargeModes {
chargingModes := []string{string(api.ModeOff), string(api.ModeNow), string(api.ModeMinPV), string(api.ModePV)}
chargeModes := []string{
c.localizedString("ChargeModeOff", nil),
DerAndereAndi marked this conversation as resolved.
Show resolved Hide resolved
c.localizedString("ChargeModeNow", nil),
c.localizedString("ChargeModeMinPV", nil),
c.localizedString("ChargeModePV", nil),
}
if !q.excludeNone {
chargingModes = append(chargingModes, "")
chargeModes = append(chargeModes, c.localizedString("ChargeModeNone", nil))
}
modeChoice, _ := c.askChoice(c.localizedString("ChargeMode_Question", nil), chargeModes)
return chargingModes[modeChoice]
}

input := ""

var err error
Expand Down Expand Up @@ -174,7 +192,7 @@ func (c *CmdConfigure) askValue(q question) string {
} else {
help += " (" + c.localizedString("Value_Optional", nil) + ")"
}
if q.exampleValue != "" {
if q.exampleValue != nil && q.exampleValue != "" {
help += fmt.Sprintf(" ("+c.localizedString("Value_Sample", nil)+": %s)", q.exampleValue)
}

Expand Down
78 changes: 39 additions & 39 deletions cmd/configure/texts.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,49 +49,49 @@ func (c *CmdConfigure) userFriendlyTexts(param templates.Param) templates.Param
result.ValueType = templates.ParamValueTypeString
}

switch strings.ToLower(result.Name) {
case "title":
result.Name = c.localizedString("UserFriendly_Title_Name", nil)
if result.Help.String(c.lang) == "" {
result.Help.SetString(c.lang, c.localizedString("UserFriendly_Title_Help", nil))
}
case "device":
result.Name = c.localizedString("UserFriendly_Device_Name", nil)
case "baudrate":
result.Name = c.localizedString("UserFriendly_Baudrate_Name", nil)
case "comset":
result.Name = c.localizedString("UserFriendly_ComSet_Name", nil)
case "host":
result.Name = c.localizedString("UserFriendly_Host_Name", nil)
case "port":
result.Name = c.localizedString("UserFriendly_Port_Name", nil)
result.ValueType = templates.ParamValueTypeNumber
case "user":
result.Name = c.localizedString("UserFriendly_User_Name", nil)
case "password":
result.Name = c.localizedString("UserFriendly_Password_Name", nil)
case "capacity":
result.Name = c.localizedString("UserFriendly_Capacity_Name", nil)
if result.Example == "" {
result.Example = "41.5"
type replacements struct {
Name string
Help string
Example string
ValueType string
}
resultNameMap := map[string]replacements{
"title": {Name: "UserFriendly_Title_Name", Help: "UserFriendly_Title_Help"},
"device": {Name: "UserFriendly_Device_Name"},
"baudrate": {Name: "UserFriendly_Baudrate_Name"},
"comset": {Name: "UserFriendly_ComSet_Name"},
"host": {Name: "UserFriendly_Host_Name"},
"port": {Name: "UserFriendly_Port_Name", ValueType: templates.ParamValueTypeNumber},
"user": {Name: "UserFriendly_User_Name"},
"password": {Name: "UserFriendly_Password_Name"},
"capacity": {Name: "UserFriendly_Capacity_Name", Example: "41.5", ValueType: templates.ParamValueTypeFloat},
"vin": {Name: "UserFriendly_Vin_Name", Help: "UserFriendly_Vin_Help"},
"cache": {Name: "UserFriendly_Cache_Name", Help: "UserFriendly_Cache_Help", Example: "5m"},
"mode": {Name: "ChargeMode_Question", ValueType: templates.ParamValueTypeChargeModes},
"minsoc": {Name: "UserFriendly_MinSoC_Name", Help: "UserFriendly_MinSoC_Help", Example: "25", ValueType: templates.ParamValueTypeNumber},
"targetsoc": {Name: "UserFriendly_TargetSoC_Name", Help: "UserFriendly_TargetSoC_Help", Example: "80", ValueType: templates.ParamValueTypeNumber},
"mincurrent": {Name: "UserFriendly_MinCurrent_Name", Help: "UserFriendly_MinCurrent_Help", Example: "6", ValueType: templates.ParamValueTypeNumber},
"maxcurrent": {Name: "UserFriendly_MaxCurrent_Name", Help: "UserFriendly_MaxCurrent_Help", Example: "16", ValueType: templates.ParamValueTypeNumber},
"identifiers": {Name: "UserFriendly_Identifier_Name", Help: "UserFriendly_Identifier_Help"},
"standbypower": {Name: "UserFriendly_StandByPower_Name", Help: "UserFriendly_StandByPower_Help", ValueType: templates.ParamValueTypeNumber},
}

if resultMapItem := resultNameMap[strings.ToLower(result.Name)]; resultMapItem != (replacements{}) {
// always overwrite if defined
if resultMapItem.Name != "" {
result.Name = c.localizedString(resultMapItem.Name, nil)
}
result.ValueType = templates.ParamValueTypeFloat
case "vin":
result.Name = c.localizedString("UserFriendly_Vin_Name", nil)
if result.Help.String(c.lang) == "" {
result.Help.SetString(c.lang, c.localizedString("UserFriendly_Vin_Help", nil))
if resultMapItem.ValueType != "" {
result.ValueType = resultMapItem.ValueType
}
case "identifiers":
result.Name = c.localizedString("UserFriendly_Identifier_Name", nil)
if result.Help.String(c.lang) == "" {
result.Help.SetString(c.lang, c.localizedString("UserFriendly_Identifier_Help", nil))
// only set if empty
if result.Help.String(c.lang) == "" && resultMapItem.Help != "" {
result.Help.SetString(c.lang, c.localizedString(resultMapItem.Help, nil))
}
case "standbypower":
result.Name = c.localizedString("UserFriendly_StandByPower_Name", nil)
if result.Help.String(c.lang) == "" {
result.Help.SetString(c.lang, c.localizedString("UserFriendly_StandByPower_Help", nil))
if result.Example == "" && resultMapItem.Example != "" {
result.Example = resultMapItem.Example
}
result.ValueType = templates.ParamValueTypeNumber
}

return result
}
6 changes: 0 additions & 6 deletions cmd/configure/types.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package configure

import "github.com/evcc-io/evcc/util/templates"

const (
DefaultConfigFilename string = "evcc.yaml"
)
Expand All @@ -12,8 +10,6 @@ func (u UsageChoice) String() string {
return string(u)
}

var ValidModbusChoices = []string{templates.ModbusChoiceRS485, templates.ModbusChoiceTCPIP}

type DeviceClass string

func (c DeviceClass) String() string {
Expand Down Expand Up @@ -42,8 +38,6 @@ const (
DeviceCategoryGuidedSetup DeviceCategory = "guided"
)

var ValidUsageChoices = []DeviceCategory{DeviceCategoryGridMeter, DeviceCategoryPVMeter, DeviceCategoryBatteryMeter, DeviceCategoryChargeMeter}

const (
defaultNameCharger = "wallbox"
defaultNameGridMeter = "grid"
Expand Down
Loading