diff --git a/assets/js/components/Config/PropertyEntry.vue b/assets/js/components/Config/PropertyEntry.vue index a1e5df70d..a1fe5bef9 100644 --- a/assets/js/components/Config/PropertyEntry.vue +++ b/assets/js/components/Config/PropertyEntry.vue @@ -14,7 +14,7 @@ :type="Type" class="me-2" :required="Required" - :validValues="ValidValues" + :choice="Choice" /> @@ -36,7 +36,7 @@ export default { Example: String, Type: String, Mask: Boolean, - ValidValues: Array, + Choice: Array, modelValue: [String, Number, Boolean, Object], }, emits: ["update:modelValue"], diff --git a/assets/js/components/Config/PropertyField.vue b/assets/js/components/Config/PropertyField.vue index 77dd2ca64..ac3f15330 100644 --- a/assets/js/components/Config/PropertyField.vue +++ b/assets/js/components/Config/PropertyField.vue @@ -111,7 +111,7 @@ export default { size: String, scale: Number, required: Boolean, - validValues: { type: Array, default: () => [] }, + choice: { type: Array, default: () => [] }, modelValue: [String, Number, Boolean, Object], }, emits: ["update:modelValue"], @@ -171,15 +171,15 @@ export default { return this.type === "List"; }, select() { - return this.validValues.length > 0; + return this.choice.length > 0; }, selectOptions() { // If the valid values are already in the correct format, return them - if (typeof this.validValues[0] === "object") { - return this.validValues; + if (typeof this.choice[0] === "object") { + return this.choice; } - let values = [...this.validValues]; + let values = [...this.choice]; if (this.icons && !this.required) { values = ["", ...values]; diff --git a/assets/js/components/Config/VehicleModal.vue b/assets/js/components/Config/VehicleModal.vue index 762821544..ba881e97e 100644 --- a/assets/js/components/Config/VehicleModal.vue +++ b/assets/js/components/Config/VehicleModal.vue @@ -313,7 +313,7 @@ export default { }; }, templateParams() { - return (this.template?.Params || []) + const params = (this.template?.Params || []) .filter((p) => !CUSTOM_FIELDS.includes(p.Name)) .map((p) => { if (p.Name === "title" || p.Name === "icon") { @@ -322,6 +322,12 @@ export default { } return p; }); + + // always start with title and icon field + const order = { title: -2, icon: -1 }; + params.sort((a, b) => (order[a.Name] || 0) - (order[b.Name] || 0)); + + return params; }, normalParams() { return this.templateParams.filter((p) => !p.Advanced); diff --git a/assets/js/components/SelectGroup.vue b/assets/js/components/SelectGroup.vue index e6ccadb0e..a746dbb70 100644 --- a/assets/js/components/SelectGroup.vue +++ b/assets/js/components/SelectGroup.vue @@ -21,7 +21,7 @@ export default { props: { id: String, options: Array, - modelValue: [Number, String], + modelValue: [Number, String, Boolean], equalWidth: Boolean, large: Boolean, transparent: Boolean, diff --git a/cmd/configure/helper.go b/cmd/configure/helper.go index d2e994c15..8e2e72ac5 100644 --- a/cmd/configure/helper.go +++ b/cmd/configure/helper.go @@ -444,7 +444,7 @@ func (c *CmdConfigure) processInputConfig(param templates.Param) string { exampleValue: param.Example, help: param.Help.ShortString(c.lang), valueType: param.Type, - validValues: param.ValidValues, + choice: param.Choice, mask: param.IsMasked(), required: param.IsRequired(), }) diff --git a/cmd/configure/survey.go b/cmd/configure/survey.go index be27dbbe9..09268fce3 100644 --- a/cmd/configure/survey.go +++ b/cmd/configure/survey.go @@ -104,7 +104,7 @@ type question struct { label, help string defaultValue, exampleValue string invalidValues []string - validValues []string + choice []string valueType templates.ParamType minNumberValue, maxNumberValue int64 mask, required bool @@ -130,11 +130,11 @@ func (c *CmdConfigure) askParam(p templates.Param) string { } return c.askValue(question{ - label: p.Description.String(c.lang), - valueType: p.Type, - validValues: p.Choice, // TODO proper choice handling - mask: mask, - required: required, + label: p.Description.String(c.lang), + valueType: p.Type, + choice: p.Choice, + mask: mask, + required: required, }) } @@ -155,8 +155,8 @@ func (c *CmdConfigure) askValue(q question) string { if q.valueType == templates.TypeChoice { label := strings.TrimSpace(strings.Join([]string{q.label, c.localizedString("Value_Choice")}, " ")) - idx, _ := c.askChoice(label, q.validValues) - return q.validValues[idx] + idx, _ := c.askChoice(label, q.choice) + return q.choice[idx] } if q.valueType == templates.TypeChargeModes { @@ -181,7 +181,7 @@ func (c *CmdConfigure) askValue(q question) string { return errors.New(c.localizedString("ValueError_Used")) } - if q.validValues != nil && !slices.Contains(q.validValues, value) { + if q.choice != nil && !slices.Contains(q.choice, value) { return errors.New(c.localizedString("ValueError_Invalid")) } diff --git a/templates/definition/charger/demo-charger.yaml b/templates/definition/charger/demo-charger.yaml index 6d959d9cc..9ced91830 100644 --- a/templates/definition/charger/demo-charger.yaml +++ b/templates/definition/charger/demo-charger.yaml @@ -13,7 +13,8 @@ params: description: de: Ladezustand en: Charge status - validvalues: [A, B, C, D, E, F] + type: choice + choice: [A, B, C, D, E, F] default: A - name: power description: diff --git a/templates/definition/charger/stiebel-lwa.yaml b/templates/definition/charger/stiebel-lwa.yaml index b10ce469b..e2cf3ada1 100644 --- a/templates/definition/charger/stiebel-lwa.yaml +++ b/templates/definition/charger/stiebel-lwa.yaml @@ -13,7 +13,8 @@ params: - name: modbus choice: ["tcpip"] - name: tempsource - validvalues: ["", "warmwater"] + type: choice + choice: ["", "warmwater"] description: de: "Temperaturquelle" en: "Temperature source" diff --git a/templates/definition/charger/stiebel-wpm.yaml b/templates/definition/charger/stiebel-wpm.yaml index 78c1ca354..0d7a2692b 100644 --- a/templates/definition/charger/stiebel-wpm.yaml +++ b/templates/definition/charger/stiebel-wpm.yaml @@ -10,7 +10,8 @@ params: - name: modbus choice: ["tcpip"] - name: tempsource - validvalues: ["", "warmwater", "buffer"] + type: choice + choice: ["", "warmwater", "buffer"] description: de: "Temperaturquelle" en: "Temperature source" diff --git a/templates/definition/meter/goodwe-hybrid.yaml b/templates/definition/meter/goodwe-hybrid.yaml index 5cb263fd7..de984aa8c 100644 --- a/templates/definition/meter/goodwe-hybrid.yaml +++ b/templates/definition/meter/goodwe-hybrid.yaml @@ -13,9 +13,8 @@ params: id: 247 - name: battery default: 1 - validvalues: - - 1 - - 2 + type: choice + choice: [1, 2] - name: capacity advanced: true - name: maxacpower diff --git a/templates/definition/meter/kostal-plenticore-gen2.yaml b/templates/definition/meter/kostal-plenticore-gen2.yaml index c8f5efe76..4319a4179 100644 --- a/templates/definition/meter/kostal-plenticore-gen2.yaml +++ b/templates/definition/meter/kostal-plenticore-gen2.yaml @@ -34,7 +34,8 @@ params: description: de: Byte-Reihenfolge (Little/Big) en: Endianness (Little/Big) - validvalues: ["big", "little"] + type: choice + choice: ["little", "big"] default: little advanced: true - name: capacity diff --git a/templates/definition/meter/kostal-plenticore.yaml b/templates/definition/meter/kostal-plenticore.yaml index 815adf992..caac55c6d 100644 --- a/templates/definition/meter/kostal-plenticore.yaml +++ b/templates/definition/meter/kostal-plenticore.yaml @@ -30,7 +30,8 @@ params: description: de: Byte-Reihenfolge (Little/Big) en: Endianness (Little/Big) - validvalues: ["big", "little"] + type: choice + choice: ["little", "big"] default: little advanced: true - name: capacity diff --git a/templates/definition/meter/senec-home.yaml b/templates/definition/meter/senec-home.yaml index c22b7f27f..314e46693 100644 --- a/templates/definition/meter/senec-home.yaml +++ b/templates/definition/meter/senec-home.yaml @@ -11,9 +11,7 @@ params: - name: host - name: schema type: choice - validvalues: - - https - - http + choice: ["https", "http"] default: https - name: capacity advanced: true diff --git a/templates/definition/meter/zendure.yaml b/templates/definition/meter/zendure.yaml index 5f53f2dcf..0136965a8 100644 --- a/templates/definition/meter/zendure.yaml +++ b/templates/definition/meter/zendure.yaml @@ -19,8 +19,8 @@ params: en: "You can find this in the Zendure App in the settings of the device" - name: region type: choice + choice: ["EU", "Global"] default: EU - validvalues: ["EU", "Global"] - name: capacity default: 2 advanced: true diff --git a/templates/definition/tariff/awattar.yaml b/templates/definition/tariff/awattar.yaml index 9e9794a86..27c795a5e 100644 --- a/templates/definition/tariff/awattar.yaml +++ b/templates/definition/tariff/awattar.yaml @@ -9,7 +9,8 @@ group: price params: - name: region example: AT - validvalues: ["DE", "AT"] + type: choice + choice: ["DE", "AT"] - preset: tariff-base render: | type: awattar diff --git a/templates/definition/tariff/elering.yaml b/templates/definition/tariff/elering.yaml index faf7f53a9..9656c76d0 100644 --- a/templates/definition/tariff/elering.yaml +++ b/templates/definition/tariff/elering.yaml @@ -12,7 +12,8 @@ group: price params: - name: region example: ee - validvalues: ["ee", "lt", "lv", "fi"] + type: choice + choice: ["ee", "lt", "lv", "fi"] - preset: tariff-base render: | type: elering diff --git a/templates/definition/tariff/energinet.yaml b/templates/definition/tariff/energinet.yaml index 3f45119e6..280877aa3 100644 --- a/templates/definition/tariff/energinet.yaml +++ b/templates/definition/tariff/energinet.yaml @@ -10,7 +10,8 @@ group: price params: - name: region example: dk1 - validvalues: ["dk1", "dk2"] + type: choice + choice: ["dk1", "dk2"] - preset: tariff-base render: | type: energinet diff --git a/templates/definition/tariff/energy-charts-api.yaml b/templates/definition/tariff/energy-charts-api.yaml index a60382232..5b364ca03 100644 --- a/templates/definition/tariff/energy-charts-api.yaml +++ b/templates/definition/tariff/energy-charts-api.yaml @@ -9,9 +9,9 @@ requirements: group: price params: - name: bzn - type: string + type: choice required: true - validvalues: + choice: [ "AT", "BE", diff --git a/templates/definition/tariff/enever.yaml b/templates/definition/tariff/enever.yaml index 5935e1f16..2694cfd66 100644 --- a/templates/definition/tariff/enever.yaml +++ b/templates/definition/tariff/enever.yaml @@ -11,7 +11,8 @@ params: - name: token required: true - name: provider - validvalues: + type: choice + choice: [ "", "AA", diff --git a/templates/definition/tariff/nordpool.yaml b/templates/definition/tariff/nordpool.yaml index f569537a9..698aedd5e 100644 --- a/templates/definition/tariff/nordpool.yaml +++ b/templates/definition/tariff/nordpool.yaml @@ -10,7 +10,8 @@ group: price params: - name: region example: GER - validvalues: + type: choice + choice: [ "EE", "LT", @@ -38,7 +39,8 @@ params: ] - name: currency default: EUR - validvalues: ["DKK", "EUR", "NOK", "PLN", "RON", "SEK"] + type: choice + choice: ["DKK", "EUR", "NOK", "PLN", "RON", "SEK"] - preset: tariff-base render: | type: custom diff --git a/templates/definition/tariff/octopus-productcode.yaml b/templates/definition/tariff/octopus-productcode.yaml index 5b033d724..bc8108610 100644 --- a/templates/definition/tariff/octopus-productcode.yaml +++ b/templates/definition/tariff/octopus-productcode.yaml @@ -13,8 +13,8 @@ params: de: "Der Tarifcode für Ihren Energievertrag. Stellen Sie sicher, dass dieser auf Ihren Importtarifcode eingestellt ist." en: "The tariff code for your energy contract. Make sure this is set to your import tariff code." - name: region - type: string - validvalues: ["A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P"] + type: choice + choice: ["A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P"] required: true help: de: "Die DNO-Region, in der Sie sich befinden. Weitere Informationen: https://www.energy-stats.uk/dno-region-codes-explained/" diff --git a/templates/definition/tariff/spottyenergy.yaml b/templates/definition/tariff/spottyenergy.yaml index 61b4909be..b0c859600 100644 --- a/templates/definition/tariff/spottyenergy.yaml +++ b/templates/definition/tariff/spottyenergy.yaml @@ -15,7 +15,8 @@ params: en: "You can get your contract id from the customer portal https://i.spottyenergie.at/" - name: pricetype default: CONSUMPTION - validvalues: ["MARKET", "CONSUMPTION", "GENERATION"] + type: choice + choice: ["MARKET", "CONSUMPTION", "GENERATION"] required: true help: de: "Preistyp, entweder Börsenpreis, Verbrauchspreis oder Einspeisevergütung (falls vereinbart), siehe https://www.spottyenergie.at/blog/energie-smart-produzieren" diff --git a/templates/definition/vehicle/bmw.yaml b/templates/definition/vehicle/bmw.yaml index ec572189a..b4ac04d33 100644 --- a/templates/definition/vehicle/bmw.yaml +++ b/templates/definition/vehicle/bmw.yaml @@ -15,7 +15,8 @@ params: description: de: Region en: Region - validvalues: ["NA", "EU"] + type: choice + choice: ["EU", "NA"] default: EU advanced: true - name: hcaptcha diff --git a/templates/definition/vehicle/ford.yaml b/templates/definition/vehicle/ford.yaml index 088f96921..ddab0d27d 100644 --- a/templates/definition/vehicle/ford.yaml +++ b/templates/definition/vehicle/ford.yaml @@ -7,8 +7,9 @@ params: - name: vin example: WF0FXX... - name: domain + type: choice + choice: ["com", "de"] default: com - validvalues: ["de", "com"] render: | type: ford {{ include "vehicle-base" . }} diff --git a/templates/definition/vehicle/mercedes.yaml b/templates/definition/vehicle/mercedes.yaml index 83914fbfd..9e3f07f8b 100644 --- a/templates/definition/vehicle/mercedes.yaml +++ b/templates/definition/vehicle/mercedes.yaml @@ -13,7 +13,8 @@ params: required: true - name: region required: true - validvalues: [EMEA, APAC, NORAM] + type: choice + choice: ["EMEA", "APAC", "NORAM"] default: EMEA - name: accessToken required: true diff --git a/templates/definition/vehicle/mg.yaml b/templates/definition/vehicle/mg.yaml index 2a55b41c4..498f1cf0f 100644 --- a/templates/definition/vehicle/mg.yaml +++ b/templates/definition/vehicle/mg.yaml @@ -9,7 +9,8 @@ params: description: de: Region en: Region - validvalues: ["EU", "AU"] + type: choice + choice: ["EU", "AU"] default: EU advanced: true render: | diff --git a/templates/definition/vehicle/mini.yaml b/templates/definition/vehicle/mini.yaml index e72ad4f05..56f28c658 100644 --- a/templates/definition/vehicle/mini.yaml +++ b/templates/definition/vehicle/mini.yaml @@ -15,7 +15,8 @@ params: description: de: Region en: Region - validvalues: ["NA", "EU"] + type: choice + choice: ["EU", "NA"] default: EU advanced: true - name: hcaptcha diff --git a/util/templates/defaults.yaml b/util/templates/defaults.yaml index cef742128..1db8a1057 100644 --- a/util/templates/defaults.yaml +++ b/util/templates/defaults.yaml @@ -222,7 +222,8 @@ params: de: "'de' für Deutsch und 'en' für Englisch" en: "'en' for English and 'de' for German" default: en - validvalues: ["de", "en"] + type: choice + choice: ["en", "de"] - name: icon description: de: Icon @@ -231,7 +232,7 @@ params: de: "Icon in der Benutzeroberfläche" en: "Icon as shown in user interface" type: choice - validvalues: + choice: - car - bike - bus diff --git a/util/templates/types.go b/util/templates/types.go index d0fa22730..9b834192c 100644 --- a/util/templates/types.go +++ b/util/templates/types.go @@ -187,7 +187,6 @@ type Param struct { Values []string `json:",omitempty"` // user provided list of values e.g. for Type "list" Usages []string `json:",omitempty"` // restrict param to these usage types, e.g. "battery" for home battery capacity Type ParamType // string representation of the value type, "string" is default - ValidValues []string `json:",omitempty"` // list of valid values the user can provide Choice []string `json:",omitempty"` // defines a set of choices, e.g. "grid", "pv", "battery", "charge" for "usage" AllInOne *bool `json:"-"` // defines if the defined usages can all be present in a single device