[{"element_type":"text","content":"\n        \u003cp\u003eBest answer is: email Adafruit support, the team will get your feeds reenabled as soon as possible.\u003c/p\u003e\n\u003cp\u003eIf you're aware that you're data is not worth anything and are happy to lose it all, then proceed to follow this guide to just recreate all the feed names.\u003c/p\u003e\n\u003cp\u003eShort answer is if there are only a couple then do it by hand, otherwise this script will save you a bit of time. I had nearly a hundred, and was curious on the state of the adafruit-io python library, so this happened :shrug:\u003c/p\u003e\n      ","metadata":{}},{"element_type":"alert","content":"This will delete your feeds that are currently disabled. If you haven't downloaded your feed data, then first go and do that as this script does not backup your data. It simply deletes each disabled feed and recreates.","metadata":{"class":"element row-fluid alert-element build-alert alert-warning","alert_type":"warning"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThis will delete and recreate all feeds that are disabled, except those that are part of WipperSnapper devices (you can now export those and then delete the device and re-import the exported JSON file).\u003c/p\u003e\n\u003cp\u003eYou'll need the adafruit-io python library, which is normally installed with this command:\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003epip install adafruit-io\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003eHowever I've modified the adafruit-io library to add the enabled flag, and it's not released yet so for now you'll want the following command instead:\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003epip install git+https://github.com/adafruit/Adafruit_IO_Python.git#add-enabled-attribute\u003c/code\u003e\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThen the script (see end of page) needs to be run, and if you use the \u003ccode\u003e-a\u003c/code\u003e command line argument then it runs without user confirmation (happens per feed). You'll \u003cstrong\u003eneed to update the script with your adafruit IO credentials, or pass them in as arguments/environment-variables.\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003ee.g.\u0026nbsp;\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003epython undisable-adafruit-io-grouped-feeds.py -a\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003eexample output (with debug=true changed in the script):\u003c/p\u003e\n      \n\n\n\n\n\n","metadata":{}},{"element_type":"code","content":"Fetching groups and their feeds...\nSkipping enabled feed: -really-silly\nSkipping enabled feed: 70041DF7750A-AfF-esp32s2-rev-tft-scd4x-co2\n*** Found WipperSnapper group: Feather Huzzah ESP8266 Stackable\nExport WipperSnapper device config and re-import instead of deleting and recreating feeds!!!\nhttps://io.adafruit.com/tyeth/devices/feather-esp826623549144\nSkipping enabled feed: silly-named-feed\nFound disabled feed in group 'My Feeds': temp\nDEBUG: Old feed\nDEBUG: obj: Feed(name='temp', key='temp', id=2687188, description='', enabled=False, unit_type=None, unit_symbol=None, history=True, visibility='private', license=None, status_notify=False, status_timeout=4320)\n\nDeleting feed: temp\nEnabling feed in cloned object...\nDEBUG: Enabled feed clone - double check!!!\nDEBUG: obj: Feed(name='temp', key='temp', id=2687188, description='', enabled=True, unit_type=None, unit_symbol=None, history=True, visibility='private', license=None, status_notify=False, status_timeout=4320)\n\nRecreating feed: temp\nSuccessfully recreated and reassigned feed: temp to group 'My Feeds'\nDEBUG: New feed\nDEBUG: obj: Feed(name='temp', key='temp', id=2687190, description='', enabled=True, unit_type=None, unit_symbol=None, history=True, visibility='private', license=None, status_notify=False, status_timeout=4320)\n\nSkipping enabled feed: temperature\nFound WipperSnapper group: BANANA Adafruit ESP32-S3 Feather with 4MB Flash 2MB PSRAM\nExport WipperSnapper device config and re-import instead of deleting and recreating feeds!!!\nhttps://io.adafruit.com/tyeth/devices/feather-esp32s3-4mbflash-2mbpsram13617589\nSkipping enabled feed: toast_burnt\nSkipping enabled feed: toast_burnt_this_month\nSkipping enabled feed: voc\nSkipping enabled feed: voc_events_last10seconds\nSkipping enabled feed: plant-sht3x-seedlings-external-humidity\nSkipping enabled feed: plant-sht3x-seedlings-external-temp\nSkipping enabled feed: plant-si7021-seedlings-internal-hum\nSkipping enabled feed: plant-si7021-seedlings-internal-temp\nFeed management completed.","metadata":{"language":"terminal","linenums":false}},{"element_type":"text","content":"\n  \n        \u003ch2\u003eHere's the script:\u003c/h2\u003e\n      \n","metadata":{}},{"element_type":"alert","content":"DATA LOSS WARNING: Read top warning!","metadata":{"class":"element row-fluid alert-element build-alert alert-danger","alert_type":"danger"}},{"element_type":"code","content":"\"\"\"\nundisable-adafruit-io-feeds.py\n\nEvaluates all Adafruit IO feeds, identifies disabled feeds, by group if any, and\nautomatically deletes and recreates each disabled feed. It offers an interactive\nmode for step-by-step confirmation and an automated mode for direct processing.\n\"\"\"\n# Change these or set environment variables / pass arguments\nDEFAULT_ADAFRUIT_IO_USERNAME = 'YOUR_ADAFRUIT_IO_USERNAME'\nDEFAULT_ADAFRUIT_IO_KEY = 'YOUR_ADAFRUIT_IO_KEY'\nDEBUG = False\n\n\nimport sys\nimport os\nimport argparse\nimport time\nfrom Adafruit_IO import Client, RequestError, Feed\n\n# Command-line Argument Parser Setup\nparser = argparse.ArgumentParser(description=\"Manage Adafruit IO feeds.\")\nparser.add_argument(\"-a\", \"--automated\", help=\"Enable automated mode\", action=\"store_true\")\nparser.add_argument(\"-u\", \"--username\", help=\"Adafruit IO Username\", type=str)\nparser.add_argument(\"-k\", \"--key\", help=\"Adafruit IO Key\", type=str)\nargs = parser.parse_args()\n\n# Environment Variables / Arguments / Defaults\nADAFRUIT_IO_USERNAME = args.username or os.environ.get(\"ADAFRUIT_IO_USERNAME\", DEFAULT_ADAFRUIT_IO_USERNAME)\nADAFRUIT_IO_KEY = args.key or os.environ.get(\"ADAFRUIT_IO_KEY\", DEFAULT_ADAFRUIT_IO_KEY)\n\ndef main():\n    \"\"\"\n    Main function to handle the feed management process.\n    \"\"\"\n    # Initialize Adafruit IO Client\n    aio = Client(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY)\n\n    # Determine mode\n    mode = 'automated' if args.automated else 'interactive'\n    if mode == 'interactive':\n        print(\"Running in interactive mode. Use -a or --automated for automated mode.\")\n\n    try:\n        print(\"Fetching groups and their feeds...\")\n        # Fetch all groups and their feeds\n        groups = aio.groups()\n        for group in groups:\n            if group.description == 'A WipperSnapper Device':\n                print(\"** Found WipperSnapper group:\", group.name)\n                print(\"Export WipperSnapper device config and re-import instead of deleting and recreating feeds!!!\")\n                print(f\"https://io.adafruit.com/{ADAFRUIT_IO_USERNAME}/devices/{group.key}\")\n                continue\n            for feed in group.feeds:\n                if hasattr(feed, \"enabled\") and feed.enabled is False:\n                    print(f\"Found disabled feed in group '{group.name}': {feed.name}\")\n\n                    if mode == 'interactive':\n                        confirm = input(f\"Do you want to delete and recreate the feed '{feed.name}' in group '{group.name}'? (y/N): \").strip().upper()\n                        if confirm != 'Y':\n                            continue\n\n                    if DEBUG:\n                        print(\"DEBUG: Old feed\")\n                        print(\"DEBUG: obj:\", feed)\n                        print(\"\")\n\n                    # Delete the disabled feed\n                    print(f\"Deleting feed: {feed.name}\")\n                    aio.delete_feed(feed.key)\n                    # Wait for Adafruit IO to process the deletion\n                    time.sleep(0.25)\n\n                    print(\"Enabling feed in cloned object...\")\n                    feed = feed._replace(enabled=True)\n                    \n                    if DEBUG:\n                        print(\"DEBUG: Enabled feed clone - double check!!!\")\n                        print(\"DEBUG: obj:\", feed)\n                        print(\"\")\n\n                    # Recreate the feed with the same settings\n                    print(f\"Recreating feed: {feed.name}\")\n                    new_feed = aio.create_feed(feed, group.key if group.key else None) # Reassign to group\n                    print(f\"Successfully recreated and reassigned feed: {new_feed.name} to group '{group.name}'\")\n\n                    if DEBUG:\n                        print(\"DEBUG: New feed\")\n                        print(\"DEBUG: obj:\", new_feed)\n                        print(\"\")\n\n                else:\n                    print(f\"Skipping enabled feed: {feed.name}\")\n\n    except RequestError as e:\n        print(f\"An error occurred: {e}\")\n        sys.exit(1)\n\n    print(\"Feed management completed.\")\n\nif __name__ == \"__main__\":\n    main()","metadata":{"language":"python","linenums":false}}]