Tibber: resubscribe on clean disconnect (#18643)
This commit is contained in:
parent
40170cc93c
commit
4f978242e5
1 changed files with 33 additions and 20 deletions
|
|
@ -20,7 +20,9 @@ func init() {
|
|||
}
|
||||
|
||||
type Tibber struct {
|
||||
data *util.Monitor[tibber.LiveMeasurement]
|
||||
data *util.Monitor[tibber.LiveMeasurement]
|
||||
homeID string
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
func NewTibberFromConfig(ctx context.Context, other map[string]interface{}) (api.Meter, error) {
|
||||
|
|
@ -67,7 +69,9 @@ func NewTibberFromConfig(ctx context.Context, other map[string]interface{}) (api
|
|||
}
|
||||
|
||||
t := &Tibber{
|
||||
data: util.NewMonitor[tibber.LiveMeasurement](cc.Timeout),
|
||||
data: util.NewMonitor[tibber.LiveMeasurement](cc.Timeout),
|
||||
homeID: cc.HomeID,
|
||||
timeout: cc.Timeout,
|
||||
}
|
||||
|
||||
// subscription client
|
||||
|
|
@ -99,18 +103,8 @@ func NewTibberFromConfig(ctx context.Context, other map[string]interface{}) (api
|
|||
return nil
|
||||
})
|
||||
|
||||
done := make(chan error, 1)
|
||||
go func(done chan error) {
|
||||
done <- t.subscribe(client, cc.HomeID)
|
||||
}(done)
|
||||
|
||||
select {
|
||||
case err := <-done:
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case <-time.After(cc.Timeout):
|
||||
return nil, api.ErrTimeout
|
||||
if err := t.ensureSubscribed(client); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
|
@ -121,11 +115,16 @@ func NewTibberFromConfig(ctx context.Context, other map[string]interface{}) (api
|
|||
}()
|
||||
|
||||
go func() {
|
||||
// The pulse sometimes declines valid(!) subscription requests, and asks the client to disconnect.
|
||||
// Therefore we need to restart the client when exiting gracefully upon server request
|
||||
// https://github.com/evcc-io/evcc/issues/17925#issuecomment-2621458890
|
||||
for tick := time.Tick(10 * time.Second); ; {
|
||||
if err := client.Run(); err != nil {
|
||||
err := client.Run()
|
||||
if err == nil {
|
||||
// The pulse sometimes declines valid(!) subscription requests, and asks the client to disconnect.
|
||||
// This invalidates the subscription, and therefore we resubscribe when exiting Run() gracefully
|
||||
// upon server request.
|
||||
// https://github.com/evcc-io/evcc/issues/17925#issuecomment-2621458890
|
||||
err = t.ensureSubscribed(client)
|
||||
}
|
||||
if err != nil {
|
||||
log.ERROR.Println(err)
|
||||
}
|
||||
|
||||
|
|
@ -140,13 +139,27 @@ func NewTibberFromConfig(ctx context.Context, other map[string]interface{}) (api
|
|||
return t, nil
|
||||
}
|
||||
|
||||
func (t *Tibber) subscribe(client *graphql.SubscriptionClient, homeID string) error {
|
||||
func (t *Tibber) ensureSubscribed(client *graphql.SubscriptionClient) error {
|
||||
done := make(chan error, 1)
|
||||
go func(done chan error) {
|
||||
done <- t.subscribe(client)
|
||||
}(done)
|
||||
|
||||
select {
|
||||
case err := <-done:
|
||||
return err
|
||||
case <-time.After(t.timeout):
|
||||
return api.ErrTimeout
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tibber) subscribe(client *graphql.SubscriptionClient) error {
|
||||
var query struct {
|
||||
tibber.LiveMeasurement `graphql:"liveMeasurement(homeId: $homeId)"`
|
||||
}
|
||||
|
||||
_, err := client.Subscribe(&query, map[string]any{
|
||||
"homeId": graphql.ID(homeID),
|
||||
"homeId": graphql.ID(t.homeID),
|
||||
}, func(data []byte, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue