evcc-io/util/homeassistant/service.go

81 lines
1.6 KiB
Go

package homeassistant
import (
"encoding/json"
"maps"
"net/http"
"slices"
"strings"
"github.com/evcc-io/evcc/server/service"
"github.com/evcc-io/evcc/util"
"github.com/samber/lo"
)
var log = util.NewLogger("homeassistant")
func init() {
mux := http.NewServeMux()
mux.HandleFunc("GET /homes", getHomes)
mux.HandleFunc("GET /homes/{home}/entities", getEntities)
service.Register("homeassistant", mux)
}
func getHomes(w http.ResponseWriter, req *http.Request) {
mu.Lock()
defer mu.Unlock()
jsonWrite(w, slices.Sorted(maps.Keys(instances)))
}
func getEntities(w http.ResponseWriter, req *http.Request) {
home := req.PathValue("home")
if instanceUriByName(home) == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
conn, _ := NewConnection(log, home)
res, err := conn.GetStates()
if err != nil {
jsonError(w, http.StatusBadRequest, err)
return
}
var domains []string
if domain := req.URL.Query().Get("domain"); domain != "" {
domains = strings.Split(domain, ",")
}
// cache list of entities
w.Header().Set("Cache-control", "max-age=300")
jsonWrite(w, lo.Map(lo.Filter(res, func(e StateResponse, _ int) bool {
if len(domains) == 0 {
return true
}
for _, domain := range domains {
if strings.HasPrefix(e.EntityId, domain+".") {
return true
}
}
return false
}), func(e StateResponse, _ int) string {
return e.EntityId
}))
}
// jsonWrite writes a JSON response
func jsonWrite(w http.ResponseWriter, data any) {
json.NewEncoder(w).Encode(data)
}
// jsonError writes an error response
func jsonError(w http.ResponseWriter, status int, err error) {
w.WriteHeader(status)
jsonWrite(w, util.ErrorAsJson(err))
}