{"id":1397,"date":"2022-01-29T00:30:32","date_gmt":"2022-01-29T06:30:32","guid":{"rendered":"https:\/\/lab.rapternet.us\/?p=1397"},"modified":"2025-03-18T21:33:04","modified_gmt":"2025-03-19T02:33:04","slug":"espdeck-home-assistant-macro-pad","status":"publish","type":"post","link":"https:\/\/lab.rapternet.us\/?p=1397","title":{"rendered":"EspDeck: Home Assistant Macro Pad"},"content":{"rendered":"\n<p>After seeing some posts with EspHome and Zigbee keypads, I realized I wanted to make one too. I wanted the ability to easily trigger more complex actions in home assistant that I don&#8217;t have an easy way to fully automate. I decided to make the <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/AeroSteveO\/EspDeck\" target=\"_blank\">EspDeck <\/a>project to provide construction and technical details on building one of these macro pads. EspDeck provides a 9 key macro pad supporting single, double, and hold click actions on every key and can be integrated with home assistant easily through the ESPHome integration or add-on.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Related Articles<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/lab.rapternet.us\/?p=1397\">EspDeck Version 1<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/lab.rapternet.us\/?p=1506\">EspDeck Version 2<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/lab.rapternet.us\/?p=2811\">EspDeck Version 3<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/lab.rapternet.us\/?p=4239\">EspDeck Version 3 + LED Backlighting<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/lab.rapternet.us\/?p=1616\">EspDeck Automations<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/lab.rapternet.us\/?p=3514\">EspDeck + NFC: The NFC Deck<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/lab.rapternet.us\/?p=3737\">NfcDeck Backlit Key Notification<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"hardware\">Hardware<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>9 x <a href=\"https:\/\/amzn.to\/3E18yDD\">mechanical keyboard switches<\/a><\/li>\n\n\n\n<li>9 x key caps<\/li>\n\n\n\n<li>1 x <a href=\"https:\/\/amzn.to\/4ak8sTD\">ESP8266<\/a><\/li>\n\n\n\n<li>9 x 10k Ohm Resistors<\/li>\n\n\n\n<li>1 x Circuit Protoboard<\/li>\n\n\n\n<li>Some 3d Printing Filament or another material for a case<\/li>\n\n\n\n<li>Hot Glue (we&#8217;re professionals around here)<\/li>\n<\/ul>\n\n\n\n<p>I have been planning on buying a mechanical keyboard for a while now, so I decided to get some key switch sample packs to see which type of key switch I like the most, and then make a few EspDecks, with the samples. This is where I got the set of 9 key switches and caps, though larger packs of key switches are more efficient on price. I will make use of the included key caps until I get around to customizing the key caps for each key function. <\/p>\n\n\n\n<p>I still had the ESP8266 boards from my WLED shenanigans, so all I had to pick up were some resistors and protoboards for that end of things.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"dev-environment\">Dev Environment<\/h2>\n\n\n\n<p>I had never used ESPHome before, so I had to start out by setting up my dev environment. I installed home assistant on a VM, so passing around USB devices can get to be a bit difficult (rebooting the VM to pick up new USB devices passed through). So instead, I decided to pull out an old laptop and install Pop!_OS to use as my base. Installing the OS had one minor snag (the installer failed on some final steps, but the install was fine to run), but still gave me a working physical linux machine. Once it was ready, it was time to start installing what we need.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo apt-get install python3 python3-pip<br>pip install wheels<br>pip install esphome<\/pre>\n\n\n\n<p>Next up I needed to include ESPHome in my PATH variable (and my .bashrc file to keep the setting around after reboot).  This will let me call the application without navigating to its binary on the filesystem. This is relatively easy to do and is included at the end of the ESPHome installer as a final manual step.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">stephen@pop-os:~$ export PATH=$PATH:$HOME\/.local\/bin<br>stephen@pop-os:~$ esphome version<br>Version: 2022.1.2<br>stephen@pop-os:~$ nano .bashrc <\/pre>\n\n\n\n<p>Since I will be working on USB devices, I needed to update the groups on my user account as well. My user account needed the <strong>tty<\/strong> and <strong>dialout<\/strong> groups added to it in order to use ESPHome to write the firmware to the ESP devices.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">stephen@pop-os:~$ groups\nstephen adm sudo lpadmin\nstephen@pop-os:~$ compgen -g\nroot\ndaemon\nbin\nsys\nadm\n<strong>tty<\/strong>\ndisk\nlp\nmail\nnews\nuucp\nman\nproxy\nkmem\n<strong>dialout<\/strong>\n.............\nstephen\nsystemd-coredump\nstephen@pop-os:~$ sudo usermod -a -G tty stephen\nstephen@pop-os:~$ sudo usermod -a -G dialout stephen<\/pre>\n\n\n\n<p>With my user account in the tty and dialout groups, I&#8217;ll now be able to run ESPHome and write my firmware to the ESP8266 devices. In order for this to fully take effect, you need to log out and log back into the system.<\/p>\n\n\n\n<p>Time to take care of the first run wizard with ESPHome. In this wizard, we give it our Wi-Fi SSID, password, board details, and other information.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">stephen@pop-os:~$ esphome\nusage: esphome [-h] [-v] [-q] [-s key value] command ...\nesphome: error: the following arguments are required: command\nstephen@pop-os:~$ esphome wizard keypad.yaml\nHi there!\nI'm the wizard of ESPHome :)\nAnd I'm here to help you get started with ESPHome.\nIn 4 steps I'm going to guide you through creating a basic configuration file for your custom ESP8266\/ESP32 firmware. Yay!\n\n\n\n============= STEP 1 =============\n    _____ ____  _____  ______\n   \/ ____\/ __ \\|  __ \\|  ____|\n  | |   | |  | | |__) | |__\n  | |   | |  | |  _  \/|  __|\n  | |___| |__| | | \\ \\| |____\n   \\_____\\____\/|_|  \\_\\______|\n\n===================================\nFirst up, please choose a name for your node.\nIt should be a unique name that can be used to identify the device later.\nFor example, I like calling the node in my living room livingroom.\n\n(name): keypad1 \nGreat! Your node is now called \"keypad1\".\n\n\n============= STEP 2 =============\n      ______  _____ _____\n     |  ____|\/ ____|  __ \\\\\n     | |__  | (___ | |__) |\n     |  __|  \\___ \\|  ___\/\n     | |____ ____) | |\n     |______|_____\/|_|\n\n===================================\nNow I'd like to know what microcontroller you're using so that I can compile firmwares for it.\nAre you using an ESP32 or ESP8266 platform? (Choose ESP8266 for Sonoff devices)\n\nPlease enter either ESP32 or ESP8266.\n(ESP32\/ESP8266): ESP8266\nThanks! You've chosen ESP8266 as your platform.\n\nNext, I need to know what board you're using.\nPlease go to http:\/\/docs.platformio.org\/en\/latest\/platforms\/espressif8266.html#boards and choose a board.\n\nFor example \"nodemcuv2\".\nOptions: d1, d1_mini, d1_mini_lite, d1_mini_pro, esp01, esp01_1m, esp07, esp12e, esp210, esp8285, esp_wroom_02, espduino, espectro, espino, espinotee, espmxdevkit, espresso_lite_v1, espresso_lite_v2, gen4iod, heltec_wifi_kit_8, huzzah, inventone, modwifi, nodemcu, nodemcuv2, oak, phoenix_v1, phoenix_v2, sonoff_basic, sonoff_s20, sonoff_sv, sonoff_th, sparkfunBlynk, thing, thingdev, wifi_slot, wifiduino, wifinfo, wio_link, wio_node, xinabox_cw01\n(board): esp12e\nWay to go! You've chosen esp12e as your board.\n\n\n\n============= STEP 3 =============\n   __          ___ ______ _\n   \\ \\        \/ (_)  ____(_)\n    \\ \\  \/\\  \/ \/ _| |__   _\n     \\ \\\/  \\\/ \/ | |  __| | |\n      \\  \/\\  \/  | | |    | |\n       \\\/  \\\/   |_|_|    |_|\n\n===================================\nIn this step, I'm going to create the configuration for WiFi.\n\nFirst, what's the SSID (the name) of the WiFi network keypad1 should connect to?\nFor example \"Abraham Linksys\".\n(ssid): my-wifi-ssid\nThank you very much! You've just chosen \"my-wifi-ssid\" as your SSID.\n\nNow please state the password of the WiFi network so that I can connect to it (Leave empty for no password)\n\nFor example \"PASSWORD42\"\n(PSK): **************\nPerfect! WiFi is now set up (you can create static IPs and so on later).\n\n\n============= STEP 4 =============\n       ____ _______\n      \/ __ \\__   __|\/\\\\\n     | |  | | | |  \/  \\\\\n     | |  | | | | \/ \/\\ \\\\\n     | |__| | | |\/ ____ \\\\\n      \\____\/  |_\/_\/    \\_\\\\\n\n===================================\nAlmost there! ESPHome can automatically upload custom firmwares over WiFi (over the air) and integrates into Home Assistant with a native API.\nThis can be insecure if you do not trust the WiFi network. Do you want to set a password for connecting to this ESP?\n\nPress ENTER for no password\n(password): \n\nDONE! I've now written a new configuration file to keypad.yaml\n\nNext steps:\n  &gt; Follow the rest of the getting started guide:\n  &gt; https:\/\/esphome.io\/guides\/getting_started_command_line.html#adding-some-features\n  &gt; to learn how to customize ESPHome and install it to your device.<\/pre>\n\n\n\n<p>Once we have a yaml file ready to test, its one simple command to upload it to the ESP8266 and run it.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">stephen@pop-os:~$ esphome run keypad.yaml<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"wiring-1\">Wiring<\/h2>\n\n\n\n<p>To start out with, we need the pinout of the ESP8266 device thats being used. There are 9 digital input\/output pins on the device, which lines up exactly with our 9 keys (it lets us avoid a more complex row\/column input layout). I originally tried just configuring ESPHome with D0 as the pin number, this didn&#8217;t work, nor did GPIO0, since the GPIO pin numbers do not line up with any of the other pin type numbers on the board. I ended up using <a href=\"https:\/\/randomnerdtutorials.com\/esp8266-pinout-reference-gpios\/\">this pinout <\/a>(and shown below).<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/i2.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/05\/ESP8266-NodeMCU-kit-12-E-pinout-gpio-pin.png?resize=817%2C542&amp;quality=100&amp;strip=all&amp;ssl=1\" alt=\"ESP8266 12-E NodeMCU Kit pinout diagram gpios pins\" class=\"wp-image-84967\"\/><figcaption class=\"wp-element-caption\">This Pinout was Helpful to Reference as I hadn&#8217;t Noticed that D0 != GPIO0<\/figcaption><\/figure>\n\n\n\n<p>The circuit design is simple, each digital IO pin has a pull down resistor to ground, as well as a connection to the key switches. The other side of the switch goes to the 3.3V rail of the ESP8266. This gives the digital IO pins a base input of 0 when the switches are open, and an input of 1 when the switches are pressed.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"340\" height=\"360\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/circuit.png\" alt=\"\" class=\"wp-image-1409\" style=\"width:386px;height:409px\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/circuit.png 340w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/circuit-283x300.png 283w\" sizes=\"auto, (max-width: 340px) 100vw, 340px\" \/><figcaption class=\"wp-element-caption\">Basically this x3 so all 9 switches are hooked up<\/figcaption><\/figure>\n\n\n\n<p>I decided to use a breadboard to prototype out one key on the macro pad as an input into the ESP8266. I used this prototype to develop the configuration for ESPHome to handle the single\/double\/hold key presses and to route them to Home Assistant<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"1024\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220126_005544790-768x1024.jpg\" alt=\"\" class=\"wp-image-1420\" style=\"width:571px;height:761px\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220126_005544790-768x1024.jpg 768w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220126_005544790-225x300.jpg 225w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220126_005544790-1152x1536.jpg 1152w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220126_005544790-1536x2048.jpg 1536w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220126_005544790-scaled.jpg 1920w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">Breadboard Prototyping the Circuit<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"esphome-integration\">ESPHome Integration<\/h2>\n\n\n\n<p>Since I was handling my ESPHome development on a separate machine from Home Assitant (and the remote device support from ESPHome doesn&#8217;t support FireFox), I had to add my device to the ESPHome integration manually. I plan on trying the ESPHome Add-On later on, as well as adding my current keypad to the Add-On so I can use it for firmware updates. Until then, the process of manually adding ESPHome is simple in the integrations tab. It can be found in the list by searching for ESP and only needs one bit of information to add a device.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"718\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/image-7-1024x718.png\" alt=\"\" class=\"wp-image-1436\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/image-7-1024x718.png 1024w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/image-7-300x210.png 300w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/image-7-768x539.png 768w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/image-7.png 1219w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">Adding the ESPHome Integration<\/figcaption><\/figure>\n\n\n\n<p>Once ESPHome is added to the integrations, a new device can be added to it. The integration just needs the Host\/IP and the port. Since I didn&#8217;t manually change the ports in use on my device, I left it on the default.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"459\" height=\"340\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/image-8.png\" alt=\"\" class=\"wp-image-1437\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/image-8.png 459w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/image-8-300x222.png 300w\" sizes=\"auto, (max-width: 459px) 100vw, 459px\" \/><figcaption class=\"wp-element-caption\">ESPHome Integration Configuration<\/figcaption><\/figure>\n\n\n\n<p>Now with the device configured, the keypad sensors can be seen in their first iteration. I don&#8217;t yet have setup the double and click and hold actions. I also don&#8217;t have all the pull down resistors in place, so multiple keypad keys are showing as perpetually &#8220;ON&#8221;.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"681\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/image-5-1024x681.png\" alt=\"\" class=\"wp-image-1401\" style=\"width:674px;height:448px\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/image-5-1024x681.png 1024w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/image-5-300x200.png 300w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/image-5-768x511.png 768w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/image-5.png 1054w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">Initial Config with all the Keypad Keys Entered in the Config, one Resistor on Keypad 1<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"developing-the-configuration\">Developing the Configuration<\/h2>\n\n\n\n<p>I started out the configuration by simply getting things going with the GPIO pins marked out for each key. This was enough to be able to get the switches acting on the breadboard and continue working towards the full final configuration.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">esphome:\n  name: keypad1\n\nesp8266:\n  board: esp12e\n\n# Enable logging\nlogger:\n\n# Enable Home Assistant API\napi:\n  password: \"\"\n\nota:\n  password: \"\"\n\nwifi:\n  ssid: \"myreallygoodssid\"\n  password: \"myreallygoodpassword\"\n\n  # Enable fallback hotspot (captive portal) in case wifi connection fails\n  ap:\n    ssid: \"Keypad1 Fallback Hotspot\"\n    password: \"somethingcomplex\"\n\ncaptive_portal:\n\nbinary_sensor:\n  - platform: gpio\n    name: \"Keypad 1\"\n    pin: 16\n  - platform: gpio\n    name: \"Keypad 2\"\n    pin: 5\n  - platform: gpio\n    name: \"Keypad 3\"\n    pin: 4\n  - platform: gpio\n    name: \"Keypad 4\"\n    pin: 0\n  - platform: gpio\n    name: \"Keypad 5\"\n    pin: 2\n  - platform: gpio\n    name: \"Keypad 6\"\n    pin: 14\n  - platform: gpio\n    name: \"Keypad 7\"\n    pin: 12\n  - platform: gpio\n    name: \"Keypad 8\"\n    pin: 13\n  - platform: gpio\n    name: \"Keypad 9\"\n    pin: 15\n<\/pre>\n\n\n\n<p>Once I had that basic input working, I went to work on the more complex actions, starting with the click and hold.  I realized I needed to create some type of mockup sensor for the held state and the double click states since having just the basic button press sensor wasn&#8217;t enough. I used the template sensors as I couldn&#8217;t find another way to configure them without hardware attached, and they worked well.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">  - platform: template\n    name: \"Keypad 2 Held\"\n    id: key_2_held_state\n  - platform: template\n    name: \"Keypad 2 Double Click\"\n    id: key_2_double_click_state\n  - platform: template\n    name: \"Keypad 2 Click\"\n    id: key_2_click_state<\/pre>\n\n\n\n<p>Now that I have my template sensors, I can turn them on and off with lambdas to emulate clicking the button. I&#8217;ll start with the click and hold action, with the goal to require the button to be held for at least 1 second, then it turns on the key_2_held_state for 1 second before turning it off. You can also see some of my experimenting with the home assistant service and the binary sensor toggle. I realized the home assistant service wasn&#8217;t going to work the way I expected and removed it later on. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">    on_click:\n        min_length: 1s\n        then:\n          - logger.log: \"Key 2 Held\"\n          - homeassistant.service:\n              service: input_boolean.turn_on\n              data:\n                entity_id: input_boolean.Keypad_2_held\n          - binary_sensor.toggle: key_2_held_state\n          - delay: 1s\n          - binary_sensor.toggle: key_2_held_state\n          - lambda: !lambda |-\n              id(key_2_held_state).publish_state(true);<\/pre>\n\n\n\n<p>This didn&#8217;t quite work as expected since the binary_sensor toggle action didn&#8217;t work out. Instead I moved to all lambdas. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">    on_multi_click:\n      - timing:\n        - ON for at least 1s\n        then:\n          - logger.log: \"Key 2 MultiHeld\"\n          - lambda: !lambda |-\n              id(key_2_held_state).publish_state(true);\n          - delay: 1s\n          - lambda: !lambda |-\n              id(key_2_held_state).publish_state(false);<\/pre>\n\n\n\n<p>Once I had the right formula of lambdas and template sensors, I added in the double click and single click actions. I had finally reached the final key configuration. Each key has 3 states, held, click, and double click. I split out the click state from the raw sensor data to avoid reading the other states also as a single click. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">  - platform: template\n    name: \"Keypad 2 Held\"\n    id: key_2_held_state\n  - platform: template\n    name: \"Keypad 2 Double Click\"\n    id: key_2_double_click_state\n  - platform: template\n    name: \"Keypad 2 Click\"\n    id: key_2_click_state\n  - platform: gpio\n    name: \"Keypad 2\"\n    pin: 5\n    on_multi_click:\n      - timing:\n        - ON for at most 950ms\n        - OFF for at least 500ms\n        then:\n          - lambda: !lambda |-\n              id(key_2_click_state).publish_state(true);\n          - delay: 500ms\n          - lambda: !lambda |-\n              id(key_2_click_state).publish_state(false);\n      - timing:\n        - ON for at least 1s\n        then:\n          - logger.log: \"Key 2 MultiHeld\"\n          - lambda: !lambda |-\n              id(key_2_held_state).publish_state(true);\n          - delay: 1s\n          - lambda: !lambda |-\n              id(key_2_held_state).publish_state(false);\n    on_double_click:\n      min_length: 25ms\n      max_length: 350ms\n      then:\n        - logger.log: \"Key 2 Double Click\"\n        - lambda: !lambda |-\n              id(key_2_double_click_state).publish_state(true);\n        - delay: 1s\n        - lambda: !lambda |-\n              id(key_2_double_click_state).publish_state(false);\n<\/pre>\n\n\n\n<p>Now just duplicate that configuration 9 times (I&#8217;m no professional yaml creator, there is most certainly a better way to do this with less duplication) for the 9 keys.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-case\">The Case<\/h2>\n\n\n\n<p>I found two 9-key cases on Thingiverse to try out. I printed out one of each and inserted the key switches I had available. I ended up going with the denser design for the top of the unit. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220124_230104507-1024x768.jpg\" alt=\"\" class=\"wp-image-1422\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220124_230104507-1024x768.jpg 1024w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220124_230104507-300x225.jpg 300w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220124_230104507-768x576.jpg 768w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220124_230104507-1536x1152.jpg 1536w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220124_230104507-2048x1536.jpg 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">Comparison of 2 Cases I had Considered<\/figcaption><\/figure>\n\n\n\n<p>After getting far into the assembly of the unit, I did discover that the original case from Thingiverse was too shallow for my skill of electronics. I made a new version of the case that is deeper to avoid the problem, while a 3rd iteration of the case will be needed eventually.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220128_175348865-1024x768.jpg\" alt=\"\" class=\"wp-image-1416\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220128_175348865-1024x768.jpg 1024w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220128_175348865-300x225.jpg 300w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220128_175348865-768x576.jpg 768w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220128_175348865-1536x1152.jpg 1536w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220128_175348865-2048x1536.jpg 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">Oops, 1st Case Iteration is a Bit too Shallow for my Skills<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"assembly\">Assembly<\/h2>\n\n\n\n<p>I started assembly with the ESP8266 and the protoboard. I wanted to get the pull down resistors wired up first, followed by the cable that will attach all the keys to the ESP device. <\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" data-id=\"1421\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_021040217-1024x768.jpg\" alt=\"\" class=\"wp-image-1421\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_021040217-1024x768.jpg 1024w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_021040217-300x225.jpg 300w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_021040217-768x576.jpg 768w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_021040217-1536x1152.jpg 1536w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_021040217-2048x1536.jpg 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">Assembling on Protoboard<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"2560\" data-id=\"1419\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_025737720-scaled.jpg\" alt=\"\" class=\"wp-image-1419\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_025737720-scaled.jpg 1920w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_025737720-225x300.jpg 225w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_025737720-768x1024.jpg 768w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_025737720-1152x1536.jpg 1152w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_025737720-1536x2048.jpg 1536w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">Fully Assembled on Protoboard<\/figcaption><\/figure>\n<\/figure>\n\n\n\n<p>With the protoboard wired up and ready, we go over to the key side of the equation. We hot glue the key switches into the top plate and start wiring them up.<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" data-id=\"1457\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_184352469-1024x768.jpg\" alt=\"\" class=\"wp-image-1457\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_184352469-1024x768.jpg 1024w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_184352469-300x225.jpg 300w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_184352469-768x576.jpg 768w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_184352469-1536x1152.jpg 1536w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_184352469-2048x1536.jpg 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">Fully Hot Glued Key Switches<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1920\" data-id=\"1418\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_025753809-scaled.jpg\" alt=\"\" class=\"wp-image-1418\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_025753809-scaled.jpg 2560w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_025753809-300x225.jpg 300w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_025753809-1024x768.jpg 1024w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_025753809-768x576.jpg 768w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_025753809-1536x1152.jpg 1536w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220127_025753809-2048x1536.jpg 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">Starting to Wire<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1920\" data-id=\"1417\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220128_014829333-scaled.jpg\" alt=\"\" class=\"wp-image-1417\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220128_014829333-scaled.jpg 2560w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220128_014829333-300x225.jpg 300w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220128_014829333-1024x768.jpg 1024w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220128_014829333-768x576.jpg 768w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220128_014829333-1536x1152.jpg 1536w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220128_014829333-2048x1536.jpg 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">Fully Wired Key Switches<\/figcaption><\/figure>\n<\/figure>\n\n\n\n<p>Once everything is all wired up, I ran a few multi-meter checks to make sure that I didn&#8217;t short anything out, and followed that up with a quick power on and test. With that test, I found out that I had a problem&#8230;. key 4 was broken, it was stuck in a high state even with the pull down resistor.<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:100%\">\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1080\" height=\"1171\" data-id=\"1455\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/Screenshot_20220129-103727-e1643499285845.png\" alt=\"\" class=\"wp-image-1455\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/Screenshot_20220129-103727-e1643499285845.png 1080w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/Screenshot_20220129-103727-e1643499285845-277x300.png 277w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/Screenshot_20220129-103727-e1643499285845-944x1024.png 944w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/Screenshot_20220129-103727-e1643499285845-768x833.png 768w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">Key 4 Input Stuck &#8220;On&#8221;<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"2560\" data-id=\"1456\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_160049372-scaled.jpg\" alt=\"\" class=\"wp-image-1456\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_160049372-scaled.jpg 1920w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_160049372-225x300.jpg 225w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_160049372-768x1024.jpg 768w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_160049372-1152x1536.jpg 1152w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_160049372-1536x2048.jpg 1536w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">Circuit Board Not Fitting in the Case<\/figcaption><\/figure>\n<\/figure>\n<\/div>\n<\/div>\n<\/div><\/div>\n\n\n\n<p>So after some research, I found out that GPIO0 \/ Key 4 needs to be pulled down by the switch, rather than my current design of having the switches pull up the digital IO pins. This swap can be easily done for just key 4 on this first iteration, however moving all keys to this method would reduce the complexity of my circuit in general and make for a better design. I started by making the electrical changes first and checkout out the switch in home assistant to make sure it was working as expected.<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-4 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" data-id=\"1459\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_225534628-1024x768.jpg\" alt=\"\" class=\"wp-image-1459\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_225534628-1024x768.jpg 1024w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_225534628-300x225.jpg 300w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_225534628-768x576.jpg 768w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_225534628-1536x1152.jpg 1536w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_225534628-2048x1536.jpg 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">Key 4 Rebuilt to use the Pull-Down on Key Press<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1920\" data-id=\"1460\" src=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_225517779-scaled.jpg\" alt=\"\" class=\"wp-image-1460\" srcset=\"https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_225517779-scaled.jpg 2560w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_225517779-300x225.jpg 300w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_225517779-1024x768.jpg 1024w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_225517779-768x576.jpg 768w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_225517779-1536x1152.jpg 1536w, https:\/\/lab.rapternet.us\/wp-content\/uploads\/2022\/01\/PXL_20220129_225517779-2048x1536.jpg 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">Nothing to See Here<\/figcaption><\/figure>\n<\/figure>\n\n\n\n<p>Now that its working, I adjusted the YAML for key #4. Key 4 is now set with the internal pull up enabled explicitly as well as inverting the output of the switch, without the invert, the default position would be &#8220;ON&#8221; and pressing the key would be registered as an &#8220;OFF&#8221; state which is opposite how I want the keys to be seen in home assistant.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">  - platform: gpio\n    name: \"Keypad 4\"\n    pin:\n      number: 0\n      mode:\n        input: true\n        pulldown: false\n        pullup: true\n      inverted: true\n    on_multi_click:\n..........................<\/pre>\n\n\n\n<p>With this final YAML update, I have the configuration done to the EspDeck Gen1. I have all keys working, all actions mapped correctly, and a fully functioning pad. The full\/final YAML file can be found in the <a href=\"https:\/\/github.com\/AeroSteveO\/EspDeck\">GitHub repo for the EspDeck<\/a> (the blog format doesn&#8217;t make for the best for hundreds of lines of config file).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"don-t-look-behind-the-prototype-1-curtains\">Don&#8217;t Look Behind the Prototype 1 Curtains<\/h2>\n\n\n\n<p>The first generation (sounds much better than first prototype) of the EspDeck has its fair share of problems, and a few solutions. Though in general I plan on solving more of the design problems with the second generation \/ prototype.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"problems-solved-in-the-first-iteration\">Problems Solved in the First Iteration<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Case was too shallow<\/li>\n\n\n\n<li>Electrical design failed to account for GPIO0 \/ Key 4<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"problems-to-solve-for-generation-2\">Problems to Solve for Generation 2<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Electrical design is inefficient (there are ways to avoid using any resistors in the design)<\/li>\n\n\n\n<li>Electrical design is different for Key 4 \/ GPIO0 vs the rest of the keys<\/li>\n\n\n\n<li>The case doesn&#8217;t support the esp device<\/li>\n\n\n\n<li>Hot glue holding the case together<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"gen-2-plans\">Gen 2 Plans<\/h2>\n\n\n\n<p>For generation 2 of the design, I plan on swapping it to use the internal pull ups in the ESP8266, and have the key switches go to ground instead of the +3.3v rail. This should simplify things, removing the need for the resistors, as well as removing the GPIO0 \/ Key 4 problem. <\/p>\n\n\n\n<p>Another plan is to get a better case design to support the ESP8266 inside the case. Currently its floating in the case and partially hot glued into place along with the USB cable. This needs to get redesigned to make it a bit cleaner and more robust, not needing to hot glue the cable into the case for fear of breaking the USB port would be great. Another addition could be a way to hold the key switch panel on top of the case without hot glue or pressure fitting it. I&#8217;m still not sure the best way to handle this, maybe some screws passing through the entire case to thread a few rounds into the top.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusions\">Conclusions<\/h2>\n\n\n\n<p>I&#8217;m happy with the outcome of the first EspDeck I built, though I&#8217;m also glad I didn&#8217;t build the second EspDeck at the same time. I do have some work on the second pad done that I will want to undo \/ correct to match my goals for generation 2. I have a few automations already put together on the macro pad, things that would normally take a few actions in the home assistant GUI to do are now one key press away. I just need to keep adding to it, looking for the best points to make things easier to use and to match my uses.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">EspDeck Resources<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/lab.rapternet.us\/?p=1616\">EspDeck Automations<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/lab.rapternet.us\/?p=1633\">Creating Icons for Relegendable Keycaps<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"resources\">Resources<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/AeroSteveO\/EspDeck\" target=\"_blank\">EspDeck on GitHub<\/a><\/li>\n\n\n\n<li><a rel=\"noreferrer noopener\" href=\"https:\/\/www.thingiverse.com\/thing:5223223\" target=\"_blank\">EspDeck on Thingiverse<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.youmagine.com\/designs\/espdeck\" target=\"_blank\" rel=\"noreferrer noopener\">EspDeck on YouMagine<\/a><\/li>\n\n\n\n<li><a rel=\"noreferrer noopener\" href=\"https:\/\/randomnerdtutorials.com\/esp8266-pinout-reference-gpios\" target=\"_blank\">RandomNerdTutorials Pinout Guides<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/esphome.io\/\">EspHome<\/a><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Some of the links in this post are affiliate links, which means I may earn a small commission if you make a purchase through them\u2014at no extra cost to you. This helps support the blog and allows me to continue creating content that you love. I will only recommend products and services that I trust and believe will be beneficial to my readers. Thank you for your support!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After seeing some posts with EspHome and Zigbee keypads, I realized I wanted to make one too. I wanted the ability to easily trigger more complex actions in home assistant that I don&#8217;t have an easy way to fully automate. I decided to make the EspDeck project to provide construction and technical details on building &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/lab.rapternet.us\/?p=1397\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;EspDeck: Home Assistant Macro Pad&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":1422,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,4],"tags":[90,76,74,38,39,75,49],"class_list":["post-1397","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-builds","category-how-to","tag-electronics","tag-espdeck","tag-esphome","tag-hardware","tag-home-assistant","tag-macropad","tag-smart-home"],"_links":{"self":[{"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=\/wp\/v2\/posts\/1397","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1397"}],"version-history":[{"count":116,"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=\/wp\/v2\/posts\/1397\/revisions"}],"predecessor-version":[{"id":4820,"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=\/wp\/v2\/posts\/1397\/revisions\/4820"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=\/wp\/v2\/media\/1422"}],"wp:attachment":[{"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1397"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1397"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lab.rapternet.us\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1397"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}