brutella/hap

hap does not support multiple servers/bridges

jurjevic opened this issue · 6 comments

	server, err := hap.NewServer(store, newBridge.A, a...)
	if err != nil {
		// stop if an error happens
		c.log.Printf("Error creating HAP Bridge '%s'", group)
	}
	server.Pin = "111111" // fake
	c.log.Printf("Starting HAP Bridge '%s' with %d devices", group, len(a))
	ctx, _ := context.WithCancel(context.Background()) // TODO implement cancel in top
	err = server.ListenAndServe(ctx)

Multiple bridges with accessories are supported by multiple servers only. So creating a new bridge and assign it to a new server will start listening on random ports. While the bridges all appear on the Home App 'Add new device', only one bridge can be added. When trying to add a second one, the Home App waits to connect and runs into an timeout. All server appear correctly in the DNS viewer. Is there a way to have multiple bridges?

Hi, try build like this
https://github.com/xxandev/homekit/blob/main/example/bridge/main.go
Test1

const (
	BRG_NAME    string = "Bridge-1"
	BRG_SN      string = "EX-Brg-1"
	BRG_ADDRESS string = ":11101"
	BRG_PIN     string = "12344321"
	BRG_MODEL   string = "HAP-BRG"
)

Test2

const (
	BRG_NAME    string = "Bridge-2"
	BRG_SN      string = "EX-Brg-2"
	BRG_ADDRESS string = ":11102"
	BRG_PIN     string = "12344321"
	BRG_MODEL   string = "HAP-BRG"
)

I've tried a similar code, which is not working:

func (c *bridge) start(id int, group string, a []*accessory.A) {
	bName := strings.ReplaceAll(group, " ", "-")
	newBridge := accessory.NewBridge(accessory.Info{
		Name:         bName,
		SerialNumber: fmt.Sprintf("%d", id),
		Manufacturer: "HBW",
		Model:        "Bridge " + group,
		Firmware:     "0.5",
	})
	store := hap.NewFsStore(bName + ".db")
	server, err := hap.NewServer(store, newBridge.A, a...)
	if err != nil {
		// stop if an error happens
		c.log.Printf("Error creating HAP Bridge '%s'", group)
	}
	server.Pin = "12312312"
	server.Addr = fmt.Sprintf(":%d", 40203+id)
	c.log.Printf("Starting HAP Bridge '%s' with %d devices", group, len(a))
	ctx, _ := context.WithCancel(context.Background()) // TODO implement cancel in top
	err = server.ListenAndServe(ctx)
	if err != nil {
		c.log.Printf("HAP Bridge '%s' execution failed with error %s", group, err)
	}
	c.log.Printf("Stopped HAP Bridge '%s'", group)
}

Still no luck here.

I've just tried out running a bridge twice and it worked for me on iOS 16.

I'm using iOS 15.5 - but I would wonder if this is the root cause.

Can you try this code, because it doesnt work on my Pi? Like I said, it shows up but I cant connect to both bridges at the same time.

func main() {
	// boot.Go()
	go test("1")
	test("2")
}

func test(id string) {
	b := accessory.NewBridge(accessory.Info{
		Name:         "Bridge" + id,
		SerialNumber: "SN" + id,
		Manufacturer: "M" + id,
		Model:        "Model" + id,
		Firmware:     "F" + id,
	})
	// Create the switch accessory.
	a := accessory.NewSwitch(accessory.Info{
		Name: "Lamp" + id,
	})

	// Store the data in the "./db" directory.
	fs := hap.NewFsStore("./db/" + id)

	// Create the hap server.
	server, err := hap.NewServer(fs, b.A, a.A)
	server.Pin = "12344321"
	if err != nil {
		// stop if an error happens
		log.Panic(err)
	}

	// Setup a listener for interrupts and SIGTERM signals
	// to stop the server.
	c := make(chan os.Signal)
	signal.Notify(c, os.Interrupt)
	signal.Notify(c, syscall.SIGTERM)

	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		<-c
		// Stop delivering signals.
		signal.Stop(c)
		// Cancel the context to stop the server.
		cancel()
	}()

	// Run the server.
	server.ListenAndServe(ctx)
}

Thanks for your sample code. I've fixed this issue in v0.0.17.

I can confirm that it works now... Thx!