Templates: fix modbus defaults not applied to configuration (#3635)
This commit is contained in:
parent
131d650ee7
commit
7335af2543
8 changed files with 91 additions and 95 deletions
|
|
@ -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{}) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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{}
|
||||
|
|
|
|||
|
|
@ -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{}) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue