45 lines
1.3 KiB
Go
45 lines
1.3 KiB
Go
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)
|
|
}
|