Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ jobs:

- name: Lint
uses: golangci/golangci-lint-action@v9
env:
GOEXPERIMENT: jsonv2
with:
version: latest
args: --timeout 5m
Expand Down
16 changes: 8 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,23 @@ ui::
npm run build

assets::
go generate ./...
GOEXPERIMENT=jsonv2 go generate ./...

docs::
go generate github.com/evcc-io/evcc/util/templates/...
GOEXPERIMENT=jsonv2 go generate github.com/evcc-io/evcc/util/templates/...

lint::
golangci-lint run
go tool modernize -test -c 0 -stringsbuilder=false -omitzero=false ./...
GOEXPERIMENT=jsonv2 golangci-lint run
GOEXPERIMENT=jsonv2 go tool modernize -test -c 0 -stringsbuilder=false -omitzero=false ./...

modernize:
go tool modernize -test -fix -stringsbuilder=false -omitzero=false ./...
GOEXPERIMENT=jsonv2 go tool modernize -test -fix -stringsbuilder=false -omitzero=false ./...

lint-ui::
npm run lint

license::
go run github.com/google/go-licenses/v2@latest check \
GOEXPERIMENT=jsonv2 go run github.com/google/go-licenses/v2@latest check \
--ignore github.com/cespare/xxhash \
--ignore github.com/coder/websocket \
--ignore github.com/cronokirby/saferith \
Expand All @@ -80,7 +80,7 @@ test-ui::

test::
@echo "Running testsuite"
CGO_ENABLED=0 go test $(BUILD_TAGS) ./...
GOEXPERIMENT=jsonv2 CGO_ENABLED=0 go test $(BUILD_TAGS) ./...

porcelain::
gofmt -w -l $$(find . -name '*.go')
Expand All @@ -89,7 +89,7 @@ porcelain::

build::
@echo Version: $(VERSION) $(SHA) $(BUILD_DATE)
CGO_ENABLED=0 go build -v $(BUILD_TAGS) $(BUILD_ARGS)
GOEXPERIMENT=jsonv2 CGO_ENABLED=0 go build -v $(BUILD_TAGS) $(BUILD_ARGS)

snapshot::
goreleaser --snapshot --skip publish --clean
Expand Down
5 changes: 2 additions & 3 deletions assets/js/components/Sessions/SessionDetailsModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
)
}}
<div v-if="session.chargeDuration">
{{ fmtDurationNs(session.chargeDuration) }}
{{ fmtDuration(session.chargeDuration) }}
(~{{ fmtW(avgPower) }})
</div>
</td>
Expand Down Expand Up @@ -194,8 +194,7 @@ export default defineComponent({
return this.session.chargedEnergy * 1e3;
},
avgPower() {
const hours = this.session.chargeDuration / 1e9 / 3600;
return this.chargedEnergy / hours;
return this.chargedEnergy / (this.session.chargeDuration / 3600);
},
solarEnergy() {
return this.chargedEnergy * (this.session.solarPercentage / 100);
Expand Down
9 changes: 3 additions & 6 deletions assets/js/components/Sessions/SessionTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -242,15 +242,15 @@ export default defineComponent({
unit: "h:mm",
total: this.chargeDuration,
value: (session) => session.chargeDuration,
format: (value) => this.fmtDurationNs(value, false, "h"),
format: (value) => this.fmtDuration(value, false, "h"),
},
{
name: "avgPower",
unit: "kW",
total: this.avgPower,
value: (session) => {
if (session.chargedEnergy && session.chargeDuration) {
return session.chargedEnergy / this.nsToHours(session.chargeDuration);
return session.chargedEnergy / (session.chargeDuration / 3600);
}
return null;
},
Expand Down Expand Up @@ -339,7 +339,7 @@ export default defineComponent({
.reduce(
(total, s) => {
total.energy += s.chargedEnergy;
total.hours += this.nsToHours(s.chargeDuration);
total.hours += s.chargeDuration / 3600;
return total;
},
{ energy: 0, hours: 0 }
Expand Down Expand Up @@ -398,9 +398,6 @@ export default defineComponent({
},
},
methods: {
nsToHours(ns: number) {
return ns / 1e9 / 3600;
},
filterByLoadpoint(session: Session) {
return !this.loadpointFilter || session.loadpoint === this.loadpointFilter;
},
Expand Down
28 changes: 14 additions & 14 deletions core/loadpoint/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@ type StaticConfig struct {

type DynamicConfig struct {
// dynamic config
Title string `json:"title"`
DefaultMode string `json:"defaultMode"`
Priority int `json:"priority"`
PhasesConfigured int `json:"phasesConfigured"`
MinCurrent float64 `json:"minCurrent"`
MaxCurrent float64 `json:"maxCurrent"`
SmartCostLimit *float64 `json:"smartCostLimit"`
SmartFeedInPriorityLimit *float64 `json:"smartFeedInPriorityLimit"`
PlanEnergy float64 `json:"planEnergy"`
PlanTime time.Time `json:"planTime"`
PlanPrecondition int64 `json:"planPrecondition"`
LimitEnergy float64 `json:"limitEnergy"`
LimitSoc int `json:"limitSoc"`
Title string `json:"title"`
DefaultMode string `json:"defaultMode"`
Priority int `json:"priority"`
PhasesConfigured int `json:"phasesConfigured"`
MinCurrent float64 `json:"minCurrent"`
MaxCurrent float64 `json:"maxCurrent"`
SmartCostLimit *float64 `json:"smartCostLimit"`
SmartFeedInPriorityLimit *float64 `json:"smartFeedInPriorityLimit"`
PlanEnergy float64 `json:"planEnergy"`
PlanTime time.Time `json:"planTime"`
PlanPrecondition time.Duration `json:"planPrecondition"`
LimitEnergy float64 `json:"limitEnergy"`
LimitSoc int `json:"limitSoc"`

Thresholds ThresholdsConfig `json:"thresholds"`
Soc SocConfig `json:"soc"`
Expand Down Expand Up @@ -59,7 +59,7 @@ func (payload DynamicConfig) Apply(lp API) error {
lp.SetSmartCostLimit(payload.SmartCostLimit)
lp.SetSmartFeedInPriorityLimit(payload.SmartFeedInPriorityLimit)
lp.SetThresholds(payload.Thresholds)
lp.SetPlanEnergy(payload.PlanTime, time.Duration(payload.PlanPrecondition)*time.Second, payload.PlanEnergy)
lp.SetPlanEnergy(payload.PlanTime, payload.PlanPrecondition, payload.PlanEnergy)
lp.SetLimitEnergy(payload.LimitEnergy)
lp.SetLimitSoc(payload.LimitSoc)

Expand Down
2 changes: 1 addition & 1 deletion server/http_config_loadpoint_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func getLoadpointDynamicConfig(lp loadpoint.API) loadpoint.DynamicConfig {
Soc: lp.GetSocConfig(),
PlanEnergy: planEnergy,
PlanTime: planTime,
PlanPrecondition: int64(planPrecondition.Seconds()),
PlanPrecondition: planPrecondition,
LimitEnergy: lp.GetLimitEnergy(),
LimitSoc: lp.GetLimitSoc(),
}
Expand Down
59 changes: 27 additions & 32 deletions server/http_loadpoint_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,11 @@ import (
)

type PlanResponse struct {
PlanId int `json:"planId"`
PlanTime time.Time `json:"planTime"`
Duration int64 `json:"duration"`
Precondition int64 `json:"precondition"`
Plan api.Rates `json:"plan"`
Power float64 `json:"power"`
}

type PlanPreviewResponse struct {
PlanTime time.Time `json:"planTime"`
Duration int64 `json:"duration"`
Precondition int64 `json:"precondition"`
Plan api.Rates `json:"plan"`
Power float64 `json:"power"`
PlanTime time.Time `json:"planTime"`
Duration time.Duration `json:"duration"`
Precondition time.Duration `json:"precondition"`
Plan api.Rates `json:"plan"`
Power float64 `json:"power"`
}

// planHandler returns the current plan
Expand All @@ -44,15 +35,19 @@ func planHandler(lp loadpoint.API) http.HandlerFunc {
requiredDuration := lp.GetPlanRequiredDuration(goal, maxPower)
plan := lp.GetPlan(planTime, requiredDuration, precondition)

res := PlanResponse{
PlanId: id,
PlanTime: planTime,
Duration: int64(requiredDuration.Seconds()),
Precondition: int64(precondition.Seconds()),
Plan: plan,
Power: maxPower,
res := struct {
PlanId int `json:"planId"`
PlanResponse `json:",inline"`
}{
PlanId: id,
PlanResponse: PlanResponse{
PlanTime: planTime,
Duration: requiredDuration,
Precondition: precondition,
Plan: plan,
Power: maxPower,
},
}

jsonWrite(w, res)
}
}
Expand Down Expand Up @@ -101,10 +96,10 @@ func staticPlanPreviewHandler(lp loadpoint.API) http.HandlerFunc {
requiredDuration := lp.GetPlanRequiredDuration(goal, maxPower)
plan := lp.GetPlan(planTime, requiredDuration, precondition)

res := PlanPreviewResponse{
res := PlanResponse{
PlanTime: planTime,
Duration: int64(requiredDuration.Seconds()),
Precondition: int64(precondition.Seconds()),
Duration: requiredDuration,
Precondition: precondition,
Plan: plan,
Power: maxPower,
}
Expand Down Expand Up @@ -153,10 +148,10 @@ func repeatingPlanPreviewHandler(lp loadpoint.API) http.HandlerFunc {
requiredDuration := lp.GetPlanRequiredDuration(soc, maxPower)
plan := lp.GetPlan(planTime, requiredDuration, precondition)

res := PlanPreviewResponse{
res := PlanResponse{
PlanTime: planTime,
Duration: int64(requiredDuration.Seconds()),
Precondition: int64(precondition.Seconds()),
Duration: requiredDuration,
Precondition: precondition,
Plan: plan,
Power: maxPower,
}
Expand Down Expand Up @@ -197,12 +192,12 @@ func planEnergyHandler(lp loadpoint.API) http.HandlerFunc {
ts, precondition, energy := lp.GetPlanEnergy()

res := struct {
Energy float64 `json:"energy"`
Precondition int64 `json:"precondition"`
Time time.Time `json:"time"`
Energy float64 `json:"energy"`
Precondition time.Duration `json:"precondition"`
Time time.Time `json:"time"`
}{
Energy: energy,
Precondition: int64(precondition.Seconds()),
Precondition: precondition,
Time: ts,
}

Expand Down
22 changes: 18 additions & 4 deletions server/http_site_handler.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package server

import (
"encoding/json"
"encoding/json/v2"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -80,8 +80,22 @@ func jsonHandler(h http.Handler) http.Handler {
})
}

func jsonMarshalers() *json.Marshalers {
return json.JoinMarshalers(
json.MarshalFunc(func(d time.Duration) ([]byte, error) {
return fmt.Append(nil, int(d.Seconds())), nil
}),
json.MarshalFunc(func(ts time.Time) ([]byte, error) {
if ts.IsZero() {
return []byte("null"), nil
}
return json.Marshal(ts)
}),
)
}

func jsonWrite(w http.ResponseWriter, data any) {
json.NewEncoder(w).Encode(data)
json.MarshalWrite(w, data, json.WithMarshalers(jsonMarshalers()))
}

func jsonError(w http.ResponseWriter, status int, err error) {
Expand Down Expand Up @@ -336,7 +350,7 @@ func adminPasswordValid(authObject auth.Auth, password string) bool {
func getBackup(authObject auth.Auth) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req loginRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
if err := json.UnmarshalRead(r.Body, &req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
Expand Down Expand Up @@ -463,7 +477,7 @@ func resetDatabase(authObject auth.Auth, shutdown func()) http.HandlerFunc {
Settings bool `json:"settings"`
}

if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
if err := json.UnmarshalRead(r.Body, &req); err != nil {
jsonError(w, http.StatusBadRequest, err)
return
}
Expand Down
8 changes: 4 additions & 4 deletions server/http_vehicle_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,12 @@ func planSocHandler(site site.API) http.HandlerFunc {
ts, precondition, soc = v.GetPlanSoc()

res := struct {
Soc int `json:"soc"`
Precondition int64 `json:"precondition"`
Time time.Time `json:"time"`
Soc int `json:"soc"`
Precondition time.Duration `json:"precondition"`
Time time.Time `json:"time"`
}{
Soc: soc,
Precondition: int64(precondition.Seconds()),
Precondition: precondition,
Time: ts,
}

Expand Down
Loading