Rename default plugin and plugin type key (#927)
This commit is contained in:
parent
3aa754024c
commit
210d0d7ce2
13 changed files with 92 additions and 76 deletions
56
README.md
56
README.md
|
|
@ -13,7 +13,7 @@ EVCC is an extensible EV Charge Controller with PV integration implemented in [G
|
|||
- simple and clean user interface
|
||||
- multiple [chargers](#charger):
|
||||
- Wallbe, Phoenix (includes ESL Walli), go-eCharger, NRGkick (direct Bluetooth or via Connect device), SimpleEVSE, EVSEWifi, KEBA/BMW, openWB, Mobile Charger Connect and any other charger using scripting
|
||||
- Smart-Home outlets: FritzDECT, Tasmota, TP-Link
|
||||
- Smart-Home outlets: FritzDECT, Tasmota, TP-Link
|
||||
- multiple [meters](#meter): ModBus (Eastron SDM, MPM3PM, SBC ALE3 and many more), Discovergy (using HTTP plugin), SMA Sunny Home Manager and Energy Meter, KOSTAL Smart Energy Meter (KSEM, EMxx), any Sunspec-compatible inverter or home battery devices (Fronius, SMA, SolarEdge, KOSTAL, STECA, E3DC, ...), Tesla PowerWall
|
||||
- wide support of vendor-specific [vehicles](#vehicle) interfaces (remote charge, battery and preconditioning status): Audi, BMW, Ford, Hyundai, Kia, Nissan, Niu, Porsche, Renault, Seat, Skoda, Tesla, Volkswagen, Volvo and any other connected vehicle using scripting
|
||||
- [plugins](#plugins) for integrating with hardware devices and home automation: Modbus (meters and grid inverters), HTTP, MQTT, Javascript, WebSockets and shell scripts
|
||||
|
|
@ -168,7 +168,7 @@ In general, due to the minimum value of 5% for signalling the EV duty cycle, the
|
|||
|
||||
### Charger
|
||||
|
||||
Charger is responsible for handling EV state and adjusting charge current.
|
||||
Charger is responsible for handling EV state and adjusting charge current.
|
||||
Available charger implementations are:
|
||||
|
||||
- `evsewifi`: chargers with SimpleEVSE controllers using [EVSE-WiFi](https://www.evse-wifi.de/)
|
||||
|
|
@ -184,7 +184,7 @@ Available charger implementations are:
|
|||
- `simpleevse`: chargers with SimpleEVSE controllers connected via ModBus (e.g. OpenWB Wallbox, Easy Wallbox B163, ...)
|
||||
- `wallbe`: Wallbe Eco chargers (see [Preparation](#wallbe-preparation-)). For older Wallbe boxes (pre 2019) with Phoenix EV-CC-AC1-M3-CBC-RCM-ETH controllers make sure to set `legacy: true` to enable correct current configuration.
|
||||
- `warp`: Tinkerforge Warp/ Warp Pro charger
|
||||
- `default`: default charger implementation using configurable [plugins](#plugins) for integrating any type of charger
|
||||
- `custom`: default charger implementation using configurable [plugins](#plugins) for integrating any type of charger
|
||||
|
||||
Smart-Home outlet charger implementations:
|
||||
- `fritzdect`: Fritz!DECT 200/210 outlets
|
||||
|
|
@ -235,7 +235,7 @@ Available meter implementations are:
|
|||
- `openwb`: OpenWB meters. Use `usage` to choose meter type: `grid`/`pv`/`battery`.
|
||||
- `sma`: SMA Home Manager 2.0 and SMA Energy Meter. Power reading is configured out of the box but can be customized if necessary. To obtain specific energy readings define the desired Obis code (Import Energy: "1:1.8.0", Export Energy: "1:2.8.0").
|
||||
- `tesla`: Tesla PowerWall meter. Use `usage` to choose meter type: `grid`/`pv`/`battery`.
|
||||
- `default`: default meter implementation where meter readings- `power`, `energy`, per-phase `currents` and battery `soc` are configured using [plugins](#plugins)
|
||||
- `custom`: default meter implementation where meter readings- `power`, `energy`, per-phase `currents` and battery `soc` are configured using [plugins](#plugins)
|
||||
|
||||
Configuration examples are documented at [andig/evcc-config#meters](https://github.com/andig/evcc-config#meters)
|
||||
|
||||
|
|
@ -261,7 +261,7 @@ Available vehicle remote interface implementations are:
|
|||
- `vw`: Volkswagen (eGolf, eUp)
|
||||
- `id`: Volkswagen (ID.3, ID.4)
|
||||
- `volvo`: Volvo
|
||||
- `default`: default vehicle implementation using configurable [plugins](#plugins) for integrating any type of vehicle
|
||||
- `custom`: default vehicle implementation using configurable [plugins](#plugins) for integrating any type of vehicle
|
||||
|
||||
Configuration examples are documented at [andig/evcc-config#vehicles](https://github.com/andig/evcc-config#vehicles)
|
||||
|
||||
|
|
@ -281,7 +281,7 @@ to the left makes **Min+PV** behave as described above. Pushing completely to th
|
|||
|
||||
## Plugins
|
||||
|
||||
Plugins are used to integrate various devices and external data sources with EVCC. Plugins can be used in combination with a `default` type meter, charger or vehicle.
|
||||
Plugins are used to integrate various devices and external data sources with EVCC. Plugins can be used in combination with a `custom` type meter, charger or vehicle.
|
||||
|
||||
Plugins support both _read_ and _write_ access. When using plugins for _write_ access, the actual data is provided as variable in form of `${var[:format]}`. If `format` is omitted, data is formatted according to the default Go `%v` [format](https://golang.org/pkg/fmt/). The variable is replaced with the actual data before the plugin is executed.
|
||||
|
||||
|
|
@ -296,7 +296,7 @@ The meter configuration consists of the actual physical connection and the value
|
|||
If the device is physically connected using an RS485 adapter, `device` and serial configuration `baudrate`, `comset` must be specified:
|
||||
|
||||
```yaml
|
||||
type: modbus
|
||||
source: modbus
|
||||
device: /dev/ttyUSB0
|
||||
baudrate: 9600
|
||||
comset: "8N1"
|
||||
|
|
@ -305,7 +305,7 @@ comset: "8N1"
|
|||
If the device is a grid inverter or a Modbus meter connected via TCP, `uri` must be specified:
|
||||
|
||||
```yaml
|
||||
type: modbus
|
||||
source: modbus
|
||||
uri: 192.168.0.11:502
|
||||
id: 1 # modbus slave id
|
||||
```
|
||||
|
|
@ -313,7 +313,7 @@ id: 1 # modbus slave id
|
|||
If the device is a Modbus RTU device connected using an RS485/Ethernet adapter, set `rtu: true`. The serial configuration must be done directly on the adapter. Example:
|
||||
|
||||
```yaml
|
||||
type: modbus
|
||||
source: modbus
|
||||
uri: 192.168.0.10:502
|
||||
id: 3 # modbus slave id
|
||||
rtu: true
|
||||
|
|
@ -321,10 +321,10 @@ rtu: true
|
|||
|
||||
#### Logical connection <!-- omit in toc -->
|
||||
|
||||
The meter device type `meter` and the device's slave id `id` are always required:
|
||||
The device's type `model` and the device's slave id `id` are always required:
|
||||
|
||||
```yaml
|
||||
type: ...
|
||||
source: modbus
|
||||
uri/device/id: ...
|
||||
model: sdm
|
||||
value: Power
|
||||
|
|
@ -357,11 +357,11 @@ In case of SunSpec-compatible inverters, values can also be configured in the fo
|
|||
If the Modbus device is not supported by MBMD, the Modbus register can also be manually configured:
|
||||
|
||||
```yaml
|
||||
type: ...
|
||||
source: modbus
|
||||
uri/device/id: ...
|
||||
register:
|
||||
address: 40070
|
||||
type: holding # holding or input
|
||||
source: holding # holding or input
|
||||
decode: int32 # int16|32|64, uint16|32|64, float32|64 and u|int32s + float32s
|
||||
scale: -1 # floating point factor applied to result, e.g. for kW to W conversion
|
||||
```
|
||||
|
|
@ -377,7 +377,7 @@ The `mqtt` plugin allows to read values from MQTT topics. This is particularly u
|
|||
Sample configuration:
|
||||
|
||||
```yaml
|
||||
type: mqtt
|
||||
source: mqtt
|
||||
topic: mbmd/sdm1-1/Power
|
||||
timeout: 30s # don't accept values older than timeout
|
||||
scale: 0.001 # floating point factor applied to result, e.g. for Wh to kWh conversion
|
||||
|
|
@ -386,7 +386,7 @@ scale: 0.001 # floating point factor applied to result, e.g. for Wh to kWh conve
|
|||
Sample write configuration:
|
||||
|
||||
```yaml
|
||||
type: mqtt
|
||||
source: mqtt
|
||||
topic: mbmd/charger/maxcurrent
|
||||
payload: ${var:%d}
|
||||
```
|
||||
|
|
@ -400,7 +400,7 @@ The `http` plugin executes HTTP requests to read or update data. Includes the ab
|
|||
Sample read configuration:
|
||||
|
||||
```yaml
|
||||
type: http
|
||||
source: http
|
||||
uri: https://volkszaehler/api/data/<uuid>.json?from=now
|
||||
method: GET # default HTTP method
|
||||
headers:
|
||||
|
|
@ -428,7 +428,7 @@ The `websocket` plugin implements a web socket listener. Includes the ability to
|
|||
Sample configuration (read only):
|
||||
|
||||
```yaml
|
||||
type: http
|
||||
source: http
|
||||
uri: ws://<volkszaehler host:port>/socket
|
||||
jq: .data | select(.uuid=="<uuid>") .tuples[0][1] # parse message json
|
||||
scale: 0.001 # floating point factor applied to result, e.g. for Wh to kWh conversion
|
||||
|
|
@ -440,7 +440,7 @@ timeout: 30s # error if no update received in 30 seconds
|
|||
EVCC includes a bundled Javascript interpreter with Underscore.js library installed. The `js` plugin is able to execute Javascript code from the `script` tag. Useful for quick prototyping:
|
||||
|
||||
```yaml
|
||||
type: js
|
||||
source: js
|
||||
script: |
|
||||
var res = 500;
|
||||
2 * res; // returns 1000
|
||||
|
|
@ -450,9 +450,9 @@ When using the `js` plugin for writing, the value to write is handed to the scri
|
|||
|
||||
```yaml
|
||||
charger:
|
||||
- type: generic
|
||||
- type: custom
|
||||
maxcurrent:
|
||||
type: js
|
||||
source: js
|
||||
script: |
|
||||
console.log(maxcurrent);
|
||||
```
|
||||
|
|
@ -464,7 +464,7 @@ The `script` plugin executes external scripts to read or update data. This plugi
|
|||
Sample read configuration:
|
||||
|
||||
```yaml
|
||||
type: script
|
||||
source: script
|
||||
cmd: /bin/bash -c "cat /dev/urandom"
|
||||
timeout: 5s
|
||||
```
|
||||
|
|
@ -472,7 +472,7 @@ timeout: 5s
|
|||
Sample write configuration:
|
||||
|
||||
```yaml
|
||||
type: script
|
||||
source: script
|
||||
cmd: /home/user/my-script.sh ${enable:%b} # format boolean enable as 0/1
|
||||
timeout: 5s
|
||||
```
|
||||
|
|
@ -482,11 +482,11 @@ timeout: 5s
|
|||
The `calc` plugin allows calculating the sum of other plugins:
|
||||
|
||||
```yaml
|
||||
type: calc
|
||||
source: calc
|
||||
add:
|
||||
- type: ...
|
||||
- source: ...
|
||||
...
|
||||
- type: ...
|
||||
- source: ...
|
||||
...
|
||||
```
|
||||
|
||||
|
|
@ -499,12 +499,12 @@ The `combined` status plugin is used to convert a mixed boolean status of plugge
|
|||
Sample configuration (read only):
|
||||
|
||||
```yaml
|
||||
type: combined
|
||||
source: combined
|
||||
plugged:
|
||||
type: mqtt
|
||||
source: mqtt
|
||||
topic: openWB/lp/1/boolPlugStat
|
||||
charging:
|
||||
type: mqtt
|
||||
source: mqtt
|
||||
topic: openWB/lp/1/boolChargeStat
|
||||
```
|
||||
|
||||
|
|
|
|||
4
go.mod
4
go.mod
|
|
@ -4,9 +4,7 @@ go 1.16
|
|||
|
||||
require (
|
||||
github.com/PuerkitoBio/goquery v1.6.1
|
||||
github.com/andig/evcc-config v0.0.0-20210426054204-3450b327d1e5
|
||||
github.com/andig/gosunspec v0.0.0-20210401131709-cd89d66b502d // indirect
|
||||
github.com/andybalholm/cascadia v1.2.0 // indirect
|
||||
github.com/andig/evcc-config v0.0.0-20210505193639-b12d8515d6f1
|
||||
github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef
|
||||
github.com/avast/retry-go v3.0.0+incompatible
|
||||
github.com/benbjohnson/clock v1.1.0
|
||||
|
|
|
|||
10
go.sum
10
go.sum
|
|
@ -50,15 +50,13 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
|
|||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/alvaroloes/enumer v1.1.2/go.mod h1:FxrjvuXoDAx9isTJrv4c+T410zFi0DtXIT0m65DJ+Wo=
|
||||
github.com/andig/evcc v0.0.0-20200727161511-d58eb15f2dc9/go.mod h1:8HONEC6cC2s4k0u3QL7GIjrYOZYTOKiiXybw0FIJL0A=
|
||||
github.com/andig/evcc-config v0.0.0-20210426054204-3450b327d1e5 h1:enGdw9V+3CvgeHHSKtU8Eu56/odljAoINywXoyZs+54=
|
||||
github.com/andig/evcc-config v0.0.0-20210426054204-3450b327d1e5/go.mod h1:nsZ9UY8liEWaNZV5MFdp7TCAHP6de3RUIsBBPk5ixsA=
|
||||
github.com/andig/evcc-config v0.0.0-20210505193639-b12d8515d6f1 h1:8y3a0rJ/7BQZqnCQjzPjrlTUCHiTyY0Ybf2LX33ffAQ=
|
||||
github.com/andig/evcc-config v0.0.0-20210505193639-b12d8515d6f1/go.mod h1:nsZ9UY8liEWaNZV5MFdp7TCAHP6de3RUIsBBPk5ixsA=
|
||||
github.com/andig/gosunspec v0.0.0-20200429133549-3cf6a82fed9c/go.mod h1:YkshK8WMzYn1iXAZzHUO75gIqhMSan2ctgBVtBkRIyA=
|
||||
github.com/andig/gosunspec v0.0.0-20201103081418-ec9af6feefde h1:QgUO3swXFjTXjqT+EA1k7XZbTxtl8AenEckO0UF3Dfw=
|
||||
github.com/andig/gosunspec v0.0.0-20201103081418-ec9af6feefde/go.mod h1:YkshK8WMzYn1iXAZzHUO75gIqhMSan2ctgBVtBkRIyA=
|
||||
github.com/andig/gosunspec v0.0.0-20210401131709-cd89d66b502d h1:AyTgrMKSEy030uAfY6nGhq5yE2ONvu3pl1sLECVS3ec=
|
||||
github.com/andig/gosunspec v0.0.0-20210401131709-cd89d66b502d/go.mod h1:YkshK8WMzYn1iXAZzHUO75gIqhMSan2ctgBVtBkRIyA=
|
||||
github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
|
||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/andybalholm/cascadia v1.2.0 h1:vuRCkM5Ozh/BfmsaTm26kbjm0mIOM3yS5Ek/F5h18aE=
|
||||
github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxBp0T0eFw1RUQY=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/andig/evcc/api"
|
||||
"github.com/andig/evcc/internal"
|
||||
"github.com/andig/evcc/provider"
|
||||
"github.com/andig/evcc/util"
|
||||
)
|
||||
|
|
@ -18,6 +19,7 @@ type Charger struct {
|
|||
|
||||
func init() {
|
||||
registry.Add("default", NewConfigurableFromConfig)
|
||||
registry.Add(internal.Custom, NewConfigurableFromConfig)
|
||||
}
|
||||
|
||||
// NewConfigurableFromConfig creates a new configurable charger
|
||||
|
|
@ -28,13 +30,13 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Charger, error
|
|||
}
|
||||
|
||||
for k, v := range map[string]string{
|
||||
"status": cc.Status.Type,
|
||||
"enable": cc.Enable.Type,
|
||||
"enabled": cc.Enabled.Type,
|
||||
"maxcurrent": cc.MaxCurrent.Type,
|
||||
"status": cc.Status.PluginType(),
|
||||
"enable": cc.Enable.PluginType(),
|
||||
"enabled": cc.Enabled.PluginType(),
|
||||
"maxcurrent": cc.MaxCurrent.PluginType(),
|
||||
} {
|
||||
if v == "" {
|
||||
return nil, fmt.Errorf("default charger config: %s required", k)
|
||||
return nil, fmt.Errorf("missing plugin configuration: %s", k)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ func NewFromConfig(typ string, other map[string]interface{}) (v api.Charger, err
|
|||
factory, err := registry.Get(strings.ToLower(typ))
|
||||
if err == nil {
|
||||
if v, err = factory(other); err != nil {
|
||||
err = fmt.Errorf("cannot create type '%s': %w", typ, err)
|
||||
err = fmt.Errorf("cannot create charger '%s': %w", typ, err)
|
||||
}
|
||||
} else {
|
||||
err = fmt.Errorf("invalid charger type: %s", typ)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ type NRGKickBLE struct {
|
|||
agent *agent.SimpleAgent
|
||||
dev *device.Device1
|
||||
device string
|
||||
macaddress string
|
||||
mac string
|
||||
pin int
|
||||
pauseCharging bool
|
||||
current int
|
||||
|
|
@ -40,7 +40,7 @@ func init() {
|
|||
|
||||
// NewNRGKickBLEFromConfig creates a NRGKickBLE charger from generic config
|
||||
func NewNRGKickBLEFromConfig(other map[string]interface{}) (api.Charger, error) {
|
||||
cc := struct{ Device, MacAddress, PIN string }{
|
||||
cc := struct{ Device, Mac, PIN string }{
|
||||
Device: "hci0",
|
||||
}
|
||||
if err := util.DecodeOther(other, &cc); err != nil {
|
||||
|
|
@ -53,11 +53,11 @@ func NewNRGKickBLEFromConfig(other map[string]interface{}) (api.Charger, error)
|
|||
return nil, fmt.Errorf("invalid pin: %s", cc.PIN)
|
||||
}
|
||||
|
||||
return NewNRGKickBLE(cc.Device, cc.MacAddress, pin)
|
||||
return NewNRGKickBLE(cc.Device, cc.Mac, pin)
|
||||
}
|
||||
|
||||
// NewNRGKickBLE creates NRGKickBLE charger
|
||||
func NewNRGKickBLE(device, macaddress string, pin int) (*NRGKickBLE, error) {
|
||||
func NewNRGKickBLE(device, mac string, pin int) (*NRGKickBLE, error) {
|
||||
logger := util.NewLogger("nrg-bt")
|
||||
|
||||
// set LE mode
|
||||
|
|
@ -103,20 +103,20 @@ func NewNRGKickBLE(device, macaddress string, pin int) (*NRGKickBLE, error) {
|
|||
}
|
||||
|
||||
nrg := &NRGKickBLE{
|
||||
log: logger,
|
||||
timer: time.NewTimer(1),
|
||||
device: device,
|
||||
macaddress: macaddress,
|
||||
pin: pin,
|
||||
adapter: adapt,
|
||||
agent: ag,
|
||||
log: logger,
|
||||
timer: time.NewTimer(1),
|
||||
device: device,
|
||||
mac: mac,
|
||||
pin: pin,
|
||||
adapter: adapt,
|
||||
agent: ag,
|
||||
}
|
||||
|
||||
return nrg, nil
|
||||
}
|
||||
|
||||
func (nrg *NRGKickBLE) connect() (*device.Device1, error) {
|
||||
dev, err := nrgble.FindDevice(nrg.adapter, nrg.macaddress, nrgTimeout)
|
||||
dev, err := nrgble.FindDevice(nrg.adapter, nrg.mac, nrgTimeout)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("find device: %s", err)
|
||||
}
|
||||
|
|
|
|||
4
internal/const.go
Normal file
4
internal/const.go
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
package internal
|
||||
|
||||
// Custom plugin type
|
||||
const Custom = "custom"
|
||||
|
|
@ -31,7 +31,7 @@ func NewFromConfig(typ string, other map[string]interface{}) (v api.Meter, err e
|
|||
factory, err := registry.Get(strings.ToLower(typ))
|
||||
if err == nil {
|
||||
if v, err = factory(other); err != nil {
|
||||
err = fmt.Errorf("cannot create type '%s': %w", typ, err)
|
||||
err = fmt.Errorf("cannot create meter '%s': %w", typ, err)
|
||||
}
|
||||
} else {
|
||||
err = fmt.Errorf("invalid meter type: %s", typ)
|
||||
|
|
|
|||
|
|
@ -5,12 +5,14 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/andig/evcc/api"
|
||||
"github.com/andig/evcc/internal"
|
||||
"github.com/andig/evcc/provider"
|
||||
"github.com/andig/evcc/util"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registry.Add("default", NewConfigurableFromConfig)
|
||||
registry.Add(internal.Custom, NewConfigurableFromConfig)
|
||||
}
|
||||
|
||||
//go:generate go run ../../cmd/tools/decorate.go -p meter -f decorateMeter -b api.Meter -o meter_decorators -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.MeterCurrent,Currents,func() (float64, float64, float64, error)" -t "api.Battery,SoC,func() (float64, error)"
|
||||
|
|
@ -28,9 +30,9 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
for k, v := range map[string]string{"power": cc.Power.Type} {
|
||||
for k, v := range map[string]string{"power": cc.Power.PluginType()} {
|
||||
if v == "" {
|
||||
return nil, fmt.Errorf("default meter config: %s required", k)
|
||||
return nil, fmt.Errorf("missing plugin configuration: %s", k)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func NewFromConfig(typ string, other map[string]interface{}) (v api.Vehicle, err
|
|||
factory, err := registry.Get(strings.ToLower(typ))
|
||||
if err == nil {
|
||||
if v, err = factory(other); err != nil {
|
||||
err = fmt.Errorf("cannot create type '%s': %w", typ, err)
|
||||
err = fmt.Errorf("cannot create vehicle '%s': %w", typ, err)
|
||||
}
|
||||
} else {
|
||||
err = fmt.Errorf("invalid vehicle type: %s", typ)
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ func (v *Provider) Climater() (active bool, outsideTemp float64, targetTemp floa
|
|||
|
||||
targetTemp = res.Data.ClimatisationSettings.TargetTemperatureC
|
||||
|
||||
// TODO: not available; use target temp to avoid wrong heating/cooling display
|
||||
// TODO not available; use target temp to avoid wrong heating/cooling display
|
||||
outsideTemp = targetTemp
|
||||
|
||||
return active, outsideTemp, targetTemp, nil
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/andig/evcc/api"
|
||||
"github.com/andig/evcc/internal"
|
||||
"github.com/andig/evcc/provider"
|
||||
"github.com/andig/evcc/util"
|
||||
)
|
||||
|
|
@ -36,6 +37,7 @@ type Vehicle struct {
|
|||
|
||||
func init() {
|
||||
registry.Add("default", NewConfigurableFromConfig)
|
||||
registry.Add(internal.Custom, NewConfigurableFromConfig)
|
||||
}
|
||||
|
||||
// NewConfigurableFromConfig creates a new Vehicle
|
||||
|
|
@ -55,9 +57,9 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error
|
|||
return nil, err
|
||||
}
|
||||
|
||||
for k, v := range map[string]string{"charge": cc.Charge.Type} {
|
||||
for k, v := range map[string]string{"charge": cc.Charge.PluginType()} {
|
||||
if v == "" {
|
||||
return nil, fmt.Errorf("default vehicle config: %s required", k)
|
||||
return nil, fmt.Errorf("missing plugin configuration: %s", k)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,13 +48,23 @@ var registry providerRegistry = make(map[string]func(map[string]interface{}) (In
|
|||
|
||||
// Config is the general provider config
|
||||
type Config struct {
|
||||
Type string
|
||||
Other map[string]interface{} `mapstructure:",remain"`
|
||||
Source string
|
||||
Type string // TODO remove deprecated
|
||||
Other map[string]interface{} `mapstructure:",remain"`
|
||||
}
|
||||
|
||||
// PluginType returns the plugin type in a legacy-aware way
|
||||
func (c Config) PluginType() string {
|
||||
typ := c.Source
|
||||
if typ == "" {
|
||||
typ = c.Type
|
||||
}
|
||||
return strings.ToLower(typ)
|
||||
}
|
||||
|
||||
// NewIntGetterFromConfig creates a IntGetter from config
|
||||
func NewIntGetterFromConfig(config Config) (res func() (int64, error), err error) {
|
||||
factory, err := registry.Get(strings.ToLower(config.Type))
|
||||
factory, err := registry.Get(config.PluginType())
|
||||
if err == nil {
|
||||
var provider IntProvider
|
||||
provider, err = factory(config.Other)
|
||||
|
|
@ -65,7 +75,7 @@ func NewIntGetterFromConfig(config Config) (res func() (int64, error), err error
|
|||
}
|
||||
|
||||
if err == nil && res == nil {
|
||||
err = fmt.Errorf("invalid plugin type: %s", config.Type)
|
||||
err = fmt.Errorf("invalid plugin type: %s", config.PluginType())
|
||||
}
|
||||
|
||||
return
|
||||
|
|
@ -73,7 +83,7 @@ func NewIntGetterFromConfig(config Config) (res func() (int64, error), err error
|
|||
|
||||
// NewFloatGetterFromConfig creates a FloatGetter from config
|
||||
func NewFloatGetterFromConfig(config Config) (res func() (float64, error), err error) {
|
||||
factory, err := registry.Get(config.Type)
|
||||
factory, err := registry.Get(config.PluginType())
|
||||
if err == nil {
|
||||
var provider IntProvider
|
||||
provider, err = factory(config.Other)
|
||||
|
|
@ -84,7 +94,7 @@ func NewFloatGetterFromConfig(config Config) (res func() (float64, error), err e
|
|||
}
|
||||
|
||||
if err == nil && res == nil {
|
||||
err = fmt.Errorf("invalid plugin type: %s", config.Type)
|
||||
err = fmt.Errorf("invalid plugin type: %s", config.PluginType())
|
||||
}
|
||||
|
||||
return
|
||||
|
|
@ -92,7 +102,7 @@ func NewFloatGetterFromConfig(config Config) (res func() (float64, error), err e
|
|||
|
||||
// NewStringGetterFromConfig creates a StringGetter from config
|
||||
func NewStringGetterFromConfig(config Config) (res func() (string, error), err error) {
|
||||
switch typ := strings.ToLower(config.Type); typ {
|
||||
switch typ := config.PluginType(); typ {
|
||||
case "combined", "openwb":
|
||||
res, err = NewOpenWBStatusProviderFromConfig(config.Other)
|
||||
|
||||
|
|
@ -109,7 +119,7 @@ func NewStringGetterFromConfig(config Config) (res func() (string, error), err e
|
|||
}
|
||||
|
||||
if err == nil && res == nil {
|
||||
err = fmt.Errorf("invalid plugin type: %s", config.Type)
|
||||
err = fmt.Errorf("invalid plugin type: %s", config.PluginType())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +128,7 @@ func NewStringGetterFromConfig(config Config) (res func() (string, error), err e
|
|||
|
||||
// NewBoolGetterFromConfig creates a BoolGetter from config
|
||||
func NewBoolGetterFromConfig(config Config) (res func() (bool, error), err error) {
|
||||
factory, err := registry.Get(strings.ToLower(config.Type))
|
||||
factory, err := registry.Get(config.PluginType())
|
||||
if err == nil {
|
||||
var provider IntProvider
|
||||
provider, err = factory(config.Other)
|
||||
|
|
@ -129,7 +139,7 @@ func NewBoolGetterFromConfig(config Config) (res func() (bool, error), err error
|
|||
}
|
||||
|
||||
if err == nil && res == nil {
|
||||
err = fmt.Errorf("invalid plugin type: %s", config.Type)
|
||||
err = fmt.Errorf("invalid plugin type: %s", config.PluginType())
|
||||
}
|
||||
|
||||
return
|
||||
|
|
@ -137,7 +147,7 @@ func NewBoolGetterFromConfig(config Config) (res func() (bool, error), err error
|
|||
|
||||
// NewIntSetterFromConfig creates a IntSetter from config
|
||||
func NewIntSetterFromConfig(param string, config Config) (res func(int64) error, err error) {
|
||||
factory, err := registry.Get(strings.ToLower(config.Type))
|
||||
factory, err := registry.Get(config.PluginType())
|
||||
if err == nil {
|
||||
var provider IntProvider
|
||||
provider, err = factory(config.Other)
|
||||
|
|
@ -148,7 +158,7 @@ func NewIntSetterFromConfig(param string, config Config) (res func(int64) error,
|
|||
}
|
||||
|
||||
if err == nil && res == nil {
|
||||
err = fmt.Errorf("invalid plugin type: %s", config.Type)
|
||||
err = fmt.Errorf("invalid plugin type: %s", config.PluginType())
|
||||
}
|
||||
|
||||
return
|
||||
|
|
@ -156,7 +166,7 @@ func NewIntSetterFromConfig(param string, config Config) (res func(int64) error,
|
|||
|
||||
// NewBoolSetterFromConfig creates a BoolSetter from config
|
||||
func NewBoolSetterFromConfig(param string, config Config) (res func(bool) error, err error) {
|
||||
factory, err := registry.Get(strings.ToLower(config.Type))
|
||||
factory, err := registry.Get(config.PluginType())
|
||||
if err == nil {
|
||||
var provider IntProvider
|
||||
provider, err = factory(config.Other)
|
||||
|
|
@ -167,7 +177,7 @@ func NewBoolSetterFromConfig(param string, config Config) (res func(bool) error,
|
|||
}
|
||||
|
||||
if err == nil && res == nil {
|
||||
err = fmt.Errorf("invalid plugin type: %s", config.Type)
|
||||
err = fmt.Errorf("invalid plugin type: %s", config.PluginType())
|
||||
}
|
||||
|
||||
return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue