Add battery grid charging (#14855)

This commit is contained in:
andig 2024-08-03 15:23:50 +02:00 • committed by GitHub
parent bbf989c3c0
commit b0ea0582e2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 797 additions and 489 deletions

View file

@ -105,10 +105,13 @@ func (s *HTTPd) RegisterSiteHandlers(site site.API, valueChan chan<- util.Param)
"buffersoc": {"POST", "/buffersoc/{value:[0-9.]+}", floatHandler(site.SetBufferSoc, site.GetBufferSoc)},
"bufferstartsoc": {"POST", "/bufferstartsoc/{value:[0-9.]+}", floatHandler(site.SetBufferStartSoc, site.GetBufferStartSoc)},
"batterydischargecontrol": {"POST", "/batterydischargecontrol/{value:[a-z]+}", boolHandler(site.SetBatteryDischargeControl, site.GetBatteryDischargeControl)},
"batterygridcharge": {"POST", "/batterygridchargelimit/{value:-?[0-9.]+}", floatPtrHandler(pass(site.SetBatteryGridChargeLimit), site.GetBatteryGridChargeLimit)},
"batterygridchargedelete": {"DELETE", "/batterygridchargelimit", floatPtrHandler(pass(site.SetBatteryGridChargeLimit), site.GetBatteryGridChargeLimit)},
"maxgridsupply": {"POST", "/maxgridsupply/{value:[0-9.]+}", floatHandler(site.SetMaxGridSupplyWhileBatteryCharging, site.GetMaxGridSupplyWhileBatteryCharging)},
"prioritysoc": {"POST", "/prioritysoc/{value:[0-9.]+}", floatHandler(site.SetPrioritySoc, site.GetPrioritySoc)},
"residualpower": {"POST", "/residualpower/{value:-?[0-9.]+}", floatHandler(site.SetResidualPower, site.GetResidualPower)},
"smartcost": {"POST", "/smartcostlimit/{value:-?[0-9.]+}", updateSmartCostLimit(site)},
"smartcostdelete": {"DELETE", "/smartcostlimit", updateSmartCostLimit(site)},
"tariff": {"GET", "/tariff/{tariff:[a-z]+}", tariffHandler(site)},
"sessions": {"GET", "/sessions", sessionHandler},
"updatesession": {"PUT", "/session/{id:[0-9]+}", updateSessionHandler},
@ -173,7 +176,8 @@ func (s *HTTPd) RegisterSiteHandlers(site site.API, valueChan chan<- util.Param)
"remotedemand": {"POST", "/remotedemand/{demand:[a-z]+}/{source:[0-9a-zA-Z_-]+}", remoteDemandHandler(lp)},
"enableThreshold": {"POST", "/enable/threshold/{value:-?[0-9.]+}", floatHandler(pass(lp.SetEnableThreshold), lp.GetEnableThreshold)},
"disableThreshold": {"POST", "/disable/threshold/{value:-?[0-9.]+}", floatHandler(pass(lp.SetDisableThreshold), lp.GetDisableThreshold)},
"smartCostLimit": {"POST", "/smartcostlimit/{value:-?[0-9.]+}", floatHandler(pass(lp.SetSmartCostLimit), lp.GetSmartCostLimit)},
"smartCost": {"POST", "/smartcostlimit/{value:-?[0-9.]+}", floatPtrHandler(pass(lp.SetSmartCostLimit), lp.GetSmartCostLimit)},
"smartCostDelete": {"DELETE", "/smartcostlimit", floatPtrHandler(pass(lp.SetSmartCostLimit), lp.GetSmartCostLimit)},
// "priority": {"POST", "/priority/{value:[0-9.]+}", floatHandler(pass(lp.SetPriority), lp.GetPriority)},
}

View file

@ -131,6 +131,20 @@ func floatHandler(set func(float64) error, get func() float64) http.HandlerFunc
return handler(parseFloat, set, get)
}
// floatPtrHandler updates float-pointer api
func floatPtrHandler(set func(*float64) error, get func() *float64) http.HandlerFunc {
return handler(func(s string) (*float64, error) {
var val *float64
f, err := parseFloat(s)
if err == nil {
val = &f
} else if s == "" {
err = nil
}
return val, err
}, set, get)
}
// intHandler updates int-param api
func intHandler(set func(int) error, get func() int) http.HandlerFunc {
return handler(strconv.Atoi, set, get)
@ -152,11 +166,16 @@ func boolGetHandler(get func() bool) http.HandlerFunc {
func updateSmartCostLimit(site site.API) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var val *float64
val, err := parseFloat(vars["value"])
if err != nil {
jsonError(w, http.StatusBadRequest, err)
return
if r.Method != http.MethodDelete {
f, err := parseFloat(vars["value"])
if err != nil {
jsonError(w, http.StatusBadRequest, err)
return
}
val = &f
}
for _, lp := range site.Loadpoints() {

View file

@ -178,12 +178,12 @@ func (m *MQTT) listenSiteSetters(topic string, site site.API) error {
{"/batteryDischargeControl", boolSetter(site.SetBatteryDischargeControl)},
{"/prioritySoc", floatSetter(site.SetPrioritySoc)},
{"/residualPower", floatSetter(site.SetResidualPower)},
{"/smartCostLimit", floatSetter(func(limit float64) error {
{"/smartCostLimit", floatPtrSetter(pass(func(limit *float64) {
for _, lp := range site.Loadpoints() {
lp.SetSmartCostLimit(limit)
}
return nil
})},
}))},
{"/batteryGridChargeLimit", floatPtrSetter(pass(site.SetBatteryGridChargeLimit))},
} {
if err := m.Handler.ListenSetter(topic+s.topic, s.fun); err != nil {
return err
@ -203,7 +203,7 @@ func (m *MQTT) listenLoadpointSetters(topic string, site site.API, lp loadpoint.
{"/limitEnergy", floatSetter(pass(lp.SetLimitEnergy))},
{"/enableThreshold", floatSetter(pass(lp.SetEnableThreshold))},
{"/disableThreshold", floatSetter(pass(lp.SetDisableThreshold))},
{"/smartCostLimit", floatSetter(pass(lp.SetSmartCostLimit))},
{"/smartCostLimit", floatPtrSetter(pass(lp.SetSmartCostLimit))},
{"/planEnergy", func(payload string) error {
var plan struct {
Time time.Time `json:"time"`

View file

@ -25,6 +25,18 @@ func floatSetter(set func(float64) error) func(string) error {
return setterFunc(parseFloat, set)
}
func floatPtrSetter(set func(*float64) error) func(string) error {
return func(s string) error {
var val *float64
if f, err := parseFloat(s); err == nil {
val = &f
} else if s != "" {
return err
}
return set(val)
}
}
func intSetter(set func(int) error) func(string) error {
return setterFunc(strconv.Atoi, set)
}