joeyhage / homebridge-alexa-smarthome

Connect Alexa devices to HomeKit
MIT License
81 stars 20 forks source link

Filtering of devices based on Skill ID #124

Closed NorthernMan54 closed 2 months ago

NorthernMan54 commented 4 months ago

Description

I have found that users of your plugin and mine ( homebridge-alexa) have gotten themselves into a bit of a device adding loop, where each of plugins discovers the devices from the other plugin and keeps adding them. Eventually triggering a meltdown of homebridge due to too many devices being created.

To resolve this I made the following changes.

1 - Added your plugin name as the manufacturer of the Homebridge Accessory, this is to allow homebridge-alexa to filter out accessories created by homebridge-alexa-smarthome. A corresponding change will be made to homebridge-alexa to filter devices coming from manufacturer homebridge-alexa-smarthome.

2 - Added filtering of devices retrieved from Amazon, based on the skill id. The internal skill identifier is a base 64 encoded value, which contains the amazon internal skill id ie {"skillId":"amzn1.ask.skill.2af008bb-2bb0-4bef-b131-e191f944a87e","stage":"live"}

3 - Added trapping of errors coming from homebridge, when too many devices are created. A single instance of homebridge is limited to 149 devices.

4 - Added a feature to expedite testing, npm run test-watch. This is similar to npm run watch, except that it reruns jest on a code change.

PS This is a draft, take a look and send some feedback. It is also the first time I have encountered fp-ts so I likely mangled things around it.

Type of change

How Has This Been Tested?

Checklist:

joeyhage commented 3 months ago

Sorry for the delay on this. I have been troubleshooting problems with the Alexa API so I haven't been able to test. It seems as though Amazon is cracking down on use of their API so I'm not sure if this plugin is still viable or if it still works for anyone.

NorthernMan54 commented 3 months ago

I have been watch the usage stats, and it appears that amazon has effectively blocked the plugin, so no urgency or need to implement.

I'm wondering if you managed the resource impact differently, you might slip thru unnoticed? Ie don't poll for status

image
joeyhage commented 3 months ago

Good to know! By default, it doesn’t poll, only looks up status when requested and if the cached values have expired. But, maybe I have a false understanding of how often Homebridge/HomeKit attempts to update device statuses. Does it only update when HomeKit is open or does it update in the background, too?

NorthernMan54 commented 3 months ago

HomeKit uses two different methods to receive updates

1 - It expects push notifications when a device status changes ( this is used to trigger automations etc ). The home app will register a characteristic for events ( push notifications ) when needed.

2 - It requests status when the Home changes to a new room ( it polls the status for all devices in a room )

I found that the plugin was requesting a status update for all devices, approx. every 90 seconds. And it was requesting all devices in parallel, hence the resource issues.

If you just wired into the .on('get' event, status would be retrieved when the Home App is open to a particular room. This would dramatically reduce the resource impact, but would break all automations.

joeyhage commented 3 months ago

It has a lock in place that only allows one call to the device status API at a time. This API call returns statuses for all devices at once and saves them in memory. So if 10 devices request an update at once, only one will make an API call, the other 9 will wait until that is done, see the cache was updated and use the cached value. This worked well for months but it seems Amazon is moving towards a GraphQL API (based on the results of reverse engineering the Alexa App now vs 10 months ago).

joeyhage commented 2 months ago

@NorthernMan54 this functionality has been implemented in v2.2.0-alpha.2