Sunspec: share block reads across values on the same connection (#33011)
This commit is contained in:
parent
1a0a05c9ad
commit
de0bac2bc8
3 changed files with 210 additions and 1 deletions
45
plugin/sunspec_client.go
Normal file
45
plugin/sunspec_client.go
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/evcc-io/evcc/util/modbus"
|
||||
gridx "github.com/grid-x/modbus"
|
||||
)
|
||||
|
||||
// sunspecCachedClient dedups the holding register reads gosunspec issues on
|
||||
// behalf of all sunspec values sharing a model block within one poll cycle.
|
||||
type sunspecCachedClient struct {
|
||||
gridx.Client
|
||||
cache *modbus.Cache
|
||||
}
|
||||
|
||||
// newSunspecCachedClient wraps client for use as gosunspec's modbus client.
|
||||
func newSunspecCachedClient(client gridx.Client) *sunspecCachedClient {
|
||||
return &sunspecCachedClient{Client: client, cache: modbus.NewCache(modbusBlockTTL)}
|
||||
}
|
||||
|
||||
func (c *sunspecCachedClient) ReadHoldingRegisters(address, quantity uint16) ([]byte, error) {
|
||||
key := fmt.Sprintf("%d/%d", address, quantity)
|
||||
|
||||
b, _, err := c.cache.Fetch(key, func() ([]byte, error) {
|
||||
return c.Client.ReadHoldingRegisters(address, quantity)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// callers unmarshal in place, hand out a copy of the shared payload
|
||||
return bytes.Clone(b), nil
|
||||
}
|
||||
|
||||
func (c *sunspecCachedClient) WriteSingleRegister(address, value uint16) ([]byte, error) {
|
||||
defer c.cache.Clear()
|
||||
return c.Client.WriteSingleRegister(address, value)
|
||||
}
|
||||
|
||||
func (c *sunspecCachedClient) WriteMultipleRegisters(address, quantity uint16, value []byte) ([]byte, error) {
|
||||
defer c.cache.Clear()
|
||||
return c.Client.WriteMultipleRegisters(address, quantity, value)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue