{"id":22501,"date":"2025-02-28T11:03:58","date_gmt":"2025-02-28T10:03:58","guid":{"rendered":"http:\/\/blog.wenzlaff.de\/?p=22501"},"modified":"2025-03-22T15:38:59","modified_gmt":"2025-03-22T14:38:59","slug":"esp32-wetterdaten-wie-temperatur-luftfeuchte-luftdruck-und-kursdaten-von-btc-etc-sol-doge-nano-und-duino-mit-user-wallet-anzeigen","status":"publish","type":"post","link":"http:\/\/blog.wenzlaff.de\/?p=22501","title":{"rendered":"ESP32: Wetterdaten wie Temperatur, Luftfeuchte, Luftdruck und Kursdaten von BTC, ETC,  SOL, DOGE, NANO  und DUINO mit User-Wallet anzeigen"},"content":{"rendered":"<p>Vor 8 Jahren hatte ich schon mal \u00fcber das <a href=\"http:\/\/blog.wenzlaff.de\/?p=8277\" target=\"_blank\">OLED Display \u201eDon\u2019t give up!<\/a> berichtet. Und w\u00e4hrend der Pandemie diente es als <a href=\"http:\/\/blog.wenzlaff.de\/?p=15458\" target=\"_blank\">CO2 Anzeige<\/a>. Das habe ich nun abgebaut und durch ein paar Abfragen per REST-Api von OpenWeatherMap und Coingecko umprogrammiert. Das Ergebnis sieht man in diesem Video: <\/p>\n<div style=\"width: 525px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-22501-1\" width=\"525\" height=\"295\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2025\/02\/esp32-anzeig.mp4?_=1\" \/><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2025\/02\/esp32-anzeig.mp4\">http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2025\/02\/esp32-anzeig.mp4<\/a><\/video><\/div>\n<p>Es werden mit dem ESP32: Wetterdaten wie Temperatur, Luftfeuchte, Luftdruck und Kursdaten von BTC, ETC, SOL, DOGE, NANO mit DUINO User-Wallet angezeigt. Das Programm sieht ungef\u00e4hr so aus: <!--more--><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2025\/02\/wenzlaff.de-2025-02-28-um-10.43.50.png\" alt=\"\" width=\"914\" height=\"2146\" class=\"aligncenter size-full wp-image-22504\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2025\/02\/wenzlaff.de-2025-02-28-um-10.43.50.png 914w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2025\/02\/wenzlaff.de-2025-02-28-um-10.43.50-128x300.png 128w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2025\/02\/wenzlaff.de-2025-02-28-um-10.43.50-436x1024.png 436w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2025\/02\/wenzlaff.de-2025-02-28-um-10.43.50-768x1803.png 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2025\/02\/wenzlaff.de-2025-02-28-um-10.43.50-654x1536.png 654w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2025\/02\/wenzlaff.de-2025-02-28-um-10.43.50-872x2048.png 872w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Der Code f\u00fcr das Flow-Diagramm sieht so aus:<\/p>\n<pre class=\"theme:dark-terminal minimize:true lang:default decode:true \" >flowchart TD\r\n    A([Start]) --&gt; B[Initialisierung]\r\n    B --&gt; C[WiFi verbinden]\r\n    C --&gt; D[NTP-Zeit synchronisieren]\r\n    D --&gt; E{Hauptschleife loop}\r\n    E --&gt; F[Lokale Zeit abrufen]\r\n    F --&gt; G{Zeit zwischen 0:00 und 5:00?}\r\n    G --&gt;|Ja| H[Display ausschalten]\r\n    G --&gt;|Nein| I{Update-Intervall erreicht?}\r\n    I --&gt;|Ja| J[Preise abrufen]\r\n    J --&gt; K[LED einschalten]\r\n    K --&gt; L[HTTP-Anfrage senden]\r\n    L --&gt; M[JSON parsen und Preise speichern]\r\n    M --&gt; N[LED ausschalten]\r\n    N --&gt; O{Display-Intervall erreicht?}\r\n    I --&gt;|Nein| O\r\n    O --&gt;|Ja| P[Preise anzeigen]\r\n    O --&gt;|Nein| Q[1 Sekunde warten]\r\n    P --&gt; Q\r\n    Q --&gt; E\r\n    H --&gt; Q<\/pre>\n<p>Hier der Code, der auch in aktueller Version in meinem <a href=\"https:\/\/gitlab.com\/IT-Berater\/twesp32\" target=\"_blank\">GitLab Repo<\/a> zu finden ist.<\/p>\n<pre class=\"lang:c++ decode:true \" >\r\n\r\n\/\/\r\n\/\/ Kurs Abfrage jede 15. Minuten und Anzeigen wechsl alle 3 Sekunden auf SSD1306 Display.\r\n\/\/ Nachts von 0 -6 Uhr keine Anzeige und Abfragen\r\n\/\/\r\n\/\/ Details siehe http:\/\/blog.wenzlaff.de\/\r\n\/\/\r\n\/\/ Thomas Wenzlaff \r\n\/\/\r\n#include &lt;Wire.h&gt;\r\n#include &lt;Adafruit_GFX.h&gt;\r\n#include &lt;Adafruit_SSD1306.h&gt;\r\n#include &lt;WiFi.h&gt;\r\n#include &lt;HTTPClient.h&gt;\r\n#include &lt;ArduinoJson.h&gt;\r\n#include &lt;time.h&gt;\r\n\/\/ Passwort Datei f\u00fcr das WLAN, mit eigenen Daten anpassen und erstellen,\r\n\/\/ einfach die credentials.h.templates renamen nach credentials.h und  den WLAN Namen und Passwort eintragen.\r\n\/\/ Die Datei sieht so aus:\r\n\/\/ #ifndef CREDENTIALS_H\r\n\/\/ #define CREDENTIALS_H\r\n\/\/ Anpassen auf die eigenen WLAN-Daten\r\n\/\/ #define SSID \"WLAN-Name\"\r\n\/\/ #define PASSWORT \"WLAN-Passwort\"\r\n\/\/\r\n\/\/ https:\/\/api.openweathermap.org\r\n\/\/ #define OPENWEATHERMAP_API_KEY \"Api Key\"\r\n\/\/ #define ORTS_KEY \"Orts Key z.B. Langenhagen 2881062\"\r\n\/\/ Duino User Name\r\n\/\/ #define DUINO_USER_NAME \"kleinhirn\"\r\n\/\/ #endif\r\n\r\n#include \"credentials.h\"\r\n\r\n\/\/ Oder anpassen auf die eigenen WLAN-Daten aus credentials.h oder hier setzen und einkommentieren\r\n\/\/ const char*  SSID = \"WLAN Name\"\r\n\/\/ const char*  PASSWORT = WLAN Passwort\r\n\r\n#define SCREEN_WIDTH 128\r\n#define SCREEN_HEIGHT 64\r\n#define OLED_RESET -1\r\n#define SCREEN_ADDRESS 0x3C\r\n#define UPDATE_INTERVAL 60 * 15 * 1000 \/\/ 15 minute\r\n#define DISPLAY_INTERVAL 3 * 1000 \/\/ 3 seconds\r\n#define BLUE_LED_PIN 2\r\n\r\nenum CryptoIndex {\r\n  BITCOIN,\r\n  ETHEREUM,\r\n  SOLANA,\r\n  NANO,\r\n  DOGECOIN,\r\n  DUINO_USER,\r\n  WETTER_TEMPERATUR,\r\n  WETTER_LUFTDRUCK,\r\n  WETTER_FEUCHTE,\r\n  NUM_CRYPTOS \/\/ muss als letztes stehen\r\n};\r\n\r\nconst char* const cryptoIds[NUM_CRYPTOS] = {\r\n  \"bitcoin\",\r\n  \"ethereum\",\r\n  \"solana\",\r\n  \"nano\",\r\n  \"dogecoin\",\r\n  \"balance\", \/\/ https:\/\/server.duinocoin.com\/users\/kleinhirn in result\/balance\/balance\r\n  \"main\", \/\/ Temperatur von https:\/\/api.openweathermap.org\r\n  \"main\", \/\/ Luftdruck von https:\/\/api.openweathermap.org\r\n  \"main\" \/\/ Feuchte von https:\/\/api.openweathermap.org\r\n};\r\n\r\nconst char* const cryptoNames[NUM_CRYPTOS] PROGMEM = {\r\n  \"Bitcoin\",\r\n  \"Ethereum\",\r\n  \"Solana\",\r\n  \"Nano\",\r\n  \"Dogecoin\",\r\n  \"DUINO Wallet\", \/\/ eigener Wert vom User Wallet\r\n  \"Temperatur\",\r\n  \"Luftdruck\",\r\n  \"Feuchte\"\r\n};\r\n\r\nconst char* const urls[NUM_CRYPTOS] = {\r\n  \"https:\/\/api.coingecko.com\/api\/v3\/simple\/price?ids=bitcoin&amp;vs_currencies=eur\", \/\/ \"Data provided by CoinGecko\"\r\n  \"https:\/\/api.coingecko.com\/api\/v3\/simple\/price?ids=ethereum&amp;vs_currencies=eur\",\r\n  \"https:\/\/api.coingecko.com\/api\/v3\/simple\/price?ids=solana&amp;vs_currencies=eur\",\r\n  \"https:\/\/api.coingecko.com\/api\/v3\/simple\/price?ids=nano&amp;vs_currencies=eur\",\r\n  \"https:\/\/api.coingecko.com\/api\/v3\/simple\/price?ids=dogecoin&amp;vs_currencies=eur\",\r\n  \"https:\/\/server.duinocoin.com\/users\/\" DUINO_USER_NAME ,\r\n  \"https:\/\/api.openweathermap.org\/data\/2.5\/weather?id=\"  ORTS_KEY  \"&amp;appid=\"  OPENWEATHERMAP_API_KEY   \"&amp;units=metric\", \/\/ Temperatur \r\n  \"https:\/\/api.openweathermap.org\/data\/2.5\/weather?id=\"  ORTS_KEY  \"&amp;appid=\"  OPENWEATHERMAP_API_KEY   \"&amp;units=metric\", \/\/ Luftdruck \r\n  \"https:\/\/api.openweathermap.org\/data\/2.5\/weather?id=\"  ORTS_KEY  \"&amp;appid=\"  OPENWEATHERMAP_API_KEY   \"&amp;units=metric\"  \/\/ Feuchte \r\n};\r\n\r\nfloat prices[NUM_CRYPTOS] = {0.0};\r\nunsigned long lastUpdate = 0;\r\nunsigned long lastDisplay = 0;\r\nCryptoIndex currentIndex = BITCOIN;\r\n\r\n\/\/ NTP-Server und Zeitzone definieren\r\n\/\/  \"CET-1CEST,M3.5.0\/2,M10.5.0\/3\":\r\n\/\/   CET-1: Mitteleurop\u00e4ische Zeit (UTC+1).\r\n\/\/        CEST: Mitteleurop\u00e4ische Sommerzeit.\r\n\/\/             M3.5.0\/2: Beginn der Sommerzeit am letzten Sonntag im M\u00e4rz um 2 Uhr.\r\n\/\/                      M10.5.0\/3: Ende der Sommerzeit am letzten Sonntag im Oktober um 3 Uhr.\r\n\r\nconst char* ntpServer = \"de.pool.ntp.org\";\r\nconst char* timeZone = \"CET-1CEST,M3.5.0\/2,M10.5.0\/3\"; \/\/ Mitteleurop\u00e4ische Zeit (Berlin)\r\n\r\nAdafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &amp;Wire, OLED_RESET);\r\n\r\nvoid setup() {\r\n  \/\/ setup l\u00e4uft nur einmal\r\n  Serial.begin(115200);\r\n  Wire.begin();\r\n\r\n  \/\/ Display ini\r\n  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {\r\n    Serial.println(F(\"SSD1306 allocation failed\"));\r\n    for (;;)\r\n      ;\r\n  }\r\n\r\n  display.setTextColor(WHITE);\r\n  WiFi.begin(SSID, PASSWORT);\r\n\r\n  display.clearDisplay();\r\n  display.setTextSize(1);\r\n  display.setCursor(4, 25);\r\n  display.print(\"Verbinde ...\");\r\n  display.display();\r\n\r\n  while (WiFi.status() != WL_CONNECTED) {\r\n    delay(500);\r\n  }\r\n  pinMode(BLUE_LED_PIN, OUTPUT);\r\n\r\n  \/\/ Zeitzone und NTP-Server konfigurieren\r\n  configTzTime(timeZone, ntpServer);\r\n  printLocalTime();\r\n  \r\n  lastUpdate = millis() - UPDATE_INTERVAL;  \/\/ Sofortige Initialisierung\r\n  lastDisplay = millis() - DISPLAY_INTERVAL;\r\n\r\n   \/\/ Beim ersten Start direkt Daten abrufen\r\n  fetchPrices();\r\n}\r\n\r\nvoid displayPrice(float price, const char* currency, CryptoIndex currentCrypto) {\r\n  display.clearDisplay();\r\n  display.setTextSize(2);\r\n  display.setCursor(4, 4);\r\n  display.print(currency);\r\n\r\n  display.setCursor(4, 25);\r\n\r\n  \/\/ \u00dcberpr\u00fcfe die aktuelle Kryptow\u00e4hrung und passe die Dezimalstellen und TextSize an\r\n  if (currentCrypto == DUINO_USER || currentCrypto == DOGECOIN) {\r\n    display.setTextSize(2);\r\n    display.print(price, 6);  \/\/ Zeigt den Preis mit 6 Dezimalstellen an\r\n  } else if (currentCrypto == NANO) {\r\n    display.setTextSize(2);\r\n    display.print(price, 6);  \/\/ Zeigt den Preis mit 6 Dezimalstellen an\r\n  } else if (currentCrypto == BITCOIN) {\r\n    display.setTextSize(4);\r\n    display.print(price, 0);  \/\/ Zeigt den Preis ohne Dezimalstellen an\r\n  } else if (currentCrypto == ETHEREUM || currentCrypto == WETTER_LUFTDRUCK || currentCrypto == WETTER_FEUCHTE) {\r\n    display.setTextSize(4);\r\n    display.print(price, 0);\r\n  } else if (currentCrypto == SOLANA) {\r\n    display.setTextSize(4);\r\n    display.print(price, 1);\r\n  } else {\r\n    display.setTextSize(4);\r\n    display.print(price, 2);  \/\/ Standardm\u00e4\u00dfig mit 2 Dezimalstellen\r\n  }\r\n\r\n  display.display();  \/\/ Aktualisiere die Anzeige\r\n}\r\n\r\nvoid displayError(const char* error) {\r\n  display.clearDisplay();\r\n  display.setTextSize(1);\r\n  display.setCursor(4, 25);\r\n  display.print(error);\r\n  display.display();\r\n}\r\n\r\nvoid fetchPrices() {\r\n  if (WiFi.status() == WL_CONNECTED) {\r\n    digitalWrite(BLUE_LED_PIN, HIGH);\r\n    for (int i = 0; i &lt; NUM_CRYPTOS; i++) {\r\n      HTTPClient http;\r\n      http.begin(urls[i]);\r\n      int httpResponseCode = http.GET();\r\n      if (httpResponseCode &gt; 0) {\r\n\r\n        String payload = http.getString();\r\n        DynamicJsonDocument doc(3072);  \/\/ Falls notwendig, anpassen (z. B. 3072 oder 4096)\r\n        DeserializationError error = deserializeJson(doc, payload);\r\n\r\n        \/\/ \u00dcberpr\u00fcfen, ob die Deserialisierung erfolgreich war\r\n        if (error) {\r\n          Serial.print(F(\"deserializeJson() fehlgeschlagen: \"));\r\n          Serial.println(error.c_str());  \/\/ Gibt die genaue Fehlermeldung aus\r\n        }\r\n\r\n        if (!error) {\r\n          if (i == DUINO_USER) {\r\n            if (doc[\"result\"][\"balance\"][\"balance\"].isNull()) {\r\n              Serial.println(F(\"Fehler: Erwarteter JSON-Pfad 'result.balance.balance' fehlt.\"));\r\n            } else {\r\n              prices[i] = doc[\"result\"][\"balance\"][\"balance\"].as&lt;float&gt;();\r\n            }\r\n          } else if (i == WETTER_TEMPERATUR) {\r\n            if (doc[\"main\"][\"temp\"].isNull()) {\r\n              Serial.println(F(\"Fehler: Erwarteter JSON-Pfad 'main.temp' fehlt.\"));\r\n            } else {\r\n              prices[i] = doc[\"main\"][\"temp\"].as&lt;float&gt;();\r\n            }\r\n          } else if (i == WETTER_LUFTDRUCK) {\r\n            if (doc[\"main\"][\"pressure\"].isNull()) {\r\n              Serial.println(F(\"Fehler: Erwarteter JSON-Pfad 'main.pressure' fehlt.\"));\r\n            } else {\r\n              prices[i] = doc[\"main\"][\"pressure\"].as&lt;float&gt;();\r\n            }\r\n          } else if (i == WETTER_FEUCHTE) {\r\n            if (doc[\"main\"][\"humidity\"].isNull()) {\r\n              Serial.println(F(\"Fehler: Erwarteter JSON-Pfad 'main.humidity' fehlt.\"));\r\n            } else {\r\n              prices[i] = doc[\"main\"][\"humidity\"].as&lt;float&gt;();\r\n            }\r\n          } else {\r\n            if (doc[cryptoIds[i]][\"eur\"].isNull()) {\r\n              Serial.print(F(\"Fehler: Erwarteter JSON-Pfad '\"));\r\n              Serial.print(cryptoIds[i]);\r\n              Serial.println(F(\".eur' fehlt.\"));\r\n            } else {\r\n              prices[i] = doc[cryptoIds[i]][\"eur\"];\r\n            }\r\n          }\r\n        }\r\n      }\r\n      http.end();\r\n    }\r\n    lastUpdate = millis();\r\n    digitalWrite(BLUE_LED_PIN, LOW);\r\n  }\r\n}\r\n\r\nvoid loop() {\r\n  unsigned long currentMillis = millis();\r\n  time_t now;\r\n  struct tm timeinfo;\r\n\r\n  if (!getLocalTime(&amp;timeinfo)) {\r\n    Serial.println(\"Failed to obtain time\");\r\n    return;\r\n  }\r\n\r\n  if (timeinfo.tm_hour &gt;= 0 &amp;&amp; timeinfo.tm_hour &lt; 6) {\r\n    Serial.println(\"Anzeige in bis morgens aus ...\");\r\n    display.ssd1306_command(SSD1306_DISPLAYOFF);\r\n  } else {\r\n    display.ssd1306_command(SSD1306_DISPLAYON);\r\n\r\n    if (currentMillis - lastUpdate &gt;= UPDATE_INTERVAL) {\r\n      Serial.println(\"Daten aktualisieren...\");\r\n      fetchPrices();\r\n    }\r\n\r\n    if (currentMillis - lastDisplay &gt;= DISPLAY_INTERVAL) {\r\n      \/\/Serial.println(\"Anzeige aktualisieren...\");\r\n      displayPrice(prices[currentIndex], cryptoNames[currentIndex], static_cast&lt;CryptoIndex&gt;(currentIndex));\r\n      currentIndex = static_cast&lt;CryptoIndex&gt;((currentIndex + 1) % NUM_CRYPTOS);\r\n      lastDisplay = currentMillis;\r\n    }\r\n  }\r\n\r\n  delay(1000);\r\n}\r\n\r\nvoid printLocalTime() {\r\n  struct tm timeinfo;\r\n  if (!getLocalTime(&amp;timeinfo)) {\r\n    Serial.println(\"Fehler: Zeit konnte nicht abgerufen werden\");\r\n    return;\r\n  }\r\n  Serial.println(&amp;timeinfo, \"%A, %d %B %Y %H:%M:%S\");\r\n}<\/pre>\n<p><small>Video Musik: &#8222;Sappheiros &#8211; Embrace&#8220; is under a Creative Commons (BY 3.0) license: https:\/\/creativecommons.org\/licenses\/&#8230; https:\/\/open.spotify.com\/artist\/5ZVHX&#8230; Music powered by BreakingCopyright: \u00a0Chill\u00a0Instrumental\u00a0[Non\u00a0Copyrighted<\/small><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Vor 8 Jahren hatte ich schon mal \u00fcber das OLED Display \u201eDon\u2019t give up! berichtet. Und w\u00e4hrend der Pandemie diente es als CO2 Anzeige. Das habe ich nun abgebaut und durch ein paar Abfragen per REST-Api von OpenWeatherMap und Coingecko umprogrammiert. Das Ergebnis sieht man in diesem Video: Es werden mit dem ESP32: Wetterdaten wie &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/blog.wenzlaff.de\/?p=22501\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eESP32: Wetterdaten wie Temperatur, Luftfeuchte, Luftdruck und Kursdaten von BTC, ETC,  SOL, DOGE, NANO  und DUINO mit User-Wallet anzeigen\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[220,5036,5027,2874,3107,4606,6109,5393,5037,6130,79,3632],"tags":[2857,2188,1183,4611,2741,6144,6145,6096,3020,2136,629,167,595,853],"class_list":["post-22501","post","type-post","status-publish","format-standard","hentry","category-anleitung","category-bitcoin","category-blockchain","category-c","category-c-programmierung","category-crypto","category-duco-coin","category-esp32-cam","category-ethereum","category-nano","category-programmierung","category-video","tag-anzeige","tag-arduino","tag-bitcoin","tag-btc","tag-c","tag-crpypto","tag-duno","tag-esp-32","tag-esp32","tag-feuchte","tag-luftdruck","tag-programmieren","tag-temperatur","tag-wetter"],"_links":{"self":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/22501","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=22501"}],"version-history":[{"count":0,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/22501\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=22501"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=22501"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=22501"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}