forked from evcc-io/evcc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvehicle.go
109 lines (90 loc) Β· 2.62 KB
/
vehicle.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package vehicle
import (
"fmt"
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/provider"
"github.com/evcc-io/evcc/util"
)
//go:generate go run ../cmd/tools/decorate.go -f decorateVehicle -b api.Vehicle -t "api.ChargeState,Status,func() (api.ChargeStatus, error)" -t "api.VehicleRange,Range,func() (int64, error)" -t "api.VehicleOdometer,Odometer,func() (float64, error)" -t "api.VehicleClimater,Climater,func() (bool, error)"
// Vehicle is an api.Vehicle implementation with configurable getters and setters.
type Vehicle struct {
*embed
socG func() (float64, error)
statusG func() (string, error)
}
func init() {
registry.Add(api.Custom, NewConfigurableFromConfig)
}
// NewConfigurableFromConfig creates a new Vehicle
func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error) {
var cc struct {
embed `mapstructure:",squash"`
Soc provider.Config
Status *provider.Config
Range *provider.Config
Odometer *provider.Config
Climater *provider.Config
}
if err := util.DecodeOther(other, &cc); err != nil {
return nil, err
}
socG, err := provider.NewFloatGetterFromConfig(cc.Soc)
if err != nil {
return nil, fmt.Errorf("soc: %w", err)
}
v := &Vehicle{
embed: &cc.embed,
socG: socG,
}
// decorate vehicle with Status
var status func() (api.ChargeStatus, error)
if cc.Status != nil {
v.statusG, err = provider.NewStringGetterFromConfig(*cc.Status)
if err != nil {
return nil, fmt.Errorf("status: %w", err)
}
status = v.status
}
// decorate vehicle with range
var rng func() (int64, error)
if cc.Range != nil {
rangeG, err := provider.NewIntGetterFromConfig(*cc.Range)
if err != nil {
return nil, fmt.Errorf("range: %w", err)
}
rng = rangeG
}
// decorate vehicle with odometer
var odo func() (float64, error)
if cc.Odometer != nil {
odoG, err := provider.NewFloatGetterFromConfig(*cc.Odometer)
if err != nil {
return nil, fmt.Errorf("odometer: %w", err)
}
odo = odoG
}
// decorate vehicle with climater
var climater func() (bool, error)
if cc.Climater != nil {
climateG, err := provider.NewBoolGetterFromConfig(*cc.Climater)
if err != nil {
return nil, fmt.Errorf("climater: %w", err)
}
climater = climateG
}
res := decorateVehicle(v, status, rng, odo, climater)
return res, nil
}
// Soc implements the api.Vehicle interface
func (v *Vehicle) Soc() (float64, error) {
return v.socG()
}
// status implements the api.ChargeState interface
func (v *Vehicle) status() (api.ChargeStatus, error) {
status := api.StatusF
statusS, err := v.statusG()
if err == nil {
status = api.ChargeStatus(statusS)
}
return status, err
}