Mapping keycodes back to verbose keycode descriptions

Currently I am working on a Python based keyboard simulator. I already ran simulations based on C++ and python implementations of plugins.

An important feature that I am now working on is a graphical display of the current state of the keyboard with RGB colored keys showing the current keys depending on the layer that is currently active. Imagine this as if the real keyboard had tiny LCD displays on each key, that display the current meaning of the key.
As the simulator works cycled, it is very easy to experiment with a new plugin and see how things change when keys are hit or if time elapses.

To enable this graphical display, I need to map the information stored in the Key union taken from the layer data structure back to a string. This means to map e.g. the Key generated via ShiftToLayer(FUNCTION) in the sketch’s keymap definition back to a string that is as closed as possible to the actual string ShiftToLayer(FUNCTION).

Has anyone of the developers already attempted something similar?

Of course, the information is all there in the sketch and I could possibly replace the KEYMAP_STACKED with something funny that generates a string array under the hood. But I would like to find a way to enable this without requiring the user to change her/his sketch and without fiddling with macros.

  (___,          Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
   Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
   Key_PageUp,   Key_A, Key_S, Key_D, Key_F, Key_G,
   Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
   Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,

   M(MACRO_ANY),  Key_6, Key_7, Key_8,     Key_9,         Key_0,         LockLayer(NUMPAD),
   Key_Enter,     Key_Y, Key_U, Key_I,     Key_O,         Key_P,         Key_Equals,
                  Key_H, Key_J, Key_K,     Key_L,         Key_Semicolon, Key_Quote,
   Key_RightAlt,  Key_N, Key_M, Key_Comma, Key_Period,    Key_Slash,     Key_Minus,
   Key_RightShift, Key_LeftAlt, Key_Spacebar, Key_RightControl,

Any ideas/help appreciated.

Here’s a link to the Python wrapper API and a little teaser from my current work (see below).

self.out.write(u"┏━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┓        ┏━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┓\n".format(r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6,        r0c9,  r0c10, r0c11, r0c12, r0c13, r0c14, r0c15))
self.out.write(u"┃{ 0}┃{ 1}┃{ 2}┃{ 3}┃{ 4}┃{ 5}┃{ 6}┃        ┃{ 7}┃{ 8}┃{ 9}┃{10}┃{11}┃{12}┃{13}┃\n")
self.out.write(u"┣━━━━╋━━━━╋━━━━╋━━━━╋━━━━╋━━━━┫    ┃        ┃    ┣━━━━╋━━━━╋━━━━╋━━━━╋━━━━╋━━━━┫\n")
self.out.write(u"┃{ 0}┃{ 1}┃{ 2}┃{ 3}┃{ 4}┃{ 5}┣━━━━┫        ┣━━━━┫{ 6}┃{ 7}┃{ 8}┃{ 9}┃{10}┃{11}┃\n".format(r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15))
self.out.write(u"┣━━━━╋━━━━╋━━━━╋━━━━╋━━━━╋━━━━┫    ┃        ┃    ┣━━━━╋━━━━╋━━━━╋━━━━╋━━━━╋━━━━┫\n")
self.out.write(u"┃{ 0}┃{ 1}┃{ 2}┃{ 3}┃{ 4}┃{ 5}┃{ 6}┃        ┃{ 7}┃{ 8}┃{ 9}┃{10}┃{11}┃{12}┃{13}┃\n".format(r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r1c6, r1c9, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15))
self.out.write(u"┣━━━━╋━━━━╋━━━━╋━━━━╋━━━━╋━━━━╋━━━━┫        ┣━━━━╋━━━━╋━━━━╋━━━━╋━━━━╋━━━━╋━━━━┫\n")
self.out.write(u"┃{ 0}┃{ 1}┃{ 2}┃{ 3}┃{ 4}┃{ 5}┃{ 6}┃        ┃{ 7}┃{ 8}┃{ 9}┃{10}┃{11}┃{12}┃{13}┃\n".format(r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r2c6,        r2c9,  r3c10, r3c11, r3c12, r3c13, r3c14, r3c15))
self.out.write(u"┗━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┛        ┗━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┛\n")
self.out.write(u"                ┏━━━━┓                                    ┏━━━━┓                \n")
self.out.write(u"                ┃{ 0}┣━━━━┓                          ┏━━━━┫{ 1}┃                \n".format(r0c7, r0c8))
self.out.write(u"                ┗━━━━┫{ 0}┣━━━━┓                ┏━━━━┫{ 1}┣━━━━┛                \n".format(r1c7, r1c8))
self.out.write(u"                     ┗━━━━┫{ 0}┣━━━━┓      ┏━━━━┫{ 1}┣━━━━┛                     \n".format(r2c7, r2c8))
self.out.write(u"                          ┗━━━━┫{ 0}┃      ┃{ 1}┣━━━━┛                          \n".format(r3c7, r3c8))
self.out.write(u"                               ┗━━━━┛      ┗━━━━┛                               \n")
self.out.write(u"                    ┏━━━━━━┓                        ┏━━━━━━┓                    \n")
self.out.write(u"                    ┃ { 0} ┃                        ┃ { 1} ┃                    \n".format(r3c6, r3c9))
self.out.write(u"                    ┗━━━━━━┛                        ┗━━━━━━┛                    \n")

Yeah, Chrysalis has something along these lines. It’s… a wee-bit of ClojureScript, but you may be able to adapt some of the ideas to Python. Or use parts of Chrysalis, dump the keymap into EDN (which is a bit like JSON, but more Clojure-ish), and work with that from Python.

The interesting parts of Chrysalis start around here.


Now I am one step further.

Not perfect yet, as I want to get rid of the references for all those keys that are standard, like β€˜a’, β€˜-’, etc.

What I finally did is to parse the sketch (.ino), extract the keymap definition and generate a nice c++ file from it that can be Python wrapped. It allows lookup of the key description like CTL_T(1) based on a layer id and the row/col information. The nice thing about this solution is that I am fully independent of the keyboard type (M01, …).

What’s still missing is the possibility to check if a Key can be easily mapped to a short descriptive four character string. This is supposed to be possible for the keys defined in key_defs_keyboard.h.

@algernon: Thanks for pointing me to the ClojureScript, this might be useful for further steps. Did you ever stumble upon a webpage/table/whatever that maps the hid hex codes, like those referenced in src/HIDTables.h to strings/characters that could serve as key labels? Something that lets me map, e.g. the 0x04 in

#define HID_KEYBOARD_A_AND_A	0x04`

to a string like β€œa”? Of course I can generate such a mapping by myself but that’s pretty tedious and error prone.

1 Like

Nope. Closest is the USB HID tables, but that’s not too useful either (and it is a PDF to boost).

1 Like

Just ran a lorem ipsum heatmap test with Kaleidoscope-Python. LED colors are now fully working. Thanks to @craigdissel for adding the feature to Kaleidoscope-Hardware-Virtual!


Can someone with an actual physical Model01 please confirm that the key in the upper right of the left hand side keyboard is actually blue when color effects like Heatmap are used?


The above test is carried out using a python script, that iterates over a lorem ipsum string and presses and releases keys after lookup in a reverse keymap. The final state of the LEDs is visualized (console output).

1 Like