fix: device color MQTT encoding (#30168)
This commit is contained in:
parent
8e0d991455
commit
cf7a95b61a
11 changed files with 107 additions and 26 deletions
20
ui/colors.go
20
ui/colors.go
|
|
@ -3,15 +3,22 @@ package ui
|
|||
|
||||
import (
|
||||
"maps"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/evcc-io/evcc/core/keys"
|
||||
"github.com/evcc-io/evcc/server/db/settings"
|
||||
)
|
||||
|
||||
// DeviceColor is the MQTT-safe publish format (map keys would leak into topic segments).
|
||||
type DeviceColor struct {
|
||||
Title string `json:"title"`
|
||||
Color string `json:"color"`
|
||||
}
|
||||
|
||||
var colorsMu sync.RWMutex
|
||||
|
||||
// GetDeviceColors returns the persisted title→hex map (never nil).
|
||||
func GetDeviceColors() map[string]string {
|
||||
colorsMu.RLock()
|
||||
defer colorsMu.RUnlock()
|
||||
|
|
@ -20,7 +27,6 @@ func GetDeviceColors() map[string]string {
|
|||
return m
|
||||
}
|
||||
|
||||
// SaveDeviceColors persists the title→hex map.
|
||||
func SaveDeviceColors(m map[string]string) error {
|
||||
colorsMu.Lock()
|
||||
defer colorsMu.Unlock()
|
||||
|
|
@ -28,3 +34,13 @@ func SaveDeviceColors(m map[string]string) error {
|
|||
maps.Copy(clean, m)
|
||||
return settings.SetJson(keys.DeviceColors, clean)
|
||||
}
|
||||
|
||||
func DeviceColorList() []DeviceColor {
|
||||
m := GetDeviceColors()
|
||||
list := make([]DeviceColor, 0, len(m))
|
||||
for title, color := range m {
|
||||
list = append(list, DeviceColor{Title: title, Color: color})
|
||||
}
|
||||
slices.SortFunc(list, func(a, b DeviceColor) int { return strings.Compare(a.Title, b.Title) })
|
||||
return list
|
||||
}
|
||||
|
|
|
|||
45
ui/colors_test.go
Normal file
45
ui/colors_test.go
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/evcc-io/evcc/server/db"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func setupDB(t *testing.T) {
|
||||
t.Helper()
|
||||
require.NoError(t, db.NewInstance("sqlite", filepath.Join(t.TempDir(), "test.db")))
|
||||
}
|
||||
|
||||
func TestDeviceColors_RoundTrip(t *testing.T) {
|
||||
setupDB(t)
|
||||
|
||||
in := map[string]string{"WP-SG+": "#2563EB", "Heizung": "#DC2626"}
|
||||
require.NoError(t, SaveDeviceColors(in))
|
||||
|
||||
assert.Equal(t, in, GetDeviceColors())
|
||||
}
|
||||
|
||||
func TestDeviceColors_EmptyWhenAbsent(t *testing.T) {
|
||||
setupDB(t)
|
||||
assert.Empty(t, GetDeviceColors())
|
||||
}
|
||||
|
||||
func TestDeviceColorList_SortedAndSafe(t *testing.T) {
|
||||
setupDB(t)
|
||||
|
||||
require.NoError(t, SaveDeviceColors(map[string]string{
|
||||
"WP-SG+": "#2563EB",
|
||||
"Heizung": "#DC2626",
|
||||
"Carport": "#10B981",
|
||||
}))
|
||||
|
||||
assert.Equal(t, []DeviceColor{
|
||||
{Title: "Carport", Color: "#10B981"},
|
||||
{Title: "Heizung", Color: "#DC2626"},
|
||||
{Title: "WP-SG+", Color: "#2563EB"},
|
||||
}, DeviceColorList())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue