DustinWatts / FreeTouchDeck

For interfacing with Windows/macOS/Linux using an ESP32, a touchscreen and BLE.
https://www.youtube.com/dustinwatts
MIT License
624 stars 126 forks source link

Flexible configuration #51

Closed sle118 closed 3 years ago

sle118 commented 3 years ago

This is just a comment. @DustinWatts and the other contributors to this project. Feel free to close it.

I wanted to thank you for taking the time to build this. It was exactly what I was looking for!

I took the time to port the code to the TTGO T-Watch 2020 v1 which I happen to own. This wasn't a huge effort; the watch has the same capacitive touch controller that the project uses. A couple of notable differences are the screen resolution (smaller) as well as the onboard power management chip which needs to be told to power on in order to get the back light to work.

Just for fun, I spent a couple of hours refactoring a bit of the code, especially around how menus/screens are represented and loaded internally. I've done it in a way that would allow any number of menus to be created, each with an arbitrary number of buttons, and an arbitrary number of actions, all the while preserving the JSON format which you are currently using (for the sake of staying compatible with existing installs).

Essentially, there are now a few more classes:

Let me know your thoughts and if this is something which you'd like to see some day.

DustinWatts commented 3 years ago

With the dedicated reboot mode, the system is now rock solid and there's no need to worry about stopping extra services. The system mode flag is sitting in a memory area that doesn't get initialized on reboot. __NOINIT_ATTR

I also just updated the button background colors. So menu colors and function buttons colors now show up correctly!

The only thing I haven't yet gotten to work is the mute/volume control (media buttons). Next for me will be some code cleanup and some minor refactoring. Then I'm thinking of implementing "toJSON()" methods that are callable from the "menu" level, as well as new json constructors the new json format.

The mediakeys work a bit different from other keys. I have had a play around and I can get it to work, but only if use bleKeyboard.write(KEY_MEDIA_MUTE) for example. Not with the vector you created, so there is something going wrong.

I changed some things in the mapping of the capacitive touch controller and all works for me now! I just have to check if this works consistently over multiple different screens to see if it can be hard coded or if there is also some calibration for the capacitive touch screen needed.

About the multistage sleep, that is a good idea!

Next I'll have a play with some UI. Most people would like to have a 43 matrix instead of a 32 as it is now. So I'll focus on that mainly. My question how is the layout determined? I mean, I have a menu now (the standard one) that has 6 buttons. They now all show up in one line.

sle118 commented 3 years ago

The layout strategy now is to fill lines until wrap occurs. I believe the best way to achieve a 4x3 layout would be to let users set the button size and let the screen overflow automatically as it does now. I have tested the layout code on a tiny screen that's 240x240, which isn't ideal.

Edit: I thought about something else. You could have an option on the front end where users decide how many tiles per line (for a given menu), how many rows, as well as spacing between buttons, and pass that to the menu init method, which is where the layout gets calculated. I'll implement a 4x3 default for now until that comes from the front end.

sle118 commented 3 years ago

I pushed some changes. Here is a summary

I guess the next big thing will be to update the configurator so that it allows sending more complex menu structures. If no one volunteer, then I will give it a shot.

As for the commands:

the new commands are conf, revx, revy and rot

sle118 commented 3 years ago

Well, I just couldn't resist. I am going to come up with a first iteration of the configurable layout editor. It won't be a big departure from current model, but the UI itself will be generated on the fly based on parameters rather than being static.

DustinWatts commented 3 years ago

Well, I just couldn't resist. I am going to come up with a first iteration of the configurable layout editor. It won't be a big departure from current model, but the UI itself will be generated on the fly based on parameters rather than being static.

I am very impressed! I ha a quick look around and just wanted to see how easy it is to make a layout... and it took me 5 minutes. 3 minutes was spent uploading things. So, Sébastien, this is really great!

I also like the configuration via serial, nice touch (pun intended)!

sle118 commented 3 years ago

now... here's the output of the json serializer when dumping the menu configuration. You'll notice that the keys are now called by their names ;)

-- Edited out as it made the thread difficult to follow
danielhunt commented 3 years ago

@danielhunt would you be in for a frontend/backend collaboration to handle the "new generation" configuration? Thinking that we might be able to leverage google's blocky for this? https://developers.google.com/blockly

Or not... I've been wondering how to make a flexible interface as simple enough for end users and I am definitely not a front end/ui person!

Sorry for the late response @sle118 - I don't have a lot of time to commit to something like this unfortunately. It wouldn't be fair of me to commit to it and not deliver :(

danielhunt commented 3 years ago

@sle118 I don't know if you're aware but the touchscreen on the ESP32 Touchdown hasn't functioned using your fork for quite a while. I'm not sure why just yet. (the display itself works though)

sle118 commented 3 years ago

@danielhunt thank you for reminding me; I didn't write know how to deal with the screen rotation vs the touch coordinates and testing permutations trough code was taking a good deal of time. So I added a console command to align panel coordinates. The touch down requires flipping x and y axis as well as reversing y (if I remember).

I just forgot to set these by default on the touchdown target build :).

Please use the serial console and use command help (followed by space) to see what commands are.

danielhunt commented 3 years ago

👍

FYI, this is the flipping code I've been using in my hacking (taken from the original master)

    uint16_t touchX, touchY;

    bool touched = false;

    if (ts.touched()) {
      // Retrieve a point
      TS_Point p = ts.getPoint();

      //Flip things around so it matches our screen rotation
      p.x = map(p.x, 0, 320, 320, 0);
      touchX = p.y;
      touchY = p.x;

      touched = true;
    } else {
      touched = tft.getTouch(&touchX, &touchY, 600);
    }

    if(!touched)
    {
      return false;
    }

    Serial.printf("x:y %s:%s\n", String(touchX), String(touchY));
DustinWatts commented 3 years ago

👍

FYI, this is the flipping code I've been using in my hacking (taken from the original master)

    uint16_t touchX, touchY;

    bool touched = false;

    if (ts.touched()) {
      // Retrieve a point
      TS_Point p = ts.getPoint();

      //Flip things around so it matches our screen rotation
      p.x = map(p.x, 0, 320, 320, 0);
      touchX = p.y;
      touchY = p.x;

      touched = true;
    } else {
      touched = tft.getTouch(&touchX, &touchY, 600);
    }

    if(!touched)
    {
      return false;
    }

    Serial.printf("x:y %s:%s\n", String(touchX), String(touchY));

It might be that the map() function needs some more then just mapping 0 to 320 and 320 to 0. I have an offset in the touches. I needed some like (p.x, 40, 280, 320, 0); For bigger buttons this wasn't really an issue, but for smaller buttons it seems it is. So I'm thinking to also make a calibration screen for the capacitive touch. Unless the offset is always the same for all screens, the we could just hard code it.

sle118 commented 3 years ago

Ok. I'll add the calibration tomorrow; it will help gather some data to see if these panels are consistent across the board. For me, and using the capacitive version of the touchdown, flipping as described worked good enough.

FYI, I'm looking for some real complicated use cases of configurations of anyone has been watching this thread. I'm refining the parsing algorithm that will interpret the existing menu layouts and convert them into the new design. The more the complication, the better, as I'm looking for as many use cases as possible.

Note that the most recent changes I committed to my fork include the ability to send a sequence of arbitrary key presses in the action definition. The system will parse The freetext action type and interpret anything between curly brackets as special keys. For example: "{LEFT_CTRL}{LEFT_ALT}{DELETE}" should send just that.

For now, none of this is supported on the front end so you'd have to edit the JSON files manually to try out.

I'm working around several limitations and doing my best to move fast, so I'd like to get some feedback from the power users around. Thank you!

sle118 commented 3 years ago

I just pushed some more changes

I just realized that I broke the media keys once more. So this version of the code will crash when trying to send keys out!

DustinWatts commented 3 years ago

A yes, a custom device name is much requested, so that is a good thing! It might be a good idea to when you push, you also push the data folder (or at least a general config). Just to give us some idea of how the structure of the JSON is intended.

I can't find the ledbrightness persistence btw. No issue, because I think this is a good idea!

My build doesn't crash when sending out mediakeys btw, although it did stop sending them :)

And what does setconfig actually do?

Great work again Sébastien!

Edit: Another funny thing I just discovered, the latching dot colour when I first upload the data folder is red. Then after a reboot, it is green, then after another reboot blue, then a fainter blue and after that is gone. Some unintended bit-shifting going on? :)

sle118 commented 3 years ago

I had forgotten to push the LED persistence, my bad. I'll also make sure I test a bit more before pushing. This time, though, all I wanted was to seek the feedback you provided, given the novelty of user actions.

So two main console commands while there is no front end:

So basically, you dump the JSON, edit it in your favorite text editor and upload it back!

As for the latch color, this was caused by a small glitch with the configuration parsing (solved now). However, you'll have to manually edit the file or wipe it so defaults kick in again. Also note that modifiers will show as text now in the config structure. I intend to put them in an array at some point, to simplify parsing and execution, but for now it will suffice.

Parsing if freetext is also better now. The idea is that this will allow arbitrary sequences of actiions to be executed. For example:

ThisTextWillBeSent{MENU:menu3}{DELAY:200}{LEFT_CTRL}{LEFT_ALT}{DELETE}{DELAY:500}{ESCAPE}{DELAY:1000}{SLEEP}

would send text, then navigate to menu3, then send ctrl+alt+delete out, then escape out, then pause 500ms and finally send the touchdown to sleep.

That sequence really doesn't make practical sense, but it's just to illustrate the potential

sle118 commented 3 years ago

@danielhunt I'll have a more robust iteration later in the day if you want to test that rotation is good now by default (after uploading the data folder once more).

DustinWatts commented 3 years ago

So basically, you dump the JSON, edit it in your favorite text editor and upload it back!

That is a nice feature! Free text parsing is also very nice, haven't tried it out that much though.

I was thinking. A lot of people ask for some kind of Home Assistant support. So basically API support. The reason I have not yet implemented something like this was a) the lack of free text (which is not a problem anymore) and b) memory usage. Just like you were unable to start the configurator. But... now moving to cJson I was thinking about NimBLE. That is advertised as having less memory usage. I also has a bleKeyboard like fork. So maybe this is something to look in to?

It would be very popular I think if we can get BLE and WiFi working together. A user could have a menu with HASS.io buttons and another with keyboard buttons. One device to rule them all!

sle118 commented 3 years ago

If memory is an issue, then your next iteration of the Touchdown could be done with a ESP32 Wrover instead. It has a "large" PSRAM that supports up to 4Mb of additional RAM. This is plenty enough to run all these things together. Once I'm done with the bulk of the changes, I'll see how we can (or cannot) improve memory usage on the poor non-PSRAM ESP32 ;)

sle118 commented 3 years ago

with regards to modifiers, they are now implemented as arrays in my local fork. I'll push later. It is also possible to push a single menu or the whole new menu structure through the console, just like the general config json now.

sle118 commented 3 years ago

Alright. Freetext now works to some extent

DustinWatts commented 3 years ago

Could you also push the homescreen and one of your menu configs? I tried making a menu config, but other then the back button disappearing, I didn't get very far :)

DustinWatts commented 3 years ago

I noticed that all buttons where being draw with a black background. So I modified the draw function a bit to draw the background according to the menu or function button colour if it is not a black background button. I'm not going to push things to your fork to keep things clean, so i'll just post what I did here.

In void FTButton::Draw(bool force) where I made the change to use the color of the logo if not black, I added a buttontype check and set the background accordingly. Basically anything other then a MENU means it is a function button:

BGColor = tft.color565(image->R, image->G, image->B);

if(BGColor > 0) // If the image color is not black use that image colour as background
    {
        BackgroundColor = BGColor;
    }
    else
    {
        if(ButtonType != ButtonTypes::MENU)
        {
                BackgroundColor = generalconfig.functionButtonColour;
        }
        else
        {
                BackgroundColor = generalconfig.menuButtonColour;
        }
 }

Btw... the latching colour thing is now ok, unless I latch and unlatch. Then it still happens...

sle118 commented 3 years ago

Could you also push the homescreen and one of your menu configs? I tried making a menu config, but other then the back button disappearing, I didn't get very far :)

You should be able to use your own menus. The ones that you have as an example work out of the box. Once you are on the console of the started device, you can use "menus" command if I am not mistaken to dump the new structure as it is created internally. There's also another command to write menus into a single file; this is the one way trip to using the new menu format that is required for freetext.

There is no longer a home menu to configure; It gets built automatically for you from all menus defined with type "HOME".

sle118 commented 3 years ago
    if(ButtonType != ButtonTypes::MENU)
    {
            BackgroundColor = generalconfig.functionButtonColour;
    }
    else
    {
            BackgroundColor = generalconfig.menuButtonColour;
    }

Ideally, this logic should be in the FTButton constructor since the button type does not change after creation.

Btw... the latching colour thing is now ok, unless I latch and unlatch. Then it still happens...

This is strange. I will have a look. Which button specifically? Mute/unmute does not get saved to general config, but beep/no beep (preference menuu) does. Try both to see if there is a difference. Also dump your config and make sure the colors are still there.

I will go ahead and remove the menu files from my fork and replace them with the new single file format.

sle118 commented 3 years ago

I'm going to see if I could put the touchdown under the binocular and replace the JTAG gpio from the TFT with something else. Having JTAG would speed things up considerably given that debugging with serial traces is akin to try hiking with a candle to light up the way. You see enough to walk, but not very far so it is slow.

Otherwise, is there a good source for the panels themselves? I could assemble one on a good old breadboard

sle118 commented 3 years ago

Also one more note about the menu config. Back buttons are automatically added to the end of the list.

There are still some quirks with the parser, though. The biggest challenge is to keep backwards compatibility so users with complicated setup will be able to migrate without having to fully redo their setup, and that complicates the parsing code quite a bit.

I haven't had much feedback at this point since this is still very much bleeding edge, but I'm starting to think that the system should only implement free text parsing and ditch the rest. I'd push a comprehensive example to the repo and simply not load old config at all.

Comments are welcome from existing power users

DustinWatts commented 3 years ago

I would not spend too much time on the backwards capability for the setups. Most users are already used to re-doing their config of all the changes I have made that required uploading SPIFFS again :)

I will go ahead and remove the menu files from my fork and replace them with the new single file format.

That would be great!

Otherwise, is there a good source for the panels themselves? I could assemble one on a good old breadboard

What panel do you mean? A TFT panel? Or the PCB?

Try both to see if there is a difference. Also dump your config and make sure the colors are still there.

I'll have a look tomorrow. But I meant the Beep and Sleep buttons. I remember that when latching on/off the colour would stay the same, but then on the next reboot the colour of the on/off latched had changed. The one I didn't touch was still it's original colour.

Speaking of saving the latch status. People pointed out to me that when the ESP32 goes to sleep, the latch status is also lost. Which makes sense because it basically reboots when waking up. I would be great if we could save that to the non-volatile memory too.

sle118 commented 3 years ago

I just pushed a complete example now with a sub menu, etc.

I meant the TFT screen with touch. I can't seem to find a reasonable price around.

Latch works for me now, by the way. Might be worth trying to upload the data folder once more. I'll see what I can do for the latch status. Perhaps we could try to save a small map in the slow rtc memory and pull it back when restoring from sleep.

sle118 commented 3 years ago

Speaking of saving the latch status. People pointed out to me that when the ESP32 goes to sleep, the latch status is also lost. Which makes sense because it basically reboots when waking up. I would be great if we could save that to the non-volatile memory too.

I started an implementation for this already today. There are really two ways to do this:

DustinWatts commented 3 years ago

Before sending the ESP32 to sleep, save the state in a file. During startup, check the start reason. If it's wake-up from sleep, read the status file. If not, delete the file.

Maybe go this way. I'm thinking out loud now, we could make an option in the configurator that will allow user to choose if latch states will persist through reset and power down?

DustinWatts commented 3 years ago

About the FREETEXT. If work is completed on that, I see no reason to have other types (other than needed by FTD itself). A configuration like this "{LEFT_GUI}{LETTERS:r}{RELEASE_ALL}{DELAY:100}cmd{RETURN}dir{RETURN}" is much simpler then have to configure each action separate.

I know the line above does not work. But I have a question: where and when are modifiers released? Ideally this would be always at the end of an action. I think also in the case of FREETEXT. Unless otherwise specified by {RELEASE_ALL} Because if LEFT_GUI is released before the letter r, CMD+R doesn't work.

DustinWatts commented 3 years ago

I still have the latch issue btw... reuploaded spiffs and the code. I'll try a erase_flash later today. And if that doesn't work, I'll make a little video showing you what I mean :)

I see you moved the background colour logic to the constructor, but that didn't work on my end. Keeping it in the draw function does. But I did test the latching without my added code in case I was causing it, but alas, no difference.

sle118 commented 3 years ago

I think I know what's wonky about colors. Setting config in the console results in converting the html colors to a different color space. The colors were then saved in that color space and converted again during config load. So the colors were going like RGB888toRGB565->save->restart->load config->RGB888toRGB565 on a RGB565 color.

I'm going to save the text value in the config structure so it is simple to save the config upon change.

And before pushing my changes, I'll make sure colors work ;)

sle118 commented 3 years ago

I know the line above does not work. But I have a question: where and when are modifiers released? Ideally this would be always at the end of an action. I think also in the case of FREETEXT. Unless otherwise specified by {RELEASE_ALL} Because if LEFT_GUI is released before the letter r, CMD+R doesn't work.

If we agree on "FREETEXT" going forward, then the parser will be very simple and I'll probably ditch the "action type" concept altogether.

As for release, it should happen after each sequence in the actions array. When actions are executed, the button checks if any requires releasing the keys and it should do it automatically.

sle118 commented 3 years ago

Could you remind me how the transparent color logic is supposed to work?

DustinWatts commented 3 years ago

Could you remind me how the transparent color logic is supposed to work?

If the first pixel of the image is black -> draw transparent (meaning all black pixels will become menu/function button colour), if not use the colour of the first pixel as the button background colour.

Technically, drawing transparent will not draw black pixels. So if the button color is already there, it will remain there. Basically skipping the black pixels...

sle118 commented 3 years ago

Could you remind me how the transparent color logic is supposed to work?

If the first pixel of the image is black -> draw transparent (meaning all black pixels will become menu/function button colour), if not use the colour of the first pixel as the button background colour.

Technically, drawing transparent will not draw black pixels. So if the button color is already there, it will remain there. Basically skipping the black pixels...

That makes perfect sense now. I'll make sure it works as intended!

sle118 commented 3 years ago

I believe I have nailed down colors and transparency. I even created a sub menu that uses all sorts of fancy colors for buttons, etc.

Free text now works well even with option keys, so it is possible to send sequences like {LEFT_ALT}{TAB}, or {LEFT_CTRL}{LEFT_SHIFT}F and not have to tell the system to release the buttons when done. Releasing is performed automatically at the end of a given "FREETEXT" sequence.

DustinWatts commented 3 years ago

Great! :) I took the liberty to structure the UserConfig.h a bit. I think for usability by inexperienced users, just selecting the right board should be enough. Something like this:

#pragma once
#include <queue>
#include "FTAction.h"
#include <freertos/task.h>

/* ------------------------------------------------------------------------ */
/* Select the board that you are using below. Make sure to only select one! */
/* ------------------------------------------------------------------------ */

//#define MAKERFABTOUCH
//#define ESP32TOUCHDOWN
#define ESP32DEVKIT
//#define ARDUINO_TWATCH

/* ------------------------------------------------------------------------ */
/* Board specific config. No need to touch if you selected the right board  */
/* ------------------------------------------------------------------------ */

/* MakerFab's Touchscreen configuration */
#ifdef MAKERFABTOUCH
#define CUSTOM_TOUCH_SDA 26
#define CUSTOM_TOUCH_SCL 27
#define USECAPTOUCH
#define touchInterruptPin GPIO_NUM_0
#define SCREEN_ROTATION 1
#define INVERSE_Y_TOUCH
#define FLIP_TOUCH_AXIS

/* Arduino TWatch Configuration */
#elif defined(ARDUINO_TWATCH_BASE) && defined(ARDUINO_TWATCH)
#include "axp20x.h"
#define CUSTOM_TOUCH_SDA 23
#define CUSTOM_TOUCH_SCL 32
#define USECAPTOUCH
#define touchInterruptPin GPIO_NUM_38
#define TFT_BL 12
#define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 240
#define SCREEN_ROTATION 2
#define ILI9341_DRIVER

/* ESP32 TouchDown Configuration */
#elif defined(ESP32TOUCHDOWN)
#define touchInterruptPin GPIO_NUM_27
#define speakerPin GPIO_NUM_26
#define SCREEN_ROTATION 1
#define FLIP_TOUCH_AXIS
#define INVERSE_Y_TOUCH
#define USECAPTOUCH

/* Using the ESP32 DevKit with a screen module */
#else defined(ESP32DEVKIT)
#define SCREEN_ROTATION 1
#define FLIP_TOUCH_AXIS
#define INVERSE_Y_TOUCH
#define touchInterruptPin GPIO_NUM_27
#endif

/* --- END OF USER CONFIG --- */

#ifndef touchInterruptPin
#define touchInterruptPin -1
#endif
#ifndef speakerPin
#define speakerPin -1
#endif
#if defined(ST7789_DRIVER) || defined(ST7735_DRIVER) || defined(ILI9163_DRIVER)
#define TFT_HEIGHT SCREEN_HEIGHT
#define TFT_WIDTH SCREEN_WIDTH
#endif
#ifndef SCREEN_ROTATION
#define SCREEN_ROTATION 1
#endif
#ifndef INVERSE_Y_TOUCH
#define INVERSE_Y_TOUCH false
#else
#undef INVERSE_Y_TOUCH
#define INVERSE_Y_TOUCH true
#endif

#ifndef INVERSE_X_TOUCH
#define INVERSE_X_TOUCH false
#else
#undef INVERSE_X_TOUCH
#define INVERSE_X_TOUCH true
#endif

#ifndef FLIP_TOUCH_AXIS
#define FLIP_TOUCH_AXIS false
#else
#undef FLIP_TOUCH_AXIS
#define FLIP_TOUCH_AXIS true
#endif

// Define the storage to be used. For now just SPIFFS.
#define FILESYSTEM SPIFFS

// Text Button Label Font
#define LABEL_FONT &FreeSansBold12pt7b

// Font size multiplier
#define KEY_TEXTSIZE 1

enum class Sounds
{
  GOING_TO_SLEEP,
  BEEP,
  STARTUP
};

#define LED_BRIGHTNESS_INCREMENT 25

extern void HandleAudio(Sounds sound);
extern Config generalconfig;
extern void drawErrorMessage(String message);
extern void drawErrorMessageChar(String message);
void drawErrorMessage(bool stop, const char *module, const char *fmt, ...);
DustinWatts commented 3 years ago

I'll leave that up there for a bit and then will remove it because of clutter. Another thing I was wondering. I couldn't find a way to have a menu button on the home screen just having a "label" instead of a logo, like it is possible to do in the submenu's. It could be that I overlooked it though!

sle118 commented 3 years ago

I'll leave that up there for a bit and then will remove it because of clutter. Another thing I was wondering. I couldn't find a way to have a menu button on the home screen just having a "label" instead of a logo, like it is possible to do in the submenu's. It could be that I overlooked it though!

The home menu generation was force defaulting the question icon. I resolved this in the upcoming commit, which also has the updated full menu structure including a label type sub menu.

I'm stripping away unnecessary complexity from the parser as well. There's going to be a cleanup needed for sure, but we're slowly getting there. I'm sure everyone will appreciate the simplified action configuration!

sle118 commented 3 years ago

I'll leave that up there for a bit and then will remove it because of clutter. Another thing I was wondering. I couldn't find a way to have a menu button on the home screen just having a "label" instead of a logo, like it is possible to do in the submenu's. It could be that I overlooked it though!

You could send me pull requests ;). Soon I think I'll be able to send a pull request your way and can run with the ball from there.

I must have killed about 75% of the actions code since not trying to support old configurations. Still need to regression before I push anything

DustinWatts commented 3 years ago

You could send me pull requests ;). Soon I think I'll be able to send a pull request your way and can run with the ball from there.

Could you pull that in the DEV branch? All documentation is made for the current version and I need to re-write a lot of it. Which will take some time. When there is a working version including configurator (which I'm working on) we could invite people on my Discord and YT to download the DEV branch and become beta testers....

briight commented 3 years ago

Im happy to test. Iv already had alook around your fork and got it running on my esp32. Thing holding mine back atm was the web config crashed on start up

DustinWatts commented 3 years ago

Thing holding mine back atm was the web config crashed on start up

This is because the configurator is looking for json files that do no exist anymore. But even without that the configurator is not ready yet. So you could get around that but the configurator in it's current form will be useless atm.

DustinWatts commented 3 years ago

I must have killed about 75% of the actions code since not trying to support old configurations. Still need to regression before I push anything

Speaking of actions. I have an idea to add an GPIO action to the ActionTypes class. Which will be a GPIO toggle action. To make sure only free GPIO's are allowed to be in that action, maybe an ALLOWED_GPIO array in the UserConfig per board?

DustinWatts commented 3 years ago

I was also wondering... is there some price to be had for the longest/most commented issue on Github? :D

sle118 commented 3 years ago

I must have killed about 75% of the actions code since not trying to support old configurations. Still need to regression before I push anything

Speaking of actions. I have an idea to add an GPIO action to the ActionTypes class. Which will be a GPIO toggle action. To make sure only free GPIO's are allowed to be in that action, maybe an ALLOWED_GPIO array in the UserConfig per board?

Good idea!

sle118 commented 3 years ago

I was also wondering... is there some price to be had for the longest/most commented issue on Github? :D

Not really, but GitHub now has discussions for these things ;)

sle118 commented 3 years ago

I've made good progress (causing a rather short night of sleep) and the configuration simplification is now complete. I have started testing and need to tune the keyboard playback as I had an issue with the TAB key. A couple of things that went along the way: