More configure flow improvements (#2005)

- Added Tinkerforge Warp help texts to make it clear that the MQTT host and port need to be added
- Allow to define linked templates in guided setup to be added multiple times, e.g. multiple SMA PV or Battery inverters with an SMA Home Manager setup
- Allow to exclude a linked template, if devices are added of another linked template, e.g. don't ask for SMA PV inverters if an SMA Energy Meter is added
- Various other changes
This commit is contained in:
Andreas Linde 2021-12-09 22:29:41 +01:00 • committed by GitHub
parent a2d209088a
commit 984392d047
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 113 additions and 43 deletions

View file

@ -84,7 +84,7 @@ func (d *DeviceTest) testCharger(v interface{}) (DeviceTestResult, error) {
return DeviceTestResultInvalid, err
}
} else {
return DeviceTestResultInvalid, errors.New("Selected device is not a wallbox!")
return DeviceTestResultInvalid, errors.New("selected device is not a wallbox!")
}
if v, ok := v.(api.Meter); ok {
@ -116,11 +116,11 @@ func (d *DeviceTest) testMeter(deviceCategory DeviceCategory, v interface{}) (De
return DeviceTestResultInvalid, err
}
} else {
return DeviceTestResultInvalid, errors.New("Selected device is not a battery meter!")
return DeviceTestResultInvalid, errors.New("selected device is not a battery meter!")
}
}
} else {
return DeviceTestResultInvalid, errors.New("Selected device is not a meter!")
return DeviceTestResultInvalid, errors.New("selected device is not a meter!")
}
return DeviceTestResultValid, nil
@ -135,7 +135,7 @@ func (d *DeviceTest) testVehicle(v interface{}) (DeviceTestResult, error) {
}
}
} else {
return DeviceTestResultInvalid, errors.New("Selected device is not a vehicle!")
return DeviceTestResultInvalid, errors.New("selected device is not a vehicle!")
}
return DeviceTestResultValid, nil

View file

@ -96,51 +96,89 @@ func (c *CmdConfigure) configureDeviceGuidedSetup() {
func (c *CmdConfigure) configureLinkedTypes(templateItem templates.Template) {
linkedTemplates := templateItem.GuidedSetup.Linked
deviceOfTemplateAdded := make(map[string]bool)
if linkedTemplates == nil {
return
}
for _, linkedTemplate := range linkedTemplates {
if linkedTemplate.ExcludeTemplate != "" {
// don't process this linked template if a referenced exclude template was added
if deviceOfTemplateAdded[linkedTemplate.ExcludeTemplate] {
continue
}
}
linkedTemplateItem, err := templates.ByTemplate(linkedTemplate.Template, string(DeviceClassMeter))
if err != nil {
fmt.Println("Error: " + err.Error())
return
}
if len(linkedTemplateItem.Params) == 0 || linkedTemplate.Usage == "" {
break
}
category := DeviceCategory(linkedTemplate.Usage)
localizeMap := localizeMap{
"Linked": linkedTemplateItem.Description,
"Article": DeviceCategories[category].article,
"Additional": DeviceCategories[category].additional,
"Category": DeviceCategories[category].title,
}
fmt.Println()
if !c.askYesNo(c.localizedString("AddLinkedDeviceInCategory", localizeMap)) {
continue
}
for ok := true; ok; {
deviceItem := device{}
linkedTemplateItem, err := templates.ByTemplate(linkedTemplate.Template, string(DeviceClassMeter))
if err != nil {
fmt.Println("Error: " + err.Error())
return
}
if len(linkedTemplateItem.Params) == 0 || linkedTemplate.Usage == "" {
return
if added := c.configureLinkedTemplate(linkedTemplateItem, category); added {
deviceOfTemplateAdded[linkedTemplate.Template] = true
}
category := DeviceCategory(linkedTemplate.Usage)
fmt.Println()
if !c.askYesNo(c.localizedString("AddLinkedDeviceInCategory", localizeMap{"Linked": linkedTemplateItem.Description, "Article": DeviceCategories[category].article, "Category": DeviceCategories[category].title})) {
if !linkedTemplate.Multiple {
break
}
values := c.processConfig(linkedTemplateItem.Params, category)
deviceItem, err = c.processDeviceValues(values, linkedTemplateItem, deviceItem, category)
if err != nil {
if !errors.Is(err, c.errDeviceNotValid) {
fmt.Println()
fmt.Println(err)
}
fmt.Println()
if c.askConfigFailureNextStep() {
continue
}
} else {
c.configuration.AddDevice(deviceItem, category)
fmt.Println()
fmt.Println(linkedTemplateItem.Description + " " + c.localizedString("Device_Added", nil))
fmt.Println()
if !c.askYesNo(c.localizedString("AddAnotherLinkedDeviceInCategory", localizeMap)) {
break
}
break
}
}
fmt.Println("DONE")
}
// configureLinkedTemplate lets the user configure a device that is marked as being linked to a guided device
// returns true if a device was added
func (c *CmdConfigure) configureLinkedTemplate(template templates.Template, category DeviceCategory) bool {
for ok := true; ok; {
deviceItem := device{}
values := c.processConfig(template.Params, category)
deviceItem, err := c.processDeviceValues(values, template, deviceItem, category)
if err != nil {
if !errors.Is(err, c.errDeviceNotValid) {
fmt.Println()
fmt.Println(err)
}
fmt.Println()
if c.askConfigFailureNextStep() {
continue
}
} else {
c.configuration.AddDevice(deviceItem, category)
fmt.Println()
fmt.Println(template.Description + " " + c.localizedString("Device_Added", nil))
return true
}
break
}
return false
}
// configureDeviceCategory lets the user select and configure a device from a specific category

View file

@ -15,7 +15,8 @@ ItemNotPresent = "Mein Gerät ist nicht in der Liste"
AddDeviceInCategory = "Möchtest du {{ .Article }} {{ .Category }} hinzufügen?"
AddAnotherDeviceInCategory = "Möchtest du noch {{ .Additional }} {{ .Category }} hinzufügen?"
AddLinkedDeviceInCategory = "Möchtest du '{{ .Linked }}' als {{ .Article }} {{ .Category }} hinzufügen?"
AddLinkedDeviceInCategory = "Möchtest du ein '{{ .Linked }}' Gerät als {{ .Article }} {{ .Category }} hinzufügen?"
AddAnotherLinkedDeviceInCategory = "Möchtest du noch ein '{{ .Linked }}' Gerät als {{ .Article }} {{ .Category }} hinzufügen?"
Error = "Fehler: {{ .Error }}"
Error_ItemNotPresent = "Gerät nicht vorhanden"

View file

@ -15,7 +15,8 @@ ItemNotPresent = "My device is not in this list"
AddDeviceInCategory = "Do you want to add {{ .Article }} {{ .Category }}?"
AddAnotherDeviceInCategory = "Do you want to add {{ .Additional }} {{ .Category }}?"
AddLinkedDeviceInCategory = "Do you want to add '{{ .Linked }}' as {{ .Article }} {{ .Category }}?"
AddLinkedDeviceInCategory = "Do you want to add a '{{ .Linked }}' device as {{ .Article }} {{ .Category }}?"
AddAnotherLinkedDeviceInCategory = "Do you want to add another '{{ .Linked }}' device as {{ .Article }} {{ .Category }}?"
Error = "Error: {{ .Error }}"
Error_ItemNotPresent = "Device not present"

View file

@ -50,6 +50,16 @@ Allows to define a list of meter devices that are typically installed with this
- `pv`: for pv inverter/meter
- `battery`: for battery inverter/meter
#### `multiple`
`multiple:true` to define that multiple devices of this template can be added
#### `excludetemplate`
`excludetemplate` defines a linked device `template` value. If defined and a device of the linked template is added, then this linked template won't be considered in the flow
Example Use Case: With SMA Home Manager, there can be a SMA Energy Meter used for getting the PV generation or multiple SMA PV inverters. But never both together. So if the used added an SMA Energy Meter, then the flow shoudn't ask for SMA PV inverters.
## `requirements`
`requirements` provides an option to define various requirements / dependencies that need to be setup

View file

@ -5,6 +5,7 @@ params:
required: true
- name: pin
required: true
mask: true
render: |
type: nrgkick-bluetooth
mac: {{ .mac }}

View file

@ -9,8 +9,14 @@ params:
- name: host
required: true
example: 192.0.2.2
help:
de: Die IP Adresse oder der Hostname des MQTT Brokers
en: The IP address or hostname of the MQTT broker
- name: port
default: 1883
help:
de: Der Port des MQTT Brokers
en: The port of the MQTT broker
- name: topic
default: warp
- name: timeout

View file

@ -9,8 +9,14 @@ params:
- name: host
required: true
example: 192.0.2.2
help:
de: Die IP Adresse oder der Hostname des MQTT Brokers
en: The IP address or hostname of the MQTT broker
- name: port
default: 1883
help:
de: Der Port des MQTT Brokers
en: The port of the MQTT broker
- name: topic
default: warp
- name: timeout

View file

@ -7,6 +7,7 @@ params:
required: true
- name: password
required: true
mask: true
render: |
type: custom
power:

View file

@ -9,8 +9,11 @@ guidedsetup:
usage: pv
- template: sma-inverter
usage: pv
multiple: true
excludetemplate: sma-energy-meter
- template: sma-inverter
usage: battery
multiple: true
params:
- name: usage
choice: ["grid"]

View file

@ -3,6 +3,7 @@ description: Fiat
paramsbase: vehicle
params:
- name: pin
mask: true
- name: vin
example: ZFAE...
- name: capacity

View file

@ -1,7 +1,7 @@
type: template
template: tinkerforge-warp-pro
description: TinkerForge WARP Charger Pro
host: 192.0.2.2
port: 1883
host: 192.0.2.2 # Die IP Adresse oder der Hostname des MQTT Brokers
port: 1883 # Der Port des MQTT Brokers
topic: warp
timeout: 30s

View file

@ -1,7 +1,7 @@
type: template
template: tinkerforge-warp
description: TinkerForge WARP Charger
host: 192.0.2.2
port: 1883
host: 192.0.2.2 # Die IP Adresse oder der Hostname des MQTT Brokers
port: 1883 # Der Port des MQTT Brokers
topic: warp
timeout: 30s

View file

@ -100,8 +100,10 @@ type GuidedSetup struct {
// Linked Template
type LinkedTemplate struct {
Template string
Usage string // usage: "grid", "pv", "battery"
Template string
Usage string // usage: "grid", "pv", "battery"
Multiple bool // if true, multiple instances of this template can be added
ExcludeTemplate string // only consider this if no device of the named linked template was added
}
// Param is a proxy template parameter