Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use location endpoint #5

Merged
merged 5 commits into from
Jan 9, 2024

Conversation

LaStrada
Copy link
Contributor

@LaStrada LaStrada commented Oct 16, 2023

To reduce the number of network requests, we can use the location endpoint.

Instead of fetching device list + iterating all devices (n+1), we can fetch locations+device list, then iterate the locations to fetch latest samples.

Nothing wrong with the current implementation, but this caused some users to experience 429 error (too many requests) if they had >10 devices. For users with 10 devices, this will now be:

  • Fetch locations
  • Fetch device list (need the device type / product name)
  • Iterate through locations (for most users this is 1 or 2)

In total 3 requests, and when locations and devices are cached, this will be 1 request. Most users has only one location, but in some cases they might have a cabin, maybe an autogenerated "hidden" location etc. In my case on my account, I have 3 locations. In my case I'll go from 7 (+ device list) to 3 (+ locations and device list).

Some user could have many locations without any devices, this can be solved by ignoring empty locations. To keep this simple for now this is not covered in this PR.

This PR also includes product_name. Then we can use this directly in Home Assistant:

airthings_device.product_name,

instead of this:

airthings_device.device_type.replace("_", " ").lower().title(),

https://github.com/home-assistant/core/blob/dev/homeassistant/components/airthings/sensor.py#L152

Also added the location_name which can be helpful for debugging if the user has multiple devices with more or less the same name, for example kitchen in your home + cabin. Not sure where to use it / present it to the user, but it's now available to be used.

Documentation:
https://developer.airthings.com/consumer-api-docs#tag/Locations

Will fix these issues:
home-assistant/core#101666
#4

Example
{'xxxxxxxxxx': AirthingsDevice(device_id='xxxxxxxxxx', name='Emilie', sensors={'battery': 54, 'co2': 569.0, 'humidity': 39.0, 'pressure': 998.5, 'radonShortTermAvg': 30.0, 'rssi': -42, 'temp': 21.9, 'time': 1697452315, 'voc': 46.0, 'relayDeviceType': 'hub'}, is_active=None, location_name='Home', device_type='Wave Plus', product_name='WAVE_PLUS'), 'xxxxxxxxxx': AirthingsDevice(device_id='xxxxxxxxxx', name='Basement Mini', sensors={'battery': 97, 'humidity': 79.0, 'mold': 3.0, 'temp': 14.5, 'time': 1697447439, 'voc': 75.0, 'relayDeviceType': 'hub'}, is_active=None, location_name='Home', device_type='Wave Mini', product_name='WAVE_MINI'), 'xxxxxxxxxx': AirthingsDevice(device_id='xxxxxxxxxx', name='Office', sensors={'battery': 83, 'co2': 572.0, 'humidity': 37.0, 'pressure': 998.4, 'radonShortTermAvg': 22.0, 'rssi': -51, 'temp': 22.7, 'time': 1697452384, 'voc': 46.0, 'relayDeviceType': 'hub'}, is_active=None, location_name='Home', device_type='Wave Plus', product_name='WAVE_PLUS'), 'xxxxxxxxxx': AirthingsDevice(device_id='xxxxxxxxxx', name='Basement Wave', sensors={'battery': 54, 'humidity': 81.0, 'radonShortTermAvg': 899.0, 'temp': 14.3, 'time': 1697433607, 'relayDeviceType': 'hub'}, is_active=None, location_name='Home', device_type='Wave', product_name='WAVE_GEN2'), 'xxxxxxxxxx': AirthingsDevice(device_id='xxxxxxxxxx', name='Bathroom', sensors={'battery': 31, 'humidity': 45.0, 'mold': 0.0, 'temp': 25.5, 'time': 1695641686, 'voc': 59.0, 'relayDeviceType': 'hub'}, is_active=None, location_name='Home', device_type='Wave Mini', product_name='WAVE_MINI'), 'xxxxxxxxxx': AirthingsDevice(device_id='xxxxxxxxxx', name='Living Room', sensors={'battery': 7, 'co2': 583.0, 'humidity': 34.0, 'pm1': 0.0, 'pm25': 0.0, 'pressure': 998.0, 'radonShortTermAvg': 24.0, 'temp': 23.1, 'time': 1697452327, 'voc': 46.0, 'relayDeviceType': 'hub'}, is_active=None, location_name='Home', device_type='View Plus', product_name='VIEW_PLUS'), 'xxxxxxxxxx': AirthingsDevice(device_id='xxxxxxxxxx', name='Kitchen', sensors={'battery': 73, 'co2': 561.0, 'humidity': 36.0, 'pm1': 0.0, 'pm25': 0.0, 'pressure': 998.3, 'radonShortTermAvg': 23.0, 'temp': 22.1, 'time': 1697451917, 'voc': 48.0, 'relayDeviceType': 'hub'}, is_active=None, location_name='Home', device_type='View Plus', product_name='VIEW_PLUS'), 'xxxxxxxxxx': AirthingsDevice(device_id='xxxxxxxxxx', name='Hub', sensors={}, is_active=None, location_name='-', device_type='Hub', product_name='HUB')}

Disclaimer: I work for Airthings. Discussed this problem with the cloud developers and this is the way to go. Less load on our cloud, and fewer 429 errors for the users.

@LaStrada
Copy link
Contributor Author

If you need any test data, please contact me on Discord (same username) and I'll provide a user with test data.

@stevefal
Copy link

stevefal commented Jan 4, 2024

Related to #4. As there, I propose a better and more equitable solution to the 429 problem is for Airthings to limit requests to N*num_devices rather than N per client, the latter of which essentially penalizes customers who have paid the most buying many Airthings products.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants