{"id":254,"date":"2025-09-18T13:46:39","date_gmt":"2025-09-18T20:46:39","guid":{"rendered":"https:\/\/www.blueeyetiger.com\/?p=254"},"modified":"2025-11-19T11:15:20","modified_gmt":"2025-11-19T19:15:20","slug":"pico-ota","status":"publish","type":"post","link":"https:\/\/www.blueeyetiger.com\/?p=254","title":{"rendered":"Pico OTAUpdate"},"content":{"rendered":"\n<p>In building a Raspberry Pi Pico W project that has a web interface and is deployed remotely running on a battery that is charged by solar power, it became more than a hassle to update the code on the Pico. This typically involved connecting my laptop to the device using a USB cable.<\/p>\n\n\n\n<p>There has to be a better way.<\/p>\n\n\n\n<p>Enter OTAUpdate.  Over The Air Updating.<\/p>\n\n\n\n<p>I started with this tutorial: (https:\/\/www.pythontutorials.net\/blog\/micropython-ota\/) , but added a reasonable amount including expanding the versions.json file to include individual entries for each module (or other file) on your pico.  ota_update.py and check_versions.py are pulled from that tutorial and modified.<\/p>\n\n\n\n<p>I found that some developers use Github to store their code and &#8220;git&#8221; the code to the Pico. (https:\/\/github.com\/rdehuyss\/micropython-ota-updater\/blob\/master\/app\/ota_updater.py). This works and may be a good solution for a production product, although there are significant downsides to using Github or even a private git server. The first downside to using Github is that you store your code on a public repository. A deal killer for proprietary projects. The second downside is this is not very useful for rapid development. GitHub updates can sometimes take many minutes. Not friendly to rapid development and testing. <\/p>\n\n\n\n<p>You can deploy your own private git server and push and pull data from it. However, most full featured git servers have a lot of overhead. I tested gitlab as a VM and it ran out of memory just running with no access with 4GB of RAM (3GB Physical + 1GB swap) and there was a constant background CPU usage doing who knows what. gitlab reconfigure can take 2 minutes. A lot of overhead for a simple operation. <\/p>\n\n\n\n<p>A simple nginx web server on a basic linux install can run on less than 100MB of RAM and takes literally zero CPU until you make a request. I am running mine on 512MB VM running Debian 13.<\/p>\n\n\n\n<p>In the future I will look at using a bare bones cli git server.  But this OTA solution uses any web server.<\/p>\n\n\n\n<p>This is config.py.  Some developers use a json file to store their contents, but I have found that using a .py module makes referencing the constants from any other module very simple.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nPORT=80\nWIFI_SSID=&#039;SSID&#039;\nWIFI_PASSWORD=&#039;PWD&#039;\nFLASH_MS=250\n# Check version this many milliseconds (for test - 15 seconds,  for production every hour? or every day?)\nVERSION_MS=15000\n# Web site base URL\nBASE_URL=&quot;http:\/\/192.168.0.123\/blink\/&quot;\n# Versions file stored at BASE_URL\nVERSIONS_FILE=&quot;versions.json&quot;\n\n<\/pre><\/div>\n\n\n<p>The second module is check_version.py.  This is the module that does the comparison of the versions currently installed with the version on the web server.  ota_update is a module called by check_version.py when an update is required.  <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport urequests\nimport json\nimport config\nimport os\nimport machine\nfrom ota_update import ota_update\n\ndef check_versions():\n    try:\n        response = urequests.get(config.BASE_URL + config.VERSIONS_FILE)\n        if response.status_code == 200:\n            versions_remote = json.loads(response.text)\n    except Exception as e:\n        print(&quot;Error:&quot;, e)\n\n    directory = &quot;\/&quot;\n    jsonfile = &quot;versions.json&quot;\n    jsonpath = directory + jsonfile\n    # Open and read the JSON file\n    try:\n        # Open the file for read only\n        with open(jsonpath, &#039;r&#039;) as file:\n            # Read the json data into dictionary named versions\n            versions_local = json.load(file)\n    except:\n        # If the local file does not exist, write out a copy of the remote file minus 1\n        # so that all files are freshly downloaded.\n        versions_local = {}\n        with open(jsonpath, &quot;w&quot;) as file:\n            file.write(json.dumps(versions_remote))\n            file.close\n        for files in versions_remote:\n            versions_local&#x5B;files] = versions_remote&#x5B;files] - 1\n    \n    # Start with the assumption there are no changes\n    changes = False\n    for file in versions_remote:\n        if versions_remote&#x5B;file] &gt; versions_local&#x5B;file]:\n            # ota_update returns 0 if the file updated successfully\n            if ota_update(config.BASE_URL, file) == 0:\n                # If even one file changes, we will reboot, but after all files are checked\/updated\n                changes = True\n\n    # Write out to the local file a copy of the remote versions file\n    with open(jsonpath, &quot;w&quot;) as file:\n        file.write(json.dumps(versions_remote))\n        file.close\n    \n    if changes:\n        machine.reset()\n<\/pre><\/div>\n\n\n<p>This is oat_update.py, called by check_versions if a file is not the latest version.  It downloads the file to temp.tmp and then renames it over the old version.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n# ota_uptate(BASE_URL, FILENAME)\nimport urequests\nimport os\nimport machine\n\ndef ota_update(BASE_URL, FILE):\n    try:\n        response = urequests.get(BASE_URL + FILE)\n        if response.status_code == 200:\n            try:\n                with open(&#039;temp.tmp&#039;, &#039;w&#039;) as f:\n                    f.write(response.text)\n                response.close()\n                os.rename(&#039;temp.tmp&#039;, FILE)\n                return 0\n            except OSError as e:\n                return e\n        else:\n            return response.status_code\n    except Exception as e:\n        print(&quot;OTA update error:&quot;, e)\n        return e\n<\/pre><\/div>\n\n\n<p>This is the main.py file.  It does some time set up and calls connect_wlan to initiate the wireless network.  Then it loops indefinitely.  Every config.VERSION_MS it runs the check_versions(), which grabs the versions.json file from the server and then updates any modules that have a new version than the one on this pico.  <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nfrom time import sleep_ms, ticks_ms, ticks_diff, time\nimport ntptime\nfrom flash import flash\nfrom check_versions import check_versions\nimport config\nfrom connect_wlan import connect_wlan\n\n\ndef main():\n    boot_time = time()\n    flash_ms = ticks_ms()\n    version_ms = ticks_ms()\n    wlan = connect_wlan()\n    while True:\n        sleep_ms(10)\n        flash_ms = flash(flash_ms)\n\n        if ticks_diff(ticks_ms(), version_ms) &gt; config.VERSION_MS:\n            check_versions()\n            version_ms = ticks_ms()\n\n        now = time()\n        if (now % 3600 == 0 or now == boot_time + 10):\n            try:\n                ntptime.settime()\n            except:\n                print(&quot;Failed to get ntptime, will try again in 10 seconds&quot;)\n                boot_time = now\n\n\nmain()\n<\/pre><\/div>\n\n\n<p>Here is connect_wlan.py<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport network\nimport socket\nimport time\nimport machine\nimport config\n\ndef connect_wlan():\n# Initialize the Wireless LAN\n    wlan = network.WLAN(network.STA_IF)\n    wlan.active(False)\n    wlan.disconnect()\n   \n    wlan.active(True)\n    wlan.connect(config.WIFI_SSID, config.WIFI_PASSWORD)\n\n    max_wait = 10\n    while max_wait &gt; 0:\n        if wlan.status() &amp;lt; 0 or wlan.status() &gt;= 3:\n            break\n        max_wait -= 1\n        print(&#039;waiting for connection...&#039;)\n        time.sleep(1)\n\n    if wlan.status() != 3:\n        print(&quot;Failed setting up wifi, will restart in 10 seconds&quot;)\n        time.sleep(10)\n        machine.reset()\n    \n    print(&#039;connected to wifi:&#039;, config.WIFI_SSID, &#039;with ip = &#039;, wlan.ifconfig()&#x5B;0])\n    return wlan\n<\/pre><\/div>\n\n\n<p>Finally, here is blink.py, a simple routine that blinks the LED on the pico by toggling the Pin state whenever called.  main.py calls this and the frequency is set in the config file.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nfrom machine import Pin\nfrom time import ticks_ms\nfrom time import ticks_diff\nimport config\n\ndef flash(flash_ms):\n    pin = Pin(&quot;LED&quot;, Pin.OUT)\n    if ticks_diff(ticks_ms(), flash_ms) &gt; config.FLASH_MS:\n        pin.toggle()\n        flash_ms = ticks_ms()\n    return flash_ms\n<\/pre><\/div>\n\n\n<p>This provides a very easy way to test the Over The Air. Just change the config.FLASH_MS and wait less than config.VERSION_MS milliseconds and it should grab the new config.py and reboot and the blink rate would speed up or slow down based on your change.<\/p>\n\n\n\n<p>!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In building a Raspberry Pi Pico W project that has a web interface and is deployed remotely running on a battery that is charged by solar power, it became more than a hassle to update the code on the Pico. This typically involved connecting my laptop to the device using a USB cable. There has [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-254","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Pico OTAUpdate - blueeyetiger.com<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.blueeyetiger.com\/?p=254\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Pico OTAUpdate - blueeyetiger.com\" \/>\n<meta property=\"og:description\" content=\"In building a Raspberry Pi Pico W project that has a web interface and is deployed remotely running on a battery that is charged by solar power, it became more than a hassle to update the code on the Pico. This typically involved connecting my laptop to the device using a USB cable. There has [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.blueeyetiger.com\/?p=254\" \/>\n<meta property=\"og:site_name\" content=\"blueeyetiger.com\" \/>\n<meta property=\"article:published_time\" content=\"2025-09-18T20:46:39+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-19T19:15:20+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.blueeyetiger.com\/wp-content\/uploads\/2024\/06\/2dfb82d5f7046217.png\" \/>\n\t<meta property=\"og:image:width\" content=\"512\" \/>\n\t<meta property=\"og:image:height\" content=\"512\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"bob\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"bob\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/?p=254#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/?p=254\"},\"author\":{\"name\":\"bob\",\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/#\\\/schema\\\/person\\\/98ff2f5d06600ab5de6b741c3d1f36ae\"},\"headline\":\"Pico OTAUpdate\",\"datePublished\":\"2025-09-18T20:46:39+00:00\",\"dateModified\":\"2025-11-19T19:15:20+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/?p=254\"},\"wordCount\":611,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/#organization\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.blueeyetiger.com\\\/?p=254#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/?p=254\",\"url\":\"https:\\\/\\\/www.blueeyetiger.com\\\/?p=254\",\"name\":\"Pico OTAUpdate - blueeyetiger.com\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/#website\"},\"datePublished\":\"2025-09-18T20:46:39+00:00\",\"dateModified\":\"2025-11-19T19:15:20+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/?p=254#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.blueeyetiger.com\\\/?p=254\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/?p=254#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.blueeyetiger.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Pico OTAUpdate\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/#website\",\"url\":\"https:\\\/\\\/www.blueeyetiger.com\\\/\",\"name\":\"blueeyetiger.com\",\"description\":\"Create, Backup, Monitor\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.blueeyetiger.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/#organization\",\"name\":\"blueeyetiger.com\",\"alternateName\":\"Blue Eye Tiger\",\"url\":\"https:\\\/\\\/www.blueeyetiger.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.blueeyetiger.com\\\/wp-content\\\/uploads\\\/2024\\\/06\\\/2dfb82d5f7046217.png\",\"contentUrl\":\"https:\\\/\\\/www.blueeyetiger.com\\\/wp-content\\\/uploads\\\/2024\\\/06\\\/2dfb82d5f7046217.png\",\"width\":512,\"height\":512,\"caption\":\"blueeyetiger.com\"},\"image\":{\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.blueeyetiger.com\\\/#\\\/schema\\\/person\\\/98ff2f5d06600ab5de6b741c3d1f36ae\",\"name\":\"bob\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c8c86a59c3373bdc11b8762ef34739774bcc9cb55e23544f39b3a5a8fa58510b?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c8c86a59c3373bdc11b8762ef34739774bcc9cb55e23544f39b3a5a8fa58510b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c8c86a59c3373bdc11b8762ef34739774bcc9cb55e23544f39b3a5a8fa58510b?s=96&d=mm&r=g\",\"caption\":\"bob\"},\"sameAs\":[\"http:\\\/\\\/docker.bobhild.com:8011\"],\"url\":\"https:\\\/\\\/www.blueeyetiger.com\\\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Pico OTAUpdate - blueeyetiger.com","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.blueeyetiger.com\/?p=254","og_locale":"en_US","og_type":"article","og_title":"Pico OTAUpdate - blueeyetiger.com","og_description":"In building a Raspberry Pi Pico W project that has a web interface and is deployed remotely running on a battery that is charged by solar power, it became more than a hassle to update the code on the Pico. This typically involved connecting my laptop to the device using a USB cable. There has [&hellip;]","og_url":"https:\/\/www.blueeyetiger.com\/?p=254","og_site_name":"blueeyetiger.com","article_published_time":"2025-09-18T20:46:39+00:00","article_modified_time":"2025-11-19T19:15:20+00:00","og_image":[{"width":512,"height":512,"url":"https:\/\/www.blueeyetiger.com\/wp-content\/uploads\/2024\/06\/2dfb82d5f7046217.png","type":"image\/png"}],"author":"bob","twitter_card":"summary_large_image","twitter_misc":{"Written by":"bob","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.blueeyetiger.com\/?p=254#article","isPartOf":{"@id":"https:\/\/www.blueeyetiger.com\/?p=254"},"author":{"name":"bob","@id":"https:\/\/www.blueeyetiger.com\/#\/schema\/person\/98ff2f5d06600ab5de6b741c3d1f36ae"},"headline":"Pico OTAUpdate","datePublished":"2025-09-18T20:46:39+00:00","dateModified":"2025-11-19T19:15:20+00:00","mainEntityOfPage":{"@id":"https:\/\/www.blueeyetiger.com\/?p=254"},"wordCount":611,"commentCount":0,"publisher":{"@id":"https:\/\/www.blueeyetiger.com\/#organization"},"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.blueeyetiger.com\/?p=254#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.blueeyetiger.com\/?p=254","url":"https:\/\/www.blueeyetiger.com\/?p=254","name":"Pico OTAUpdate - blueeyetiger.com","isPartOf":{"@id":"https:\/\/www.blueeyetiger.com\/#website"},"datePublished":"2025-09-18T20:46:39+00:00","dateModified":"2025-11-19T19:15:20+00:00","breadcrumb":{"@id":"https:\/\/www.blueeyetiger.com\/?p=254#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.blueeyetiger.com\/?p=254"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.blueeyetiger.com\/?p=254#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.blueeyetiger.com\/"},{"@type":"ListItem","position":2,"name":"Pico OTAUpdate"}]},{"@type":"WebSite","@id":"https:\/\/www.blueeyetiger.com\/#website","url":"https:\/\/www.blueeyetiger.com\/","name":"blueeyetiger.com","description":"Create, Backup, Monitor","publisher":{"@id":"https:\/\/www.blueeyetiger.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.blueeyetiger.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.blueeyetiger.com\/#organization","name":"blueeyetiger.com","alternateName":"Blue Eye Tiger","url":"https:\/\/www.blueeyetiger.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.blueeyetiger.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.blueeyetiger.com\/wp-content\/uploads\/2024\/06\/2dfb82d5f7046217.png","contentUrl":"https:\/\/www.blueeyetiger.com\/wp-content\/uploads\/2024\/06\/2dfb82d5f7046217.png","width":512,"height":512,"caption":"blueeyetiger.com"},"image":{"@id":"https:\/\/www.blueeyetiger.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.blueeyetiger.com\/#\/schema\/person\/98ff2f5d06600ab5de6b741c3d1f36ae","name":"bob","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/c8c86a59c3373bdc11b8762ef34739774bcc9cb55e23544f39b3a5a8fa58510b?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/c8c86a59c3373bdc11b8762ef34739774bcc9cb55e23544f39b3a5a8fa58510b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c8c86a59c3373bdc11b8762ef34739774bcc9cb55e23544f39b3a5a8fa58510b?s=96&d=mm&r=g","caption":"bob"},"sameAs":["http:\/\/docker.bobhild.com:8011"],"url":"https:\/\/www.blueeyetiger.com\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/www.blueeyetiger.com\/index.php?rest_route=\/wp\/v2\/posts\/254","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.blueeyetiger.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blueeyetiger.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blueeyetiger.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blueeyetiger.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=254"}],"version-history":[{"count":9,"href":"https:\/\/www.blueeyetiger.com\/index.php?rest_route=\/wp\/v2\/posts\/254\/revisions"}],"predecessor-version":[{"id":271,"href":"https:\/\/www.blueeyetiger.com\/index.php?rest_route=\/wp\/v2\/posts\/254\/revisions\/271"}],"wp:attachment":[{"href":"https:\/\/www.blueeyetiger.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=254"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blueeyetiger.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=254"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blueeyetiger.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=254"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}