diff --git a/go.mod b/go.mod index 16f15c7..78cc192 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,8 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1 // indirect github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f // indirect + github.com/tadglines/go-pkgs v0.0.0-20210623144937-b983b20f54f9 // indirect + golang.org/x/crypto v0.48.0 // indirect golang.org/x/mod v0.33.0 // indirect golang.org/x/net v0.50.0 // indirect golang.org/x/sync v0.19.0 // indirect diff --git a/go.sum b/go.sum index b202810..21c0973 100644 --- a/go.sum +++ b/go.sum @@ -47,6 +47,10 @@ github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f h1:1R9KdKjCNSd7F8iGTxI github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f/go.mod h1:vQhwQ4meQEDfahT5kd61wLAF5AAeh5ZPLVI4JJ/tYo8= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tadglines/go-pkgs v0.0.0-20210623144937-b983b20f54f9 h1:aeN+ghOV0b2VCmKKO3gqnDQ8mLbpABZgRR2FVYx4ouI= +github.com/tadglines/go-pkgs v0.0.0-20210623144937-b983b20f54f9/go.mod h1:roo6cZ/uqpwKMuvPG0YmzI5+AmUiMWfjCBZpGXqbTxE= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= diff --git a/internal/homekit/homekit.go b/internal/homekit/homekit.go new file mode 100644 index 0000000..d6ca9bb --- /dev/null +++ b/internal/homekit/homekit.go @@ -0,0 +1,62 @@ +package homekit + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/AlexxIT/go2rtc/pkg/hap" + "github.com/eduard256/strix/internal/api" + "github.com/eduard256/strix/internal/app" + "github.com/rs/zerolog" +) + +var log zerolog.Logger + +func Init() { + log = app.GetLogger("homekit") + + api.HandleFunc("api/homekit/pair", apiPair) +} + +func apiPair(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + return + } + + var req struct { + IP string `json:"ip"` + Port int `json:"port"` + DeviceID string `json:"device_id"` + PIN string `json:"pin"` + } + + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + if req.IP == "" || req.Port == 0 || req.DeviceID == "" || req.PIN == "" { + http.Error(w, "ip, port, device_id and pin required", http.StatusBadRequest) + return + } + + // ex. "homekit://10.0.10.52:45959?device_id=90:8C:0F:F2:EC:F3&pin=12345678" + rawURL := fmt.Sprintf("homekit://%s:%d?device_id=%s&pin=%s", req.IP, req.Port, req.DeviceID, req.PIN) + + log.Debug().Str("ip", req.IP).Int("port", req.Port).Str("device_id", req.DeviceID).Msg("[homekit] pair") + + conn, err := hap.Pair(rawURL) + if err != nil { + log.Warn().Err(err).Str("ip", req.IP).Msg("[homekit] pair failed") + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer conn.Close() + + url := conn.URL() + log.Info().Str("ip", req.IP).Str("device_id", req.DeviceID).Msg("[homekit] paired") + + api.ResponseJSON(w, map[string]string{"url": url}) +} diff --git a/internal/probe/probe.go b/internal/probe/probe.go index fb524a9..90e7838 100644 --- a/internal/probe/probe.go +++ b/internal/probe/probe.go @@ -35,7 +35,7 @@ func Init() { ports = loadPorts() // HomeKit detector detectors = append(detectors, func(r *probe.Response) string { - if r.Probes.MDNS != nil && !r.Probes.MDNS.Paired { + if r.Probes.MDNS != nil { if r.Probes.MDNS.Category == "camera" || r.Probes.MDNS.Category == "doorbell" { return "homekit" } diff --git a/main.go b/main.go index 882d091..859c427 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "github.com/eduard256/strix/internal/frigate" "github.com/eduard256/strix/internal/generate" "github.com/eduard256/strix/internal/go2rtc" + "github.com/eduard256/strix/internal/homekit" "github.com/eduard256/strix/internal/probe" "github.com/eduard256/strix/internal/search" "github.com/eduard256/strix/internal/test" @@ -33,6 +34,7 @@ func main() { {"generate", generate.Init}, {"frigate", frigate.Init}, {"go2rtc", go2rtc.Init}, + {"homekit", homekit.Init}, } for _, m := range modules { diff --git a/www/homekit.html b/www/homekit.html index 258efc4..deb1b84 100644 --- a/www/homekit.html +++ b/www/homekit.html @@ -4,7 +4,7 @@ -
- We are working on adding Apple HomeKit camera support to Strix, but we don't have HomeKit cameras available for testing. -
-- The device at this IP supports HomeKit protocol. If you'd like to help us add support for HomeKit cameras, please reach out. Your contribution would be greatly appreciated. -
+