Tile updating in home app
I am tring your solution that creates a HomeKit bridge and connects devices to Apple Home. Question: Is there a way to update the tile states in the Home app directly from my smart device?
Current behavior:
When I tap a tile, events are sent to my backend, and everything works fine.
But if I try to send data (e.g., from a temperature sensor), the state doesn’t update until I restart the Home app.
Why does this happen, and how can I fix it?
How did you implement your HomeKit device using this library? How are you observing changes of your temperature sensor and set the new value?
Pretty straightforward test implementation here
type Device struct {
ID string
Name string
Type string
IsOn bool
Brightness int
Temperature float64
}
type DeviceManager struct {
devices map[string]*Device
}
func NewDeviceManager() *DeviceManager {
return &DeviceManager{
devices: make(map[string]*Device),
}
}
func (dm *DeviceManager) AddDevice(device *Device) {
dm.devices[device.ID] = device
}
func (dm *DeviceManager) UpdateDeviceState(deviceID string, isOn bool, brightness int, temp float64) {
if dev, ok := dm.devices[deviceID]; ok {
dev.IsOn = isOn
dev.Brightness = brightness
dev.Temperature = temp
log.Printf("Device %s state updated: On=%v, Brightness=%d, Temp=%.1f",
deviceID, isOn, brightness, temp)
}
}
func Start() {
dm := NewDeviceManager()
dm.AddDevice(&Device{ID: "1", Name: "lamp1", Type: "light"})
dm.AddDevice(&Device{ID: "2", Name: "tempSensor", Type: "thermostat"})
bridgeInfo := accessory.Info{
Name: fmt.Sprintf("%s_%s", "CompanyName", /*generates rnd string*/ password.GeneratePassword(6)),
Manufacturer: "My Company",
}
bridge := accessory.NewBridge(bridgeInfo)
fs := hap.NewFsStore("/tmp/db")
if _, err := fs.Get("accessories"); err != nil && !os.IsNotExist(err) {
log.Fatalf("Error trying to get db: %v", err)
}
var accessories []*accessory.A
// save pointers to devices
var lampAcc *accessory.Lightbulb
var thermoAcc *accessory.Thermostat
for _, dev := range dm.devices {
switch dev.Type {
case "light":
acc := accessory.NewLightbulb(accessory.Info{
Name: dev.Name,
Manufacturer: "My Company",
})
acc.Lightbulb.On.OnValueRemoteUpdate(func(on bool) {
dm.UpdateDeviceState(dev.ID, on, dev.Brightness, dev.Temperature)
log.Printf("Device %s state changed: %v", dev.Name, on)
})
accessories = append(accessories, acc.A)
lampAcc = acc
case "thermostat":
acc := accessory.NewThermostat(accessory.Info{
Name: dev.Name,
Manufacturer: "My Company",
})
acc.Thermostat.TargetTemperature.OnValueRemoteUpdate(func(temp float64) {
dm.UpdateDeviceState(dev.ID, dev.IsOn, dev.Brightness, temp)
log.Printf("temp sensor %s is changed state: %.1f°C", dev.Name, temp)
})
accessories = append(accessories, acc.A)
thermoAcc = acc
}
}
server, err := hap.NewServer(fs, bridge.A, accessories...)
if err != nil {
log.Panic(err)
}
server.Pin = "13371337"
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
ctx, cancel := context.WithCancel(context.Background())
go func() {
<-c
signal.Stop(c)
cancel()
}()
// lamp1 demo
go func() {
ticker := time.NewTicker(3 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
if lampAcc != nil {
newState := !lampAcc.Lightbulb.On.Value()
lampAcc.Lightbulb.On.SetValue(newState)
log.Printf("Lamp state switch %v", newState)
}
case <-ctx.Done():
return
}
}
}()
// temp sensor demo
go func() {
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
if thermoAcc != nil {
newTemp := 18 + rand.Float64()*7 // 18-25°C
thermoAcc.Thermostat.CurrentTemperature.SetValue(newTemp)
thermoAcc.Thermostat.TargetTemperature.SetValue(newTemp)
log.Printf("Demo: temp sensor is set to: %.1f°C", newTemp)
}
case <-ctx.Done():
return
}
}
}()
log.Println("Starting HomeKit...")
log.Println("PIN is 13371337")
if err := server.ListenAndServe(ctx); err != nil {
log.Fatal(err)
}
}
Platform: MIPSEL / OpenWRT 19 Summary: Home app notification only works after restart; unclear bridge discovery behavior (Avahi vs. dnssd)
Details: I've successfully cross-compiled my solution with this library for the MIPSEL/OpenWRT19 platform. The accessory posts correctly and generally functions as expected. However, the Home app only receives the accessory notification after application restart or some time after device state chaged using Home app.
Additionally, I'm experiencing issues with bridge discovery. I'm using Avahi, while the library relies on dnssd, which may be causing conflicts. Discovery starts working at seemingly random time — I’m not sure what triggers it. Eventually, I was able to discover and pair the bridge with the Home app, but the behavior is inconsistent.