Templates: fix modbus defaults not applied to configuration (#3635)

This commit is contained in:
andig 2022-06-16 17:26:49 +02:00 • committed by GitHub
parent 131d650ee7
commit 7335af2543
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 91 additions and 95 deletions

View file

@ -49,7 +49,7 @@ func TestTemplates(t *testing.T) {
} else {
values[templates.ModbusKeyRS485TCPIP] = true
}
values = tmpl.ModbusValues(templates.TemplateRenderModeInstance, true, values)
tmpl.ModbusValues(templates.TemplateRenderModeInstance, values)
}
templates.RenderTest(t, tmpl, values, func(values map[string]interface{}) {

View file

@ -1,7 +1,6 @@
package configure
import (
"bufio"
"fmt"
"sort"
"strings"
@ -15,7 +14,8 @@ import (
"gopkg.in/yaml.v3"
)
// processDeviceSelection processes the the user selected device, check if it is an actual device and make sure the requirements are set
// processDeviceSelection processes the user-selected device, checks
// if it's an actual device and makes sure the requirements are set
func (c *CmdConfigure) processDeviceSelection(deviceCategory DeviceCategory) (templates.Template, error) {
templateItem := c.selectItem(deviceCategory)
@ -30,7 +30,8 @@ func (c *CmdConfigure) processDeviceSelection(deviceCategory DeviceCategory) (te
return templateItem, nil
}
// processDeviceValues processes the user provided values, create a device configuration and check if it is a valid device
// processDeviceValues processes the user provided values, creates
// a device configuration and check if it is a valid device
func (c *CmdConfigure) processDeviceValues(values map[string]interface{}, templateItem templates.Template, device device, deviceCategory DeviceCategory) (device, error) {
c.addedDeviceIndex++
@ -45,12 +46,14 @@ func (c *CmdConfigure) processDeviceValues(values map[string]interface{}, templa
}
}
categoryWithUsage := deviceCategory == DeviceCategoryPVMeter || deviceCategory == DeviceCategoryBatteryMeter || deviceCategory == DeviceCategoryGridMeter
var categoryWithUsage bool
fmt.Println()
if categoryWithUsage {
switch deviceCategory {
case DeviceCategoryPVMeter, DeviceCategoryBatteryMeter, DeviceCategoryGridMeter:
categoryWithUsage = true
fmt.Println(c.localizedString("TestingDevice_TitleUsage", localizeMap{"Device": templateItem.Title(), "Usage": deviceCategory.String()}))
} else {
default:
fmt.Println(c.localizedString("TestingDevice_Title", localizeMap{"Device": templateItem.Title()}))
}
@ -81,24 +84,8 @@ func (c *CmdConfigure) processDeviceValues(values map[string]interface{}, templa
templateItem.Params = append(templateItem.Params, templates.Param{Name: "name", Value: device.Name})
if !c.expandedMode {
for index, param := range templateItem.Params {
// reduce help texts to one line and add ...
help := param.Help.String(c.lang)
if help != "" {
scanner := bufio.NewScanner(strings.NewReader(help))
line := 0
for scanner.Scan() {
if line == 0 {
help = scanner.Text()
} else {
help += "..."
break
}
}
if help != param.Help.String(c.lang) {
templateItem.Params[index].Help.SetString(c.lang, help)
}
}
for _, param := range templateItem.Params {
param.Help.Shorten(c.lang)
}
b, err := templateItem.RenderProxyWithValues(values, c.lang)
@ -115,6 +102,7 @@ func (c *CmdConfigure) processDeviceValues(values map[string]interface{}, templa
templateItem.Render = fmt.Sprintf("name: {{ .name }}\n%s", templateItem.Render)
}
}
b, _, err := templateItem.RenderResult(templates.TemplateRenderModeInstance, values)
if err != nil {
c.addedDeviceIndex--
@ -470,11 +458,7 @@ func (c *CmdConfigure) processParams(templateItem *templates.Template, deviceCat
}
default:
if !c.advancedMode && param.Advanced {
continue
}
if param.Deprecated {
if param.Advanced && !c.advancedMode || param.Deprecated {
continue
}
@ -493,7 +477,9 @@ func (c *CmdConfigure) processParams(templateItem *templates.Template, deviceCat
}
}
additionalConfig[param.Name] = nonEmptyValues
default:
// TODO make processInputConfig aware of default values added by template
if value := c.processInputConfig(param); value != "" {
additionalConfig[param.Name] = value
}
@ -593,8 +579,10 @@ func (c *CmdConfigure) processModbusConfig(templateItem *templates.Template, dev
values := make(map[string]interface{})
templateItem.Params[modbusIndex].Value = choiceTypes[index]
// add the interface type specific modbus params
templateItem.ModbusParams(choiceTypes[index], values)
// Update the modbus default values
_ = templateItem.ModbusValues(templates.TemplateRenderModeInstance, true, values)
// update the modbus default values
templateItem.ModbusValues(templates.TemplateRenderModeInstance, values)
}

View file

@ -57,28 +57,35 @@ type DeviceCategoryData struct {
var DeviceCategories = map[DeviceCategory]DeviceCategoryData{
DeviceCategoryCharger: {
class: DeviceClassCharger,
defaultName: defaultNameCharger},
defaultName: defaultNameCharger,
},
DeviceCategoryGuidedSetup: {
class: DeviceClassMeter},
class: DeviceClassMeter,
},
DeviceCategoryGridMeter: {
class: DeviceClassMeter,
categoryFilter: DeviceCategoryGridMeter,
defaultName: defaultNameGridMeter},
defaultName: defaultNameGridMeter,
},
DeviceCategoryPVMeter: {
class: DeviceClassMeter,
categoryFilter: DeviceCategoryPVMeter,
defaultName: defaultNamePVMeter},
defaultName: defaultNamePVMeter,
},
DeviceCategoryBatteryMeter: {
class: DeviceClassMeter,
categoryFilter: DeviceCategoryBatteryMeter,
defaultName: defaultNameBatteryMeter},
defaultName: defaultNameBatteryMeter,
},
DeviceCategoryVehicle: {
class: DeviceClassVehicle,
defaultName: defaultNameVehicle},
defaultName: defaultNameVehicle,
},
DeviceCategoryChargeMeter: {
class: DeviceClassMeter,
categoryFilter: DeviceCategoryChargeMeter,
defaultName: defaultNameChargeMeter},
defaultName: defaultNameChargeMeter,
},
}
type localizeMap map[string]interface{}

View file

@ -48,7 +48,7 @@ func TestTemplates(t *testing.T) {
} else {
values[templates.ModbusKeyRS485TCPIP] = true
}
values = tmpl.ModbusValues(templates.TemplateRenderModeInstance, true, values)
tmpl.ModbusValues(templates.TemplateRenderModeInstance, values)
}
templates.RenderTest(t, tmpl, values, func(values map[string]interface{}) {

View file

@ -181,18 +181,6 @@ func (t *Template) Defaults(renderMode string) map[string]interface{} {
return values
}
// Update the default value of a param
//
// Used for modbus params, which are dynamically added after selecting the interface
func (t *Template) SetParamDefault(name string, value string) {
for i, p := range t.Params {
if p.Name == name {
t.Params[i].Default = value
return
}
}
}
// return the param with the given name
func (t *Template) ParamByName(name string) (int, Param) {
for i, p := range t.Params {
@ -292,7 +280,7 @@ func (t *Template) RenderResult(renderMode string, other map[string]interface{})
return nil, values, err
}
values = t.ModbusValues(renderMode, false, values)
t.ModbusValues(renderMode, values)
// add the common templates
for _, v := range t.ConfigDefaults.Presets {

View file

@ -1,12 +1,10 @@
package templates
import (
"bufio"
"bytes"
_ "embed"
"fmt"
"regexp"
"strings"
"text/template"
"github.com/Masterminds/sprig/v3"
@ -53,7 +51,7 @@ func (t *Template) RenderDocumentation(product Product, values map[string]interf
}
modbusData := map[string]interface{}{}
modbusData = t.ModbusValues(TemplateRenderModeDocs, true, modbusData)
t.ModbusValues(TemplateRenderModeDocs, modbusData)
modbusOut := new(bytes.Buffer)
@ -70,31 +68,16 @@ func (t *Template) RenderDocumentation(product Product, values map[string]interf
var hasAdvancedParam bool
var newParams []Param
for _, param := range t.Params {
// reduce help texts to one line and add ...
help := param.Help.String(lang)
if help != "" {
scanner := bufio.NewScanner(strings.NewReader(help))
line := 0
for scanner.Scan() {
line++
if line == 1 {
help = scanner.Text()
} else {
help += "..."
break
}
}
if help != param.Help.String(lang) {
param.Help.SetString(lang, help)
}
}
param.Help.Shorten(lang)
if param.Deprecated || param.Name == ParamUsage {
continue
}
if param.Advanced {
hasAdvancedParam = true
}
newParams = append(newParams, param)
}
t.Params = newParams

View file

@ -34,11 +34,11 @@ func (t *Template) ModbusParams(modbusType string, values map[string]interface{}
t.Params = append(modbusParams, t.Params...)
}
// set the modbus values required from modbus.tpl and and the template to the render
func (t *Template) ModbusValues(renderMode string, setDefaults bool, values map[string]interface{}) map[string]interface{} {
// ModbusValues adds the values required for modbus.tpl to the value map
func (t *Template) ModbusValues(renderMode string, values map[string]interface{}) {
choices := t.ModbusChoices()
if len(choices) == 0 {
return values
return
}
// only add the template once, when testing multiple usages, it might already be present
@ -46,10 +46,6 @@ func (t *Template) ModbusValues(renderMode string, setDefaults bool, values map[
t.Render = fmt.Sprintf("%s\n%s", t.Render, modbusTmpl)
}
if !setDefaults {
return values
}
modbusConfig := t.ConfigDefaults.Modbus
_, modbusParam := t.ParamByName(ParamModbus)
@ -58,9 +54,20 @@ func (t *Template) ModbusValues(renderMode string, setDefaults bool, values map[
modbusInterfaces = append(modbusInterfaces, modbusConfig.Interfaces[choice]...)
}
// set default interface type
if len(modbusInterfaces) == 1 {
values[ParamModbus] = modbusInterfaces[0]
}
for _, iface := range modbusInterfaces {
typeParams := modbusConfig.Types[iface].Params
for _, p := range typeParams {
// don't overwrite custom values
if values[p.Name] != nil {
continue
}
values[p.Name] = p.DefaultValue(renderMode)
var defaultValue string
@ -84,21 +91,13 @@ func (t *Template) ModbusValues(renderMode string, setDefaults bool, values map[
}
}
if defaultValue == "" {
continue
}
if renderMode == TemplateRenderModeInstance {
t.SetParamDefault(p.Name, defaultValue)
} else {
if defaultValue != "" {
values[p.Name] = defaultValue
}
}
if renderMode == TemplateRenderModeDocs {
values[iface] = true
}
}
return values
}

View file

@ -1,6 +1,10 @@
package templates
import "reflect"
import (
"bufio"
"reflect"
"strings"
)
const (
ParamUsage = "usage"
@ -79,7 +83,7 @@ var predefinedTemplateProperties = []string{"type", "template", "name",
ModbusKeyTCPIP, ModbusKeyRS485Serial, ModbusKeyRS485TCPIP,
}
// language specific texts
// TextLanguage contains language-specific texts
type TextLanguage struct {
Generic string // language independent
DE string // german text
@ -99,7 +103,7 @@ func (t *TextLanguage) String(lang string) string {
return t.DE
}
func (t *TextLanguage) SetString(lang, value string) {
func (t *TextLanguage) set(lang, value string) {
switch lang {
case "de":
t.DE = value
@ -110,6 +114,33 @@ func (t *TextLanguage) SetString(lang, value string) {
}
}
// Shorten reduces help texts to one line and adds ...
func (t *TextLanguage) Shorten(lang string) {
help := t.String(lang)
if help == "" {
return
}
scanner := bufio.NewScanner(strings.NewReader(help))
var line int
var short string
for scanner.Scan() {
line++
if line == 1 {
short = scanner.Text()
} else {
short += "..."
break
}
}
if help != short {
t.set(lang, short)
}
}
// Update the language specific texts
//
// always true to always update if the new value is not empty
@ -261,7 +292,7 @@ type Product struct {
// TemplateDefinition contains properties of a device template
type TemplateDefinition struct {
Template string
Covers []string // list of covered outdated tempate names
Covers []string // list of covered outdated template names
Products []Product // list of products this template is compatible with
Capabilities []string
Requirements Requirements