HEMS: add "smartgrid" session logging (#25907)
This commit is contained in:
parent
73f468e4c5
commit
381573b0eb
33 changed files with 915 additions and 215 deletions
|
|
@ -17,12 +17,14 @@ var (
|
|||
sessions Sessions
|
||||
)
|
||||
|
||||
func Init() error {
|
||||
err := db.Instance.AutoMigrate(new(Session))
|
||||
if err == nil {
|
||||
err = db.Instance.Find(&sessions).Error
|
||||
}
|
||||
return err
|
||||
func init() {
|
||||
db.Register(func() error {
|
||||
if err := db.Instance.AutoMigrate(new(Session)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return db.Instance.Find(&sessions).Error
|
||||
})
|
||||
}
|
||||
|
||||
// NewStore creates a session store
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
package session
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/message"
|
||||
)
|
||||
|
||||
func TestFormatValue(t *testing.T) {
|
||||
mp := message.NewPrinter(language.Make("en"))
|
||||
|
||||
f := 1.2345
|
||||
assert.Equal(t, "1.234", formatValue(mp, f, 3))
|
||||
assert.Equal(t, "1.234", formatValue(mp, &f, 3))
|
||||
}
|
||||
|
|
@ -2,20 +2,11 @@ package session
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/util/locale"
|
||||
"github.com/fatih/structs"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/message"
|
||||
"golang.org/x/text/number"
|
||||
csvutil "github.com/evcc-io/evcc/util/csv"
|
||||
)
|
||||
|
||||
// Session is a single charging session
|
||||
|
|
@ -42,112 +33,9 @@ type Sessions []Session
|
|||
|
||||
var _ api.CsvWriter = (*Sessions)(nil)
|
||||
|
||||
func (t *Sessions) writeHeader(ctx context.Context, ww *csv.Writer) error {
|
||||
localizer := locale.Localizer
|
||||
if val := ctx.Value(locale.Locale).(string); val != "" {
|
||||
localizer = i18n.NewLocalizer(locale.Bundle, val, locale.Language)
|
||||
}
|
||||
|
||||
var row []string
|
||||
for _, f := range structs.Fields(Session{}) {
|
||||
csv := f.Tag("csv")
|
||||
if csv == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
caption, err := localizer.Localize(&locale.Config{
|
||||
MessageID: "sessions.csv." + strings.ToLower(f.Name()),
|
||||
})
|
||||
if err != nil {
|
||||
if csv != "" {
|
||||
caption = csv
|
||||
} else {
|
||||
caption = f.Name()
|
||||
}
|
||||
}
|
||||
|
||||
row = append(row, caption)
|
||||
}
|
||||
|
||||
return ww.Write(row)
|
||||
}
|
||||
|
||||
func formatValue(mp *message.Printer, value any, digits int) string {
|
||||
if rv := reflect.ValueOf(value); rv.Kind() == reflect.Pointer && rv.IsNil() {
|
||||
return ""
|
||||
}
|
||||
|
||||
switch v := value.(type) {
|
||||
case float64:
|
||||
return mp.Sprint(number.Decimal(v, number.NoSeparator(), number.MaxFractionDigits(digits)))
|
||||
case *float64:
|
||||
return mp.Sprint(number.Decimal(*v, number.NoSeparator(), number.MaxFractionDigits(digits)))
|
||||
case time.Time:
|
||||
if v.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return v.Local().Format("2006-01-02 15:04:05")
|
||||
default:
|
||||
return fmt.Sprintf("%v", value)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Sessions) writeRow(ww *csv.Writer, mp *message.Printer, r Session) error {
|
||||
var row []string
|
||||
for _, f := range structs.Fields(r) {
|
||||
if f.Tag("csv") == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
digits := 3
|
||||
if format := f.Tag("format"); format == "int" {
|
||||
digits = 0
|
||||
}
|
||||
|
||||
val := formatValue(mp, f.Value(), digits)
|
||||
|
||||
row = append(row, val)
|
||||
}
|
||||
|
||||
return ww.Write(row)
|
||||
}
|
||||
|
||||
// WriteCsv implements the api.CsvWriter interface
|
||||
func (t *Sessions) WriteCsv(ctx context.Context, w io.Writer) error {
|
||||
if _, err := w.Write([]byte{0xEF, 0xBB, 0xBF}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// get context language
|
||||
lang := locale.Language
|
||||
if language, ok := ctx.Value(locale.Locale).(string); ok && language != "" {
|
||||
lang = language
|
||||
}
|
||||
|
||||
tag, err := language.Parse(lang)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ww := csv.NewWriter(w)
|
||||
|
||||
// set separator according to locale
|
||||
if b, _ := tag.Base(); b.String() == language.German.String() {
|
||||
ww.Comma = ';'
|
||||
}
|
||||
|
||||
if err := t.writeHeader(ctx, ww); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mp := message.NewPrinter(tag)
|
||||
for _, r := range *t {
|
||||
if err := t.writeRow(ww, mp, r); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
ww.Flush()
|
||||
|
||||
return ww.Error()
|
||||
return csvutil.WriteStructSlice(ctx, w, t, csvutil.Config{
|
||||
I18nPrefix: "sessions.csv",
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue