[{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eI work on Adafruit IO, and I've had this mischievous plan for a while to adjust my \u003ca href=\"https://learn.adafruit.com/quickstart-adafruit-io-wippersnapper/welcome-to-wippersnapper\" target=\"_blank\"\u003eWipperSnapper\u003c/a\u003e no-code sensor devices to poll more frequently than the 30s minimum that the web interface offers, like maybe as low as 5seconds to avoid burning my toast (having recently tried measuring the particle emissions again but found it too infrequent).\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/198/original/ezgif.com-animated-gif-maker_%281%29.gif?1727527726","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eIt's running on an \u003ca href=\"https://www.adafruit.com/product/5438\" target=\"_blank\"\u003eAdafruit Feather ESP32 v2 with 8MB flash 2MB PSRAM plus w.FL connector\u003c/a\u003e and the external WiFi antenna, connected to a \u003ca href=\"https://www.adafruit.com/product/5964\" target=\"_blank\"\u003eSEN5x breakout board\u003c/a\u003e using a \u003ca href=\"https://www.adafruit.com/product/4399\" target=\"_blank\"\u003eStemmaQT cable\u003c/a\u003e, and the \u003ca href=\"https://www.digikey.com/en/products/detail/sensirion-ag/SEN54-SDN-T/15903868\" target=\"_blank\"\u003eSensirion SEN54 air quality sensor\u003c/a\u003e with it's \u003ca href=\"https://www.adafruit.com/product/5754\" target=\"_blank\"\u003eweird locking JST-GHR 6pin cable\u003c/a\u003e.\u0026nbsp; (Skip to the end to see the device in-situ)\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003ePlan of Attack:\u003c/h2\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eSo Saturday morning I was having a prod at the firmware (\u003ca href=\"https://github.com/adafruit/Adafruit_Wippersnapper_Arduino\" target=\"_blank\"\u003eyou can too as it's open source code\u003c/a\u003e) and watching the API calls in the network monitor to see where gets prodded when the user changes a sensor to read every 30s.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/190/original/Screenshot_2024-09-28_122816.png?1727524501","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eHere we can see the period being updated to 30seconds when I select that option in the Adafruit IO component dialog and click update component.\u003c/p\u003e\n\u003cp\u003eSo the idea now is to recreate that message to update the time period for the sensor, but with a new value of our choosing.\u003c/p\u003e\n\u003ch2\u003e📮Postman 📬📯\u003c/h2\u003e\n\u003cp\u003e\u0026nbsp;I've used \u003ca href=\"https://www.postman.com/\" target=\"_blank\"\u003epostman\u003c/a\u003e for API testing for a while now, it allows me some quick and useful templating and storing collections with reusable \"variables\".\u003c/p\u003e\n\u003cp\u003eSince starting this job I've built a collection of requests that use some of the more interesting bits of the IO API, and for this example I've ended up copying the request payload from my google chrome Developer tools window (the network panel shown in the image above) into my Postman collection.\u003c/p\u003e\n\u003cp\u003eThere I already have my authorisation key setup as an HTTP header (by following the \u003ca href=\"https://io.adafruit.com/api/docs/#including-an-adafruit-io-key\" target=\"_blank\"\u003eadafruit IO API docs\u003c/a\u003e), and I'm modifying the time period in the payload to a lower value of 5 seconds then sending the HTTP PUT request.\u003c/p\u003e\n\u003cp\u003eYou'll see the response from the API with the updated value:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/193/original/Screenshot_2024-09-28_125736.png?1727524682","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n        \u003cp\u003eNow as \u003ca href=\"https://www.postman.com/\" target=\"_blank\"\u003ePostman\u003c/a\u003e is so useful (and free for minimal use - teams of 3), \u003cstrong\u003eI've decided to include my collection here so you can easily import it into your own postman account\u003c/strong\u003e.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/tyeth/adafruit-io-postman-collection/blob/main/Adafruit%20HTTP%20API%20(update%20variables).postman_collection.json\" target=\"_blank\"\u003ehttps://github.com/tyeth/adafruit-io-postman-collection/blob/main/Adafruit%20HTTP%20API%20(update%20variables).postman_collection.json\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;I've created a new account called playground_example and included those details so you could immediately run one of the GET requests, but the key has been automatically reset due to publishing it online.\u003cbr\u003e\u003cspan style=\"text-decoration: underline;\"\u003ePlease instead update the variables to use your own account immediately.\u003c/span\u003e\u0026nbsp;\u003cspan style=\"text-decoration: underline;\"\u003e\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eSharing Accounts and giving out your key is a very bad idea, if that happens by accident you can regenerate a new key from the View Key dialog.\u003c/strong\u003e\u003c/p\u003e\n      \n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/201/original/ajZSw2O3C0.png?1727610615","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n        \u003cp\u003eIf your key is detected as published publicly online, then you'll receive an email saying it's been compromised and has been automatically regenerated. Something like this:\u0026nbsp;\u003c/p\u003e\n      \n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/202/original/Screenshot_2024-09-29_152404.png?1727619876","metadata":{"caption":""}},{"element_type":"text","content":"\n        \u003cp\u003eAfter importing the collection of requests in your Postman account, click on the collection name and goto the Variables tab of the collection window that opens.\u003c/p\u003e\n\u003cp\u003eUpdate your io_user and io_key variables (both the default and current_value entries).\u003c/p\u003e\n      ","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/200/original/VpULMju11J.png?1727610595","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eTesting the change:\u003c/h2\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eAfter rebooting the device it worked!\u003c/p\u003e\n\u003cp\u003eThe readings now come every 5seconds instead of every 30, as shown below in the serial monitor, and the adafruit IO feed page for the temperature sensor:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/192/original/Screenshot_2024-09-28_123718.png?1727524541","metadata":{"caption":""}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/196/original/Screenshot_2024-09-28_123957.png?1727525766","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eYou can see the sensor component interface on the wippersnapper device page now shows a blank entry for temperature sensor poll period, but still shows the 30seconds poll period for all the other sensors sub components:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/195/original/Screenshot_2024-09-28_130714.png?1727525313","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eThoughts, what's next, and an in-situ photo\u003c/h2\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThere's even more WipperSnapper pin information available from the Feeds API endpoint which I've had my eye on for a while... It's also possible to create and modify Dashboards via the API! Once I've got a bit more other stuff done I may revisit this topic.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eNow I just need to do it to the particle sensor sub-components instead as that's how I'll be detecting the toast beginning to burn (and then switch off the toaster).\u003c/p\u003e\n\u003cp\u003eThen setup a quick Action to trigger the power off once a burning toast event is detected and \u003cem\u003evoila...no more burnt toast!\u003c/em\u003e\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/197/original/kitchen_toast_monitor.jpg?1727526127","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThe only downside of my current setup is that I'm using those TP-Link Tapo P110 power monitoring wifi switches which don't have a friendly API supporting webhooks. I either need to run a python script on a raspberry pi (that I use for netflix) which would monitor a feed using MQTT and then run a \u003ca href=\"https://github.com/mihai-dinculescu/tapo\" target=\"_blank\"\u003epython+rust combo\u003c/a\u003e to interact with the Tapo plug, or alternatively pay IFTTT a monthly fee, or last option is to wire my toaster through a relay (I have a \u003ca href=\"https://www.adafruit.com/product/3191\" target=\"_blank\"\u003eHigh Power Relay featherwing supporting 1200Watts\u003c/a\u003e and my toaster is 700w so it's not insane - ignoring inrush and resistive load issues which derate it to about half).\u003c/p\u003e\n\u003cp\u003eI should probably just be running home assistant at this point, then I could more easily interact with the Tapo devices. So far I've been happy enough integrating my Tapo and eWeLink devices over google, plus the free tier of IFTTT, only occasionally reaching into a web dashboard or mobile app. I have to admit I'm also running a pi in the greenhouse with NodeRED (diagram flow based programming) for the odd automation and test.\u003c/p\u003e\n      \n\n\n\n\n\n","metadata":{}}]