Skip to content

No Response

Erik Baauw edited this page Dec 13, 2023 · 13 revisions

No Response in HomeKit

HomeKit sets the No Response state for an accessory, when a request to that accessory times out, or results in an error response. It clears the No Response state, when a request to the accessory results in a valid response. No Response doesn't mean that the accessory isn't currently responding, only that the last request to the accessory didn't result in a valid response.

HomeKit Accessory Protocol (HAP)

A HomeKit accessory provides a web server to HomeKit, for HomeKit to interact with the accessory. They communicate using the HomeKit Accessory Protocol (HAP), which is based on HTTP. Bluntly speaking, HAP provides three operations on characteristics:

  • read: HomeKit issues a request to get the current value, the accessory responds with the value or with an error;
  • write: HomeKit issues a request to set a new value; the accessory response with the status (success or error) and, optionally, with the new value;
  • event: The accessory pushes a new value to HomeKit, or rather, to HomeKit runtime instances that subscribed to notifications for this characteristic.

When a read or write results in an error or in no response at all, HomeKit sets the No Response state for the accessory, and Home shows No Response in the tile(s). Other HomeKit apps might show this state in a different way, e.g. Eve shows a little red triangle.
When a subsequent read or write succeeds, the No Response state is cleared, and Home no longer shows No Response.
The No Response state isn't updated on an event (I think this is because HomeKit cancels the subscriptions when it sets No Response). So an accessory cannot clear No Response, the initiative for this needs to come from HomeKit.

Bridged Accessories

A HomeKit bridge (like Homebridge) provides access to multiple accessories from a single HAP server. When the bridge doesn't respond, HomeKit marks all accessories exposed by that bridge as No Response. By returning an error a bridge can cause No Response to be set for a single bridged accessory, e.g. in case the corresponding device is not reachable. By returning a valid response for the next request, a bridge can cause the No Response state to be cleared. As with non-bridged accessories, there is no way for a bridge to push the No Response state to HomeKit; the initiative needs to come from HomeKit.

Tip: Run Homebridge with DEBUG=* set in the environment, to have HAP-NodeJS log the interaction with HomeKit.

Setting or Clearing No Response

As mentioned before, the initiative to set or clear must come from HomeKit, so you need to get it to issue a read or write request to the accessory or bridge.
You can trigger a write by changing a characteristic value in Home or another HomeKit app. Triggering a read is very tricky. Sometimes refreshing a view, or changing views in Home or another HomeKit app triggers a read, but other times it doesn't. The only sure way to trigger a read is to force-quit and restart Home.

reachable in the Hue API

The Hue API exposes a reachable attribute on resources corresponding to Zigbee devices. This attribute is set on receipt of a message from the device. It is cleared when a few subsequent requests to the device go unanswered. A value false for reachable doesn't mean that the device is currently unreachable, only that it didn't respond the last couple of times that the bridge tried to reach the device.

Power Off

Of course, devices are unreachable when powered off. However, they is no definite way for other devices, including the bridge, to ascertain whether a device is powered off or no response is received for another reason. Not surprisingly, Zigbee doesn't define any message for a device to announce that it's powered down. How would the device send the message without power?

When the firmware of a Zigbee device boots, it broadcasts a Device Announcement message, to announce its presence in the Zigbee network. As the bridge picks this up, it sets reachable.

End Devices

Technically, Zigbee end devices are unreachable almost all of the time. They turn off their radio to preserve (battery) power. Messages to an end device are delivered to its parent router, who saves them for 7.5 seconds. Periodically, the end device wakes up and "polls" its parent, it asks its parent if there's any messages. "Light sleepers" poll their parent router at least every 7.5 seconds, and appear to be responding to requests, albeit with a delay. "Deep sleepers" poll their parent at longer intervals (up to several hours), and appear to be dead. The bridge needs to hold any requests, until the end device is awake. The pending requests are exposed through config.pending.

What Happens When reachable Is false?

The Hue API continues to accept PUT requests, returning OK. Initially, it still sends the corresponding commands to the Zigbee device. After some time, it concludes that the device really is unreachable, stops polling it, and silently drops any requests to it, while still returning OK to the API call.

The native HomeKit function of the Hue bridge returns an error on read or write, and doesn't send the corresponding Zigbee commands, even when the API still would.

Homebridge Hue

Because No Response cannot be set or cleared directly from an accessory, Homebridge Hue exposes reachable as Status Fault by default. It does not return any error response, causing HomeKit to set No Response. To change this, and make Homebridge Hue behave more like the native Hue bridge HomeKit function and other plugins, set noResponse.

Status Fault

When the API reports a resource with reachable false, Homebridge Hue sets Status Fault. It clears Status Fault when reachable becomes true again. Otherwise, Homebridge Hue does not handle reachable in any special way.

Like any number or boolean characteristic, Status Fault can be used on HomeKit automations.

There are also some issues with using Status Fault:

  • Most other Homebridge plugins and the native HomeKit feature of the Hue bridge report unreachable devices by returning an error status on read or write, causing HomeKit to set No Response;
  • The Home app gracefully ignores Status Fault, so if you're only using that app, you have no clue about reachable being false;
  • Quite a number of people continue to use 20th century wall switches to power off their smart lights. Homebridge Hue continues to show these lights as on.

To address these issues, the noResponse setting was introduced.

No Response

To change the default behaviour, set noResponse, in config.json. When reachable becomes false and noResponse is set, Homebridge Hue, in addition to setting Status Fault:

  • Returns an error response on a HomeKit read of On or Active;
  • Returns an error response on a HomeKit write for any state attribute, but still sends the corresponding request to the Hue bridge.