Skip to content

Groups: send multiple feeds data at once #162

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

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

tyeth
Copy link
Contributor

@tyeth tyeth commented May 22, 2025

@bradanlane mentioned on discord the desire to send data for multiple feeds at once. The API supports this but library does not.
I equally wanted this multiple times in the past, and have now done an experimental PR which satisfies the need.

Could do with more severe testing, and I dislike that it fails if the groupname prefix is included in the feed key.
@lorennorman maybe we can make the API endpoint for groups/GROUPNAME/data allow the feeds datapoints to use a key that includes the group prefix as it causes a fatal error - I appreciate it's an unnecessary qualification including the prefix but also what IO returns for feed.key so very likely to be passed over by a user to the send method.
To test the error, just modify my new tests to not do the replace on group feed key here:

{"key": test_feed1.key.replace(
test_group.key + ".", ""), "value": 43},
{"key": test_feed2.key.replace(
test_group.key + ".", ""), "value": 43}

@bradanlane
Copy link

bradanlane commented May 23, 2025

Tested with the attached code. The only issue I found was that I expected the post response as a return value, similar to how send_data() behaves.

BTW: looking at client.py I would add the same comment of expecting the post response for the send_batch_data() method.

import time
import datetime
import random

from Adafruit_IO import Client

class AIO:
    def __init__(self, user, key):
        self.aio = Client(user, key)
        self.active = True

    def send_data_to_group(self, val1, val2, val3, val4):
        timestamp = datetime.datetime.now(datetime.timezone.utc).isoformat()
        data = {
            "feeds": [
                {"key": "cht1", "value": val1},
                {"key": "cht2", "value": val2},
                {"key": "cht3", "value": val3},
                {"key": "cht4", "value": val4}
            ],
            "created_at": timestamp,
            #"lat": 0.0,
            #"lon": 0.0,
            #"ele": 0.0,
        }
        response = self.aio.send_group_multiple_data(AIO_GROUP_KEY, data)
        print(f"Response: {response}")

aio = AIO(AIO_USER, AIO_KEY)

# setup data for test
values = [random.uniform(27, 37) for _ in range(4)]
counter = 25
while True:
    counter -= 1
    # Gradually increase each value
    if counter <= 0:
        break
    for i in range(4):
        increment = random.uniform(0.5, 1.5) * counter
        values[i] += increment

    aio.send_data_to_group(values[0], values[1], values[2], values[3])
    time.sleep(30)

@tyeth
Copy link
Contributor Author

tyeth commented May 23, 2025 via email

@tyeth tyeth self-assigned this May 23, 2025
@tyeth
Copy link
Contributor Author

tyeth commented May 23, 2025

Regarding the API changes at the server end to accommodate group prefixes for feed keys:
I did think we could just do a split on '.' and take last, don't even check it, then if feed isn't it group it fails like usual (could offer that in error message though). Alternatively we validate that group prefixed feed exists (could be group2 prefix but same feed) and is member of group1

@bradanlane
Copy link

bradanlane commented May 23, 2025

Regarding the API changes at the server end to accommodate group prefixes for feed keys...

tl:dr; As an end user vs a developer or tester of the API, I expected the "feed keys" to not be prefixed with the "group key". Translation, the current construction of the data dictionary is as I would expect.

.

The current implementation feels intuitive.

As a user, I create my groups and feeds once (and most often manually). The same goes for my dashboard. Then, my code has constants for the group key and feeds once keys. (similar to how it needs constants for my user name and key).

I can see the issue when developing tests where the whole process from birth to death is encapsulated in the test. I just didn't see that as an intuitive method for end users.

Addendum: a search of GitHub for usage of Adafruit_IO shows a majority of users simply code their feed keys as static strings or constants.

@tyeth
Copy link
Contributor Author

tyeth commented May 23, 2025

I agree with that sentiment too, but it occurred to me the user may not be generating those keys, instead receiving them from IO and using for later posting. I'm not sure how the Group and Feed class objects quite behave with those group prefixes, but I can definitely remember having received / tried to use such a key in the past.

@bradanlane
Copy link

bradanlane commented May 23, 2025

I was only speaking from personal experience and the GitHub search.

As an end user, I created my groups, feeds, and dashboards via the web experience. The web experience gives you the non-hierarchical name.

Example: when I create a group called "Engine" it shows me the key "engine". Then when I create feeds within the group "CHT1", "CHT2", etc. it shows me the keys "cht1", "cht2", etc.

The web experiences never shows me hierarchically names.

@tyeth
Copy link
Contributor Author

tyeth commented May 23, 2025

At the bottom of the Feed Info dialog (on feed page) is a link to "Show detailed feed JSON record", which I think shows you the json you would get when requesting the feed via the API.
This gets doubly confusing if a user adds a feed to two groups, but classically while testing/demoing that I found/filed a UI bug related to setting additional groups on a feed.

@bradanlane
Copy link

I did look at it once but the default user experience gives the simple keys.

I get the desire to cover all the bases but from a UX perspective, "the default should always be simple".

@lorennorman
Copy link

I've made the requested changes to that API endpoint for you now, @tyeth!

groups/:key/data will now allow feeds to be specified with their joined key. If provided, it will ensure that the group_key portion of the key matches the group in the URL. Feeds with joined keys that do not match the group are silently ignored.

@bradanlane
Copy link

Should change to return the response from _post() for both send_batch_data() and send_data_to_group() be done as part of this PR or should it be a separate PR?

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