evcc-io/util/homeassistant/instance.go

92 lines
1.7 KiB
Go

package homeassistant
import (
"fmt"
"sync"
"github.com/evcc-io/evcc/plugin/auth"
"github.com/evcc-io/evcc/util"
"golang.org/x/oauth2"
)
func init() {
auth.Register("homeassistant", NewHomeAssistantFromConfig)
}
// NewHomeAssistantFromConfig creates a Home Assistant token source from configuration
func NewHomeAssistantFromConfig(other map[string]any) (oauth2.TokenSource, error) {
var cc struct {
URI string
Home string // TODO remove deprecated
Insecure bool
}
if err := util.DecodeOther(other, &cc); err != nil {
return nil, err
}
uri := cc.URI
if uri == "" && cc.Home != "" {
uri = instanceUriByName(cc.Home)
if uri == "" {
return nil, fmt.Errorf("unknown instance: %s", cc.Home)
}
}
if ts, ok := supervisorTokenSource(uri); ok {
return ts, nil
}
return NewOAuth(uri, cc.Insecure)
}
type proxyInstance struct {
mu sync.Mutex
home, uri string
insecure bool
oauth2.TokenSource
}
func (inst *proxyInstance) URI() string {
inst.mu.Lock()
defer inst.mu.Unlock()
if inst.uri == "" && inst.home != "" {
// Try to resolve home name to URI (backward compatibility)
inst.uri = instanceUriByName(inst.home)
if inst.uri == "" {
return ""
}
}
return inst.uri
}
func (inst *proxyInstance) Token() (*oauth2.Token, error) {
uri := inst.URI()
if uri == "" {
if inst.home != "" {
return nil, fmt.Errorf("unknown instance: %s", inst.home)
}
return nil, fmt.Errorf("no URI configured")
}
inst.mu.Lock()
defer inst.mu.Unlock()
if inst.TokenSource == nil {
if ts, ok := supervisorTokenSource(uri); ok {
inst.TokenSource = ts
} else {
ts, err := NewOAuth(uri, inst.insecure)
if err != nil {
return nil, err
}
inst.TokenSource = ts
}
}
return inst.TokenSource.Token()
}