ESPHome powered 24-button keypad | The LocalDeck

We’ve just released the LocalDeck, a 24-button keypad powered by ESPHome

The LocalDeck keypad lets you control your smart home in one convenient place.
With 24 buttons – customisable and RGB backlit – this keypad makes controlling your home easy and instant for the whole family. (Yes, even your significant other).
And we’re just going to say it – it looks pretty cool.
Designed with super durable Kailh MX Brown Switches, you can be sure your deck will suit the style of any room.

3 Likes

Enjoying this so far, except for the random green flickering @AAllport. Also, did you label them all 0001 or did I really get the first production model? :upside_down_face:

First project complete: Illuminate one key blue when my weather station is detecting rain. Pressing the button sends TTS message to my watch giving me current piezo readings, rainfall chance over next hour. Thinking of also adding in having it read back a short form forecast for the rest of the day.

We did experience some of this during development, but we made many changes to improve the signal integrity (like plastering vias everywhere).
Can I check that it’s not always happening, just the occasional flicker when you press a button?

They’re all serialised… congrats on being #1

That’s amazing… Please consider posting on our forum with your automation!

Flickering is intermittent and will occur even without pressing buttons.
It looks like power leakage if I’m honest. Almost like a connection is not quite being made correctly.

Just xposting for visibility… we have found a fix - Fix occasional flashing · Issue #26 · LocalBytes/localdeck-config · GitHub

1 Like

Node-RED starter flow:

If, like me, you enjoy using Node-RED for your HA automations, this is a short demo flow which:

  • Listens for any button press on any of your localDecks (using a regex binary_sensor.localdeck_.*_button_.*

  • Extracts the localdeck name and button number into msg.data

  • Passes onto a function which turns the corresponding light on (red, fast pulse, 100% brightness) or turns it off, appropriately.

I hope it’s of use to somebody.

[{"id":"d9ca31236363cf76","type":"server-state-changed","z":"e441d6e9.691a58","name":"Keypad button","server":"82070ffe.b97dd","version":5,"outputs":2,"exposeAsEntityConfig":"","entityId":"binary_sensor.localdeck_.*_button_.*","entityIdType":"regex","outputInitially":false,"stateType":"str","ifState":"on","ifStateType":"str","ifStateOperator":"is","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":110,"y":1820,"wires":[["3fc45fb7a2d766af"],[]]},{"id":"3fc45fb7a2d766af","type":"change","z":"e441d6e9.691a58","name":"Extract keypad & button","rules":[{"t":"set","p":"data.button","pt":"msg","to":"$split(msg.topic, \"_\")[4]","tot":"jsonata"},{"t":"set","p":"data.keypad","pt":"msg","to":"$split(msg.topic, \"_\")[2]","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":1820,"wires":[["588818e5499e8d95"]]},{"id":"3df88dcc725b0a36","type":"comment","z":"e441d6e9.691a58","name":"LocalDecks","info":"","x":90,"y":1740,"wires":[]},{"id":"6d625acbe90a3bf4","type":"api-call-service","z":"e441d6e9.691a58","name":"","server":"82070ffe.b97dd","version":5,"debugenabled":false,"domain":"light","service":"turn_on","areaId":[],"deviceId":[],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":950,"y":1760,"wires":[[]]},{"id":"588818e5499e8d95","type":"function","z":"e441d6e9.691a58","name":"Format action (on with properties/off)","func":"let lightName = \"light.localdeck_\" + msg.data.keypad + \"_button_\" + msg.data.button + \"_light\";\nlet lightState = global.get(\"homeassistant.homeAssistant.states['\"+ lightName + \"'].state\");\n\nif (lightState == 'on') {\n    msg.payload = {\n        \"target\": {\n            \"entity_id\": lightName\n        }\n    }\n\n    return [null, msg];\n\n} else {\n    msg.payload = {\n        \"target\": {\n            \"entity_id\": lightName\n        },\n        \"data\": {\n            \"brightness_pct\": 100,\n            \"effect\": \"Fast Pulse\",\n            \"color_name\": \"red\"\n        }\n    }\n\n    return [msg, null];\n}","outputs":2,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":670,"y":1820,"wires":[["6d625acbe90a3bf4"],["7ec75b4acaed5edd"]]},{"id":"7ec75b4acaed5edd","type":"api-call-service","z":"e441d6e9.691a58","name":"","server":"82070ffe.b97dd","version":5,"debugenabled":false,"domain":"light","service":"turn_off","areaId":[],"deviceId":[],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":950,"y":1860,"wires":[[]]},{"id":"82070ffe.b97dd","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]