Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
8a6e1ad
config: color type
SpComb Jun 9, 2026
792ca99
leds: do not repeat artnet timeout, clear once when entering test mode
SpComb Jun 9, 2026
665b650
fixup config_set_color
SpComb Jun 9, 2026
982544e
leds static color, basic functionality to set at boot
SpComb Jun 9, 2026
c8123d2
main: leds static is always initialized
SpComb Jun 9, 2026
7e58d51
main: leds static overrides test mode
SpComb Jun 9, 2026
c7279ec
leds: cmd static, replaces all
SpComb Jun 9, 2026
a11b7ab
main: replace unsafe direct leds test cmd/api with task-based test mode
SpComb Jun 9, 2026
b1f9daf
http config api color type
SpComb Jun 9, 2026
5bd7d99
web: config type color
SpComb Jun 9, 2026
0670aa4
main: interpret static config color transparency for RGBW LEDs
SpComb Jun 9, 2026
9fa0314
config: color compat with RGB, RRGGBB, RRGGBBAA values
SpComb Jun 9, 2026
8212ccd
user_buttons: simplify test mode state
SpComb Jun 13, 2026
778def9
leds test: fix frame skips on premature update
SpComb Jun 13, 2026
faa48d9
leds test: refactor
SpComb Jun 13, 2026
53e6483
leds: remove TEST_MODE_BLACK, clear on TEST_MODE_NONE
SpComb Jun 13, 2026
59de03d
fixup step test mode
SpComb Jun 13, 2026
03a0eb5
leds test: fix auto mode on or after last frame
SpComb Jun 13, 2026
1126d01
main: refactor leds artnet timeout
SpComb Jun 13, 2026
0fbe82e
leds: track task update state to make artnet -> leds clear apply to b…
SpComb Jun 13, 2026
98f3a4b
main: TODO leds source priorities
SpComb Jun 13, 2026
326f8bf
leds: artnet sync clear
SpComb Jun 13, 2026
9805d55
main: handle leds update state overrides
SpComb Jun 13, 2026
8781e2c
main: fix artnet timeout stats
SpComb Jun 13, 2026
e3638cc
leds test: skip over CHASE mode in hold -> auto
SpComb Jun 13, 2026
2a44685
main: split leds_test_http.c
SpComb Jun 13, 2026
aab96ee
config_color_parse
SpComb Jun 13, 2026
3e48064
move config_leds_color
SpComb Jun 13, 2026
3507327
main: POST /api/leds/static
SpComb Jun 13, 2026
876dd9e
fixup config_leds_color
SpComb Jun 13, 2026
99210a4
config_color_str
SpComb Jun 13, 2026
c53bcff
leds: include static.color in leds http
SpComb Jun 13, 2026
414589c
main: common leds api color format
SpComb Jun 13, 2026
3838290
web: LedsView default to first available leds
SpComb Jun 13, 2026
3a629bb
main: leds http common leds=leds%d params
SpComb Jun 13, 2026
2dfaa9f
web: drop experimental color input alpha
SpComb Jun 13, 2026
23d6911
web: tabbed split view, controls actions fieldset button margin
SpComb Jun 13, 2026
c35ae15
web: leds static color picker
SpComb Jun 13, 2026
3afe165
web: leds static color save
SpComb Jun 13, 2026
c3c498b
web: form color input styles
SpComb Jun 13, 2026
328a0f1
main: fix leds config static_color description
SpComb Jun 13, 2026
2612290
web: config static_enabled=true on leds static color save
SpComb Jun 13, 2026
56a494f
main: remove unused clear_leds()
SpComb Jun 13, 2026
5096be5
main: route update_leds() via task
SpComb Jun 13, 2026
84c17ce
leds_clear_all() cannot fail
SpComb Jun 13, 2026
db463ac
leds: leds_set_all() cannot fail
SpComb Jun 13, 2026
aa0554f
main: use mutex and start_leds_update() / end_leds_update() for cmd/h…
SpComb Jun 13, 2026
1a03129
main: leds update timer
SpComb Jun 13, 2026
9e7c1ab
main: leds static_enabled description
SpComb Jun 17, 2026
fa260d7
main: review
SpComb Jun 17, 2026
e9bf663
main: split cmd/http update timers
SpComb Jun 17, 2026
afdc370
leds: crash on xSemaphoreGiveRecursive() failures
SpComb Jun 17, 2026
62ac2df
main: fix leds test wait tick bug
SpComb Jun 17, 2026
eb80913
main: add leds update state to status
SpComb Jun 17, 2026
621b0a1
main: TODO leds update -> output tick/timeout
SpComb Jun 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions components/config/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ static void print_configtab(const struct config_path path)

break;

case CONFIG_TYPE_COLOR:
printf("<RGB|RRGGBB|RRGGBBAA>");
break;

default:
printf("???");
break;
Expand Down
57 changes: 57 additions & 0 deletions components/config/color.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include <config.h>

#include <logging.h>

#include <string.h>

int config_color_parse(struct config_color *color, const char *value)
{
int r = 0, g = 0, b = 0, a = 0;

switch (strlen(value)) {
case 3:
a = 0xff;

if (sscanf(value, "%1x%1x%1x", &r, &g, &b) < 3) {
return -1;
}

r = (r << 4) | r;
g = (g << 4) | g;
b = (b << 4) | b;

break;

case 6:
a = 0xff;

if (sscanf(value, "%2x%2x%2x", &r, &g, &b) < 3) {
return -1;
}

break;

case 8:
if (sscanf(value, "%2x%2x%2x%2x", &r, &g, &b, &a) < 4) {
return -1;
}

break;

default:
return -1;
}

*color = (struct config_color) { r, g, b, a };

return 0;
}

int config_color_str(char *buf, size_t size, struct config_color color)
{
if (snprintf(buf, size, "%02x%02x%02x%02x", color.r, color.g, color.b, color.a) >= size) {
return -1;
}

return 0;
}
7 changes: 7 additions & 0 deletions components/config/get.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ int config_get(const struct config_path path, unsigned index, char *buf, size_t
break;
}

case CONFIG_TYPE_COLOR:
if (config_color_str(buf, size, tab->color_type.value[index])) {
return -1;
} else {
break;
}

default:
LOG_ERROR("invalid type=%d", tab->type);
return -1;
Expand Down
16 changes: 16 additions & 0 deletions components/config/include/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ enum config_type {
CONFIG_TYPE_BOOL,
CONFIG_TYPE_ENUM,
CONFIG_TYPE_FILE,
CONFIG_TYPE_COLOR,
};

struct config_enum {
Expand All @@ -52,6 +53,10 @@ struct config_file_path {
const char *suffix;
};

struct config_color {
uint8_t r, g, b, a;
};

struct configmod;
struct configtab;

Expand Down Expand Up @@ -119,6 +124,11 @@ struct configtab {
size_t size;
const struct config_file_path *paths;
} file_type;

struct {
struct config_color *value;
struct config_color default_value;
} color_type;
};
};

Expand Down Expand Up @@ -167,6 +177,12 @@ int config_file_walk(const struct config_file_path *paths, int (*func)(const str

FILE *config_file_open(const struct config_file_path *paths, const char *value);

/* Color */
#define CONFIG_COLOR_BUF_SIZE (8+1)

int config_color_parse(struct config_color *color, const char *value);
int config_color_str(char *buf, size_t size, struct config_color color);

int configmod_lookup(const struct configmod *modules, const char *name, const struct configmod **modp, unsigned *indexp, const struct configtab **tablep);
int configtab_lookup(const struct configmod *module, unsigned index, const struct configtab *table, const char *name, const struct configtab **tabp);

Expand Down
11 changes: 11 additions & 0 deletions components/config/print.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,17 @@ int config_print(const struct config_path path, unsigned index, FILE *file)
}
break;

case CONFIG_TYPE_COLOR:
if (fprintf(file, "%02x%02x%02x%02x",
tab->color_type.value[index].r,
tab->color_type.value[index].g,
tab->color_type.value[index].b,
tab->color_type.value[index].a
) < 0) {
return -1;
}
break;

default:
LOG_ERROR("invalid type=%d", tab->type);
return -1;
Expand Down
4 changes: 4 additions & 0 deletions components/config/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ int configtab_reset(const struct config_path path)
memset(tab->file_type.value, 0, tab->file_type.size);
break;

case CONFIG_TYPE_COLOR:
*tab->color_type.value = tab->color_type.default_value;
break;

default:
LOG_ERROR("invalid type=%d", tab->type);
return -1;
Expand Down
14 changes: 14 additions & 0 deletions components/config/set.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ int config_clear(const struct config_path path)
memset(tab->file_type.value, 0, tab->file_type.size);
break;

case CONFIG_TYPE_COLOR:
*tab->color_type.value = tab->color_type.default_value;
break;

default:
LOG_ERROR("invalid type=%d", tab->type);
return -1;
Expand Down Expand Up @@ -160,6 +164,13 @@ static int config_set_file(const struct config_path path, unsigned index, const
return 0;
}

static int config_set_color(const struct config_path path, unsigned index, const char *str)
{
const struct configtab *tab = path.tab;

return config_color_parse(&tab->color_type.value[index], str);
}

int config_set(const struct config_path path, const char *value)
{
const struct configtab *tab = path.tab;
Expand Down Expand Up @@ -201,6 +212,9 @@ int config_set(const struct config_path path, const char *value)
case CONFIG_TYPE_FILE:
return config_set_file(path, index, value);

case CONFIG_TYPE_COLOR:
return config_set_color(path, index, value);

default:
LOG_ERROR("invalid type=%d", tab->type);
return -1;
Expand Down
7 changes: 3 additions & 4 deletions components/leds/include/leds.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,10 +379,9 @@ enum leds_test_mode {
TEST_MODE_RGB_BLACK,

TEST_MODE_RAINBOW,
TEST_MODE_BLACK,
};

#define TEST_MODE_COUNT (TEST_MODE_BLACK + 1)
#define TEST_MODE_COUNT (TEST_MODE_RAINBOW)

int leds_new(struct leds **ledsp, const struct leds_options *options);

Expand All @@ -401,7 +400,7 @@ unsigned leds_count(struct leds *leds);
/*
* Set all LEDs off.
*/
int leds_clear_all(struct leds *leds);
void leds_clear_all(struct leds *leds);

/*
* @param index 0-based index
Expand All @@ -414,7 +413,7 @@ int leds_set(struct leds *leds, unsigned index, struct leds_color color);
* @param global 5-bit global brightness 0-31
* @param b, g, r 8-bit RGB value
*/
int leds_set_all(struct leds *leds, struct leds_color color);
void leds_set_all(struct leds *leds, struct leds_color color);

/*
* Decode LED colors from binary data, using given format.
Expand Down
8 changes: 2 additions & 6 deletions components/leds/leds.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ unsigned leds_count(struct leds *leds)
return leds->options.count;
}

int leds_clear_all(struct leds *leds)
void leds_clear_all(struct leds *leds)
{
struct leds_color color = {}; // all off

Expand All @@ -110,8 +110,6 @@ int leds_clear_all(struct leds *leds)
for (unsigned i = 0; i < leds->options.count; i++) {
leds->pixels[i] = color;
}

return 0;
}

int leds_set(struct leds *leds, unsigned index, struct leds_color color)
Expand All @@ -129,7 +127,7 @@ int leds_set(struct leds *leds, unsigned index, struct leds_color color)
return 0;
}

int leds_set_all(struct leds *leds, struct leds_color color)
void leds_set_all(struct leds *leds, struct leds_color color)
{
LOG_DEBUG("[%03d] %02x:%02x%02x%02x", leds->options.count, color.parameter, color.r, color.g, color.b);

Expand All @@ -138,8 +136,6 @@ int leds_set_all(struct leds *leds, struct leds_color color)
for (unsigned i = 0; i < leds->options.count; i++) {
leds->pixels[i] = color;
}

return 0;
}

unsigned leds_count_active(struct leds *leds)
Expand Down
25 changes: 2 additions & 23 deletions components/leds/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ int leds_test_chase_frame(struct leds *leds, unsigned frame, struct leds_color c
}

// black
if ((err = leds_set_all(leds, (struct leds_color){ }))) {
return err;
}
leds_clear_all(leds);

if ((err = leds_set(leds, frame % count, color))) {
return err;
Expand All @@ -48,8 +46,6 @@ int leds_test_chase_frame(struct leds *leds, unsigned frame, struct leds_color c

int leds_test_color_frame(struct leds *leds, unsigned frame, struct leds_color color)
{
int err;

switch (leds_parameter_type(leds)) {
case LEDS_PARAMETER_NONE:
break;
Expand All @@ -62,9 +58,7 @@ int leds_test_color_frame(struct leds *leds, unsigned frame, struct leds_color c
break;
}

if ((err = leds_set_all(leds, color))) {
return err;
}
leds_set_all(leds, color);

if (frame < TEST_MODE_COLOR_FRAMES) {
return TEST_FRAME_TICKS;
Expand Down Expand Up @@ -154,18 +148,6 @@ int leds_test_rainbow_frame(struct leds *leds, unsigned frame)
return TEST_FRAME_TICKS;
}

int leds_test_black_frame(struct leds *leds, unsigned frame)
{
int err;

// black
if ((err = leds_set_all(leds, (struct leds_color){ }))) {
return err;
}

return 0;
}

/*
* Return number of ticks for this frame, 0 for last frame, <0 on error.
*/
Expand Down Expand Up @@ -260,9 +242,6 @@ int leds_set_test(struct leds *leds, enum leds_test_mode mode, unsigned frame)
case TEST_MODE_RAINBOW:
return leds_test_rainbow_frame(leds, frame);

case TEST_MODE_BLACK:
return leds_test_black_frame(leds, frame);

default:
LOG_ERROR("unknown mode=%d", mode);
return -1;
Expand Down
23 changes: 23 additions & 0 deletions main/config_http_get.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ static int config_api_write_file_value(struct json_writer *w, const struct confi
}
}

static int config_api_write_color_value(struct json_writer *w, const struct configtab *tab, unsigned index)
{
char buf[CONFIG_COLOR_BUF_SIZE];

if (config_color_str(buf, sizeof(buf), tab->color_type.value[index])) {
return -1;
}

return json_write_string(w, buf);
}

static int config_api_write_configtab_value(struct json_writer *w, const struct configtab *tab, unsigned index)
{

Expand All @@ -49,6 +60,9 @@ static int config_api_write_configtab_value(struct json_writer *w, const struct
case CONFIG_TYPE_FILE:
return config_api_write_file_value(w, tab, index);

case CONFIG_TYPE_COLOR:
return config_api_write_color_value(w, tab, index);

default:
LOG_ERROR("unknown type=%d", tab->type);
return -1;
Expand Down Expand Up @@ -166,6 +180,13 @@ static int config_api_write_configtab_members_file(struct json_writer *w, const
);
}

static int config_api_write_configtab_members_color(struct json_writer *w, const struct configtab *tab)
{
return (
config_api_write_configtab_type_members(w, tab, "color")
);
}

static int config_api_write_configtab_members(struct json_writer *w, const struct config_path *path)
{
const struct configtab *tab = path->tab;
Expand All @@ -181,6 +202,8 @@ static int config_api_write_configtab_members(struct json_writer *w, const struc
return config_api_write_configtab_members_enum(w, tab);
case CONFIG_TYPE_FILE:
return config_api_write_configtab_members_file(w, tab);
case CONFIG_TYPE_COLOR:
return config_api_write_configtab_members_color(w, tab);
default:
return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions main/http_routes.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const struct http_route http_routes[] = {
{ "GET", "api/leds/test", leds_api_test_get, NULL },
{ "POST", "api/leds/test", leds_api_test_post, NULL },

{ "POST", "api/leds/static", leds_api_static_post, NULL },

/* user_http.c */
{ "GET", "api/status", user_api_get_status, NULL },
{ "POST", "api/button", user_api_post_button, NULL },
Expand Down
4 changes: 4 additions & 0 deletions main/http_routes.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,13 @@ int leds_api_get(struct http_request *request, struct http_response *response, v
int leds_api_get_status(struct http_request *request, struct http_response *response, void *ctx);
int leds_api_post(struct http_request *request, struct http_response *response, void *ctx);

/* leds_test_http.c */
int leds_api_test_get(struct http_request *request, struct http_response *response, void *ctx);
int leds_api_test_post(struct http_request *request, struct http_response *response, void *ctx);

/* leds_static_http.c */
int leds_api_static_post(struct http_request *request, struct http_response *response, void *ctx);

/* user_http.c */
int user_api_get_status(struct http_request *request, struct http_response *response, void *ctx);
int user_api_post_button(struct http_request *request, struct http_response *response, void *ctx);
Loading
Loading