{"id":196,"date":"2018-12-29T11:52:07","date_gmt":"2018-12-29T09:52:07","guid":{"rendered":"https:\/\/dev.drun.net\/?p=196"},"modified":"2018-12-29T11:52:07","modified_gmt":"2018-12-29T09:52:07","slug":"home-automation-with-docker-and-domoticz","status":"publish","type":"post","link":"https:\/\/dev.krasi.net\/?p=196","title":{"rendered":"Home automation with Docker and Domoticz"},"content":{"rendered":"\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/dev.krasi.net\/wp-content\/uploads\/2018\/12\/Screenshot-2018-12-29-at-9.27.51-1-1024x377.png\" alt=\"\" class=\"wp-image-199\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Intro<\/h3>\n\n\n\n<p>I&#8217;ve decided it&#8217;s about time to finish my Domoticz setup and connect all my devices to it. I just did it and this post is about the setup.<\/p>\n\n\n\n<p>I currently have several <a href=\"\/2018\/05\/21\/measuring-temperature-humidity-pressure-esp8266\/\">sensor boards with ESP8266 that I made<\/a> for measuring mostly the temperature and also several <a href=\"https:\/\/github.com\/xoseperez\/espurna\">ESPurna<\/a>&#8211; based Sonoff switches ( controlling boilers, water pumps, and heating ), which I wanted to connect in one app and have an overview, control from mobile, etc.<\/p>\n\n\n\n<p>I have an all-time running server at home, which I decided to use for that purpose. You can, of course, use any connected machine (or virtual server) you like. However, if you need to connect Z-Wave USB adapters, real hardware is needed. You can go with Raspberry PI too (that was my initial setup), however, I found that it&#8217;s a bit cumbersome to set up and support. Docker setup is much easier.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Docker<\/h3>\n\n\n\n<p>Okay, so I&#8217;m assuming you have a running Docker on Linux. If you don&#8217;t, please install it ( there are numerous tutorials on that ) and continue.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Traefik<\/h3>\n\n\n\n<p>Okay, that&#8217;s not mandatory at all, but I&#8217;ve used <g class=\"gr_ gr_4 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del multiReplace\" id=\"4\" data-gr-id=\"4\">Traefik<\/g> to redirect port 80 to 443 and forward real domains directly to docker images (of course, make sure your router redirects ports to the machine chosen). The certificates  generated automatically with LetsEncrypt.<\/p>\n\n\n\n<p>My configuration for running Traefik ( in Docker, of course) is like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run --name=traefik --restart=unless-stopped -d -p 80:80 \\\n    -p 8081:8080 \\\n    -p 443:443 \\\n    -l traefik.enable=true -l traefik.backend=traefik \\\n    -l traefik.frontend.rule=Host:traefik.example.net \\\n    -l traefik.port=8080 \\\n    -v \/opt\/traefik\/traefik.toml:\/traefik.toml \\\n    -v \/opt\/traefik\/acme.json:\/acme.json \\\n    -v \/var\/run\/docker.sock:\/var\/run\/docker.sock \\\n    traefik<\/code><\/pre>\n\n\n\n<p>traefik.toml looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>debug = false\n\ndefaultEntryPoints = [\"https\",\"http\"]\n\n[entryPoints]\n    [entryPoints.http]\n    address = \":80\"\n    [entryPoints.http.redirect]\n    entryPoint = \"https\"\n    [entryPoints.https]\n    address = \":443\"\n    [entryPoints.https.tls]\n\n[retry]\n\n[docker]\n    endpoint = \"unix:\/\/\/var\/run\/docker.sock\"\n    domain = \"traefik.example.net\"\n    watch = true\n    exposedbydefault = false\n\n[acme]\n    email = \"youremail@example.net\"\n    storage = \"acme.json\"\n    entryPoint = \"https\"\n    OnHostRule = true\n    [acme.httpChallenge]\n    entryPoint = \"http\"\n\n[web]\n    [web.auth.basic]\n    users = [\"admin:ENCODEDPASSHERE\"]\n\naddress = \":8080\"<\/code><\/pre>\n\n\n\n<p>Of course, you have to replace example.net entries with your domain and if you want to protect it with a password (I strongly <g class=\"gr_ gr_7 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling\" id=\"7\" data-gr-id=\"7\">advice<\/g> so), you can <a href=\"https:\/\/docs.traefik.io\/configuration\/backends\/web\/#basic-authentication\">generate your ENCODEDPASSHERE with htpasswd<\/a> (accepts MD5, SHA1, and BCrypt are supported).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Domoticz<\/h3>\n\n\n\n<p>I&#8217;ve used <a href=\"https:\/\/hub.docker.com\/r\/linuxserver\/domoticz\/\">Linuxserver&#8217;s Domoticz<\/a> image. The script for starting is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run -d --name=domoticz \\\n    --net=bridge \\\n    --restart=unless-stopped \\\n    -v \/opt\/domoticz:\/config \\\n    -e PGID=1001 -e PUID=1000 \\\n    -e TZ=Europe\/Sofia \\\n    -p 21443:1443 \\\n    -p 26144:6144 \\\n    -p 28080:8080 \\\n    --device=\/dev\/ttyACM0 \\\n    -l traefik.enable=true -l traefik.backend=domoticz \\\n    -l traefik.frontend.rule=Host:domoticz.example.net \\\n    -l traefik.port=8080 \\\n    linuxserver\/domoticz\n\ndocker exec domoticz apk update\ndocker exec domoticz apk add mosquitto-clients<\/code><\/pre>\n\n\n\n<p>The <strong>&#8211;device=\/dev\/ttyACM0<\/strong> row is optional and is used with USB Z-Wave dongle I have, so that Domoticz can see it. Omit, if you will never use it.<\/p>\n\n\n\n<p>The last two commands I use to add MQTT clients package, which I use in LUA scripting (further below). Also, by using Traefik labels, I&#8217;m making sure that Domoticz is visible on <strong>https<\/strong>:\/\/domoticz.example.net (or whatever your domain is).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">MQTT<\/h3>\n\n\n\n<p>First, prepare two files ( my location is in \/opt\/mqtt\/config , but yours might differ).<\/p>\n\n\n\n<p>mosquitto.conf with this content:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>password_file \/mqtt\/config\/passwd\nallow_anonymous false<\/code><\/pre>\n\n\n\n<p>and passwd file can be created like this (make sure you have <em>mosquitto<\/em> package (on Ubuntu it&#8217;s installed like <em>sudo apt install mosquitto<\/em>) :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mosquitto_passwd -c \/opt\/mqtt\/config\/passwd domoticz<\/code><\/pre>\n\n\n\n<p>Install MQTT in Docker with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run --name mqtt -d --restart=unless-stopped \\\n  -p 1884:1884 \\\n  -v \/opt\/mqtt\/config:\/mqtt\/config:ro \\\n  -v \/opt\/mqtt\/log:\/mqtt\/log \\\n  -v \/opt\/mqtt\/data\/:\/mqtt\/data\/ \\\n  toke\/mosquitto<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">MQTT in Domoticz setup<\/h3>\n\n\n\n<p>In Domoticz web interface, go to <strong>Settings<\/strong> -> <strong>Hardware<\/strong> and add new device of type <strong>MQTT Client Gateway with LAN interface<\/strong>:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/dev.krasi.net\/wp-content\/uploads\/2018\/12\/Screenshot-2018-12-29-at-11.03.43-1024x803.png\" alt=\"\" class=\"wp-image-226\"\/><\/figure>\n\n\n\n<p>Of course, enter the IP address of your machine and the username + password you&#8217;ve used.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">OpenSenseMap<\/h3>\n\n\n\n<p>For adding <a href=\"https:\/\/opensensemap.org\/\">public OSM sensors<\/a> in Domoticz, I&#8217;ve chosen to use <em>lua<\/em> scripting.<\/p>\n\n\n\n<p>In \/opt\/domoticz\/scripts\/<g class=\"gr_ gr_7 gr-alert gr_spell gr_inline_cards gr_disable_anim_appear ContextualSpelling ins-del multiReplace\" id=\"7\" data-gr-id=\"7\">lua<\/g>, create <strong>FUNCTIONS.lua<\/strong> with this content<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nfunction timestampToTime(ts)\n\n    local pattern = \"(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+).(%d+)Z\"\n    local runyear, runmonth, runday, runhour, runminute, runseconds, runmillisec = ts:match(pattern)\n\n    local d = os.time({year = runyear, month = runmonth, day = runday, hour = runhour, min = runminute, sec = runseconds})\n    return d\nend\n\nfunction timeGMT()\n    local dt = os.date('!*t')\n\n    if os.date(\"*t\").isdst then\n\treturn os.time(dt) - 3600\n    else\n\treturn os.time(dt)\n    end\nend\n\nfunction reqUpdate(idx)\n    os.execute(\"(sleep 2 &amp;&amp; mosquitto_pub -h mqtt.example.net -p 1884 -t 'domoticz\/in' -u domoticz -P MYPASSWORD -m '{\\\"command\\\": \\\"getdeviceinfo\\\", \\\"idx\\\": \"..idx..\" }') &amp;\")\nend\n<\/code><\/pre>\n\n\n\n<p>and <strong>JSON.lua<\/strong> with <a href=\"https:\/\/dev.drun.net\/wp-content\/uploads\/2018\/12\/JSON.lua\">this content<\/a>. There are two functions in there, which we will use later and JSON decoding\/encoding functions ( you might already have that ).<\/p>\n\n\n\n<p>In <em>Domoticz<\/em> web interface, go to <strong>Setup<\/strong> -> <strong>Hardware<\/strong> and create a new device that is <strong>Dummy (Does nothing, use for virtual switches only)<\/strong>. Name it however you like and save it.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/dev.krasi.net\/wp-content\/uploads\/2018\/12\/Screenshot-2018-12-29-at-10.10.39-1024x449.png\" alt=\"\" class=\"wp-image-216\"\/><\/figure>\n\n\n\n<p>When added to your list, tap on <strong>Create virtual sensors<\/strong> , name it, and select <strong>Temperature<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/dev.krasi.net\/wp-content\/uploads\/2018\/12\/Screenshot-2018-12-29-at-10.12.32-1024x625.png\" alt=\"\" class=\"wp-image-217\"\/><\/figure>\n\n\n\n<p>You can repeat the same for Humidity, Pressure, etc.<\/p>\n\n\n\n<p>Go to <strong>Setup<\/strong> -> <strong>Devices<\/strong>. Remember the idx of the sensors added. We will use them in another <em>Lua<\/em> script.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/dev.krasi.net\/wp-content\/uploads\/2018\/12\/Screenshot-2018-12-29-at-10.16.46-150x150.png\" alt=\"\" class=\"wp-image-219\"\/><\/figure>\n\n\n\n<p>For convinience, I&#8217;m adding the script here. <strong>Make\u00a0sure\u00a0it&#8217;s\u00a0name\u00a0starts\u00a0with\u00a0script_time_<\/strong> (e.g. script_time_sensor_1.lua), so that it&#8217;s executed every minute.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>commandArray = {}\n\njson = (loadfile \"\/config\/scripts\/lua\/JSON.lua\")()\n\nindexArray = 0\n\n-- make sure these match the ids for added virtual sensors\nidxTemp1 = 9\nidxHumidity1 = 10\nidxPressure1 = 11\n\n-- sensor 1\nlocal config=assert(io.popen('curl https:\/\/api.opensensemap.org\/boxes\/5ad4e2fb223bd800193bec4e\/sensors' ))\nlocal location = config:read('*all')\nconfig:close()\nlocal jsonLocation = json:decode(location)\n\nloadfile \"\/config\/scripts\/lua\/FUNCTIONS.lua\"()\nlocal d = timestampToTime(jsonLocation.sensors[1].lastMeasurement.createdAt)\nlocal now = timeGMT()\n\n-- if it wasn't updated, skip it.\nif (d &lt; now - 119) then\n    print(\"Skipping Sensor 1...\")\n    return commandArray\nend\n\ntemp1 = jsonLocation.sensors[1].lastMeasurement.value\npressure1 = jsonLocation.sensors[2].lastMeasurement.value\nhumidity1 = jsonLocation.sensors[3].lastMeasurement.value\n\nprint('Temperature Sensor 1: '..temp1)\nprint('Pressure Sensor 1: '..pressure1)\nprint('Humidity Sensor 1: '..humidity1)\n\ncommandArray[0] = {['UpdateDevice'] = tostring(idxTemp1)..'|0|'..tostring(temp1)}\ncommandArray[1] = {['UpdateDevice'] = tostring(idxHumidity1)..'|'..tostring(humidity1)..'|0'}\ncommandArray[2] = {['UpdateDevice'] = tostring(idxPressure1)..'|0|'..tostring(pressure1)}\n\n-- enable this if you want to update the MQTT server. If not, you can safely skip it.\n-- reqUpdate(idxTemp1)\n-- reqUpdate(idxHumidity1)\n-- reqUpdate(idxPressure1)\n\nreturn commandArray<\/code><\/pre>\n\n\n\n<p>Make sure to replace the ID of the sensebox with yours or the one you want to use.<\/p>\n\n\n\n<p>I&#8217;m also bit lazy here &#8211; I&#8217;m not properly parsing it, so if you don&#8217;t have humidity or pressure, or your ordering in the <g class=\"gr_ gr_41 gr-alert gr_spell gr_inline_cards gr_disable_anim_appear ContextualSpelling\" id=\"41\" data-gr-id=\"41\">json<\/g> file is not the same &#8211; please fine tune it. You can also add print statements and they will show in Domoticz log.<\/p>\n\n\n\n<p>Also, <strong>if you want to enable MQTT posting\u00a0of\u00a0data<\/strong>, you can configure your server location in <em>FUNCTIONS.lua<\/em> and enable <em>reqUpdate()<\/em> rows in the example script above.<\/p>\n\n\n\n<p>If you completed all steps properly, you will see the added temperature reading in <strong>Domoticz<\/strong> &#8211; <strong>Temperature<\/strong> tab.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/dev.krasi.net\/wp-content\/uploads\/2018\/12\/Screenshot-2018-12-29-at-11.10.01-300x108.png\" alt=\"\" class=\"wp-image-228\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">ESPurna<\/h3>\n\n\n\n<p>Let&#8217;s connect a Sonoff switch with ESPurna firmware to Domoticz. That&#8217;s very easy to do, once we have MQTT and are running on recent ESPurna firmware.<\/p>\n\n\n\n<p>First, go to <strong>Domoticz<\/strong> web -> <strong>Setup<\/strong> -> <strong>Hardware<\/strong> and add new Dummy device:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/dev.krasi.net\/wp-content\/uploads\/2018\/12\/Screenshot-2018-12-29-at-11.27.57-1024x237.png\" alt=\"\" class=\"wp-image-233\"\/><\/figure>\n\n\n\n<p>Tap on <strong>Create Virtual Sensors<\/strong> on the newly created row and add type <strong>Switch<\/strong>:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/dev.krasi.net\/wp-content\/uploads\/2018\/12\/Screenshot-2018-12-29-at-11.29.16.png\" alt=\"\" class=\"wp-image-234\"\/><\/figure>\n\n\n\n<p>You can further customize the look of the switch by going to <strong>Switches<\/strong> tab and clicking on <strong>Edit<\/strong> button and customizing it:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/dev.krasi.net\/wp-content\/uploads\/2018\/12\/Screenshot-2018-12-29-at-11.30.21-1024x588.png\" alt=\"\" class=\"wp-image-235\"\/><\/figure>\n\n\n\n<p>Note the idx #, you will need it later.<\/p>\n\n\n\n<p>In ESPurna&#8217;s web interface, configure the MQTT server. Note that if your switch is outside your network, it has to be accessible.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/dev.krasi.net\/wp-content\/uploads\/2018\/12\/Screenshot-2018-12-29-at-11.13.22-1024x727.png\" alt=\"\" class=\"wp-image-230\"\/><\/figure>\n\n\n\n<p>Save it and then go to <strong>DOMOTICZ<\/strong> tab. Enable it, the defaults should be okay. Make sure to change the Switch #0 (or whatever entries you have &#8211; some devices have more) to the <g class=\"gr_ gr_128 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del multiReplace\" id=\"128\" data-gr-id=\"128\">idx<\/g> of the virtual switch you&#8217;ve added:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/dev.krasi.net\/wp-content\/uploads\/2018\/12\/Screenshot-2018-12-29-at-11.14.21-1024x660.png\" alt=\"\" class=\"wp-image-231\"\/><\/figure>\n\n\n\n<p>Save again and go to <strong>DEBUG<\/strong> section. Observe the connection to MQTT is successful and if it&#8217;s not, you have to double check your configuration.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Z-Wave<\/h3>\n\n\n\n<p>While Z-Wave devices are not cheap and you need an USB adapter, they can also be attached if you have any.<\/p>\n\n\n\n<p>Go to Domoticz web -> <strong>Setup<\/strong> -> <strong>Hardware<\/strong> and add <strong>OpenZWave USB<\/strong> device:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/dev.krasi.net\/wp-content\/uploads\/2018\/12\/Screenshot-2018-12-29-at-11.39.57-1024x282.png\" alt=\"\" class=\"wp-image-245\"\/><figcaption>Mine is Aeotec ZW090 Z-Stick Gen5<\/figcaption><\/figure>\n\n\n\n<p>Click on <strong>Setup<\/strong> and configure it. <a href=\"https:\/\/www.vesternet.com\/resources\/application-notes\/apnt-85#.U_4xlxYU58E\">Here&#8217;s actually <g class=\"gr_ gr_81 gr-alert gr_gramm gr_inline_cards gr_disable_anim_appear Grammar only-ins replaceWithoutSep\" id=\"81\" data-gr-id=\"81\">pretty<\/g> decent and detailed tutorial<\/a> on how to configure it ( skip the first few blocks ). Because I&#8217;m lazy \ud83d\ude42<\/p>\n\n\n\n<p>Once You&#8217;re done, you should be able to see all your added devices and monitor whatever they provide ( I have an Aeotec ZW100 MultiSensor 6 device and this shows several &#8220;switch&#8221;-es and readings ). However, I&#8217;m not really interested in anything besides the light reading and temperature + humidity:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.krasi.net\/wp-content\/uploads\/2018\/12\/Screenshot-2018-12-29-at-11.48.49.png\" alt=\"\" class=\"wp-image-248\" width=\"400\" height=\"140\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/dev.krasi.net\/wp-content\/uploads\/2018\/12\/Screenshot-2018-12-29-at-11.49.58.png\" alt=\"\" class=\"wp-image-249\"\/><\/figure>\n\n\n\n<p>Domoticz also have apps for both iOS and Android. However, they are pretty ugly (sorry, but that&#8217;s true) and I prefer using the web page.<\/p>\n\n\n\n<p>I hope you enjoyed this tutorial. I will be adding more info very soon, related to Domoticz and automation.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Intro I&#8217;ve decided it&#8217;s about time to finish my Domoticz setup and connect all my devices to it. I just did it and this post is about the setup. I currently have several sensor boards with ESP8266 that I made for measuring mostly the temperature and also several ESPurna&#8211; based Sonoff switches ( controlling boilers, water pumps, and heating ), which I wanted to connect in one app and have an overview, control from mobile, etc. I have an all-time running server at home, which I decided to use for that purpose. You can, of course, use any connected machine (or virtual server) you like. However, if you need to connect Z-Wave USB adapters, real hardware is needed. You can go with Raspberry PI too (that was my initial setup), however, I found that it&#8217;s a bit cumbersome to set up and support. Docker setup is much easier. Docker Okay, so I&#8217;m assuming you have a running Docker on Linux. If you don&#8217;t, please install it ( there are numerous tutorials on that ) and continue. Traefik Okay, that&#8217;s not mandatory at all, but I&#8217;ve used Traefik to redirect port 80 to 443 and forward real domains directly to docker [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":198,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-196","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software"],"_links":{"self":[{"href":"https:\/\/dev.krasi.net\/index.php?rest_route=\/wp\/v2\/posts\/196","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dev.krasi.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.krasi.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.krasi.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.krasi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=196"}],"version-history":[{"count":0,"href":"https:\/\/dev.krasi.net\/index.php?rest_route=\/wp\/v2\/posts\/196\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dev.krasi.net\/index.php?rest_route=\/"}],"wp:attachment":[{"href":"https:\/\/dev.krasi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=196"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.krasi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=196"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.krasi.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}