evcc-io/util/homeassistant/zeroconf.go

67 lines
1.2 KiB
Go

package homeassistant
import (
"context"
"fmt"
"strings"
"sync"
"github.com/evcc-io/evcc/util"
"github.com/libp2p/zeroconf/v2"
)
var (
mu sync.Mutex
instances = make(map[string]string)
)
func init() {
go scan()
}
func instanceUriByName(name string) string {
mu.Lock()
defer mu.Unlock()
return instances[name]
}
func addInstance(name, uri string) {
mu.Lock()
defer mu.Unlock()
instances[name] = uri
}
func scan() {
ctx := context.Background()
entries := make(chan *zeroconf.ServiceEntry, 1)
go func() {
for {
select {
case se := <-entries:
uri := fmt.Sprintf("http://%s:%d", se.HostName, se.Port)
OUTER:
for _, text := range se.Text {
for _, prefix := range []string{"external_url", "base_url", "internal_url"} {
if u, ok := strings.CutPrefix(text, prefix+"="); ok && u != "" {
uri = u
break OUTER
}
}
}
addInstance(se.Instance, uri)
case <-ctx.Done():
return
}
}
}()
if err := zeroconf.Browse(ctx, "_home-assistant._tcp.", "local.", entries); err != nil {
log := util.NewLogger("homeassistant")
log.ERROR.Println("zeroconf: failed to browse:", err.Error())
}
}