Add prioritySoC api (mqtt only) (#633)

This commit is contained in:
andig 2021-02-02 16:53:38 +01:00 • committed by GitHub
parent f5ca4430aa
commit ca988fcf2b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 6 deletions

View file

@ -501,6 +501,7 @@ The MQTT API follows the REST API's structure, with loadpoint ids starting at `0
- `evcc`: root topic
- `evcc/updated`: timestamp of last update
- `evcc/site`: site dynamic state
- `evcc/site/prioritySoC`: battery priority SoC (writable)
- `evcc/loadpoints`: number of available loadpoints
- `evcc/loadpoints/<id>`: loadpoint dynamic state
- `evcc/loadpoints/<id>/mode`: loadpoint charge mode (writable)

View file

@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"math"
"sync"
"time"
"github.com/andig/evcc/api"
@ -26,6 +27,7 @@ type Site struct {
*Health
sync.Mutex
log *util.Logger
// configuration
@ -55,12 +57,6 @@ type MetersConfig struct {
BatteryMeterRef string `mapstructure:"battery"` // Battery charging meter reference
}
// SiteAPI is the external site API
type SiteAPI interface {
Healthy() bool
LoadPoints() []LoadPointAPI
}
// NewSiteFromConfig creates a new site
func NewSiteFromConfig(
log *util.Logger,
@ -158,6 +154,10 @@ func (site *Site) DumpConfig() {
meterCapabilities("battery", site.batteryMeter),
fmt.Sprintf("soc %s", presence[ok]),
)
if ok {
site.publish("prioritySoC", site.PrioritySoC)
}
}
for i, lp := range site.loadpoints {
@ -287,6 +287,9 @@ func (site *Site) sitePower() (float64, error) {
site.log.DEBUG.Printf("battery soc: %.0f%%", soc)
site.publish("batterySoC", math.Trunc(soc))
site.Lock()
defer site.Unlock()
// if battery is charging give it priority
if soc < site.PrioritySoC && batteryPower < 0 {
site.log.DEBUG.Printf("giving priority to battery at soc: %.0f", soc)

36
core/site_api.go Normal file
View file

@ -0,0 +1,36 @@
package core
import (
"errors"
"github.com/andig/evcc/api"
)
// SiteAPI is the external site API
type SiteAPI interface {
Healthy() bool
LoadPoints() []LoadPointAPI
SetPrioritySoC(float64) error
}
// GetPrioritySoC returns the PrioritySoC
func (site *Site) GetPrioritySoC() float64 {
site.Lock()
defer site.Unlock()
return site.PrioritySoC
}
// SetPrioritySoC sets the PrioritySoC
func (site *Site) SetPrioritySoC(soc float64) error {
site.Lock()
defer site.Unlock()
if _, ok := site.batteryMeter.(api.Battery); !ok {
return errors.New("battery not configured")
}
site.PrioritySoC = soc
site.publish("prioritySoC", site.PrioritySoC)
return nil
}

View file

@ -88,10 +88,19 @@ func (m *MQTT) listenSetters(topic string, apiHandler core.LoadPointAPI) {
// Run starts the MQTT publisher for the MQTT API
func (m *MQTT) Run(site core.SiteAPI, in <-chan util.Param) {
// site setters
m.Handler.Listen(fmt.Sprintf("%s/site/prioritySoC/set", m.root), func(payload string) {
soc, err := strconv.Atoi(payload)
if err == nil {
_ = site.SetPrioritySoC(float64(soc))
}
})
// number of loadpoints
topic := fmt.Sprintf("%s/loadpoints", m.root)
m.publish(topic, true, len(site.LoadPoints()))
// loadpoint setters
for id, lp := range site.LoadPoints() {
topic := fmt.Sprintf("%s/loadpoints/%d", m.root, id+1)
m.listenSetters(topic, lp)
@ -101,6 +110,7 @@ func (m *MQTT) Run(site core.SiteAPI, in <-chan util.Param) {
updated := time.Now().Unix()
m.publish(fmt.Sprintf("%s/updated", m.root), true, updated)
// publish
for p := range in {
topic := fmt.Sprintf("%s/site", m.root)
if p.LoadPoint != nil {