Skip to content

Commit

Permalink
Merge pull request #96 from qmsk/web-info
Browse files Browse the repository at this point in the history
Web UI improvements
  • Loading branch information
SpComb authored Jan 6, 2025
2 parents 3c5be73 + 498c909 commit 3dbb8a1
Show file tree
Hide file tree
Showing 44 changed files with 2,115 additions and 323 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@
/projects/*/sdkconfig@*
/projects/*/sdkconfig.old
/projects/*/build/

builds/
debug/
42 changes: 38 additions & 4 deletions components/leds/include/leds_status.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,30 @@ struct leds_limit_status {
unsigned output; /* Limited LED power output */
};

/*
* Get power usage before configured limits.
*
* @return 0.0 .. 1.0
* 0.0 -> all off
* 1.0 -> maximum power
*/
static inline float leds_limit_status_power(const struct leds_limit_status *status)
{
if (status->power && status->count) {
return (float) status->power / (float) status->count;
} else {
return 0.0f;
}
}

/*
* Get power limit configured.
*
* @return 0.0 .. 1.0
* 0.0 -> maximum power limit
* 1.0 -> no power limit
*/
static inline float leds_limit_status_configured(const struct leds_limit_status *status)
static inline float leds_limit_status_limit(const struct leds_limit_status *status)
{
if (status->limit && status->count) {
return (float) status->limit / (float) status->count;
Expand All @@ -33,7 +49,7 @@ static inline float leds_limit_status_configured(const struct leds_limit_status
* 1.0 -> at power limit
* >1.0 -> power limiting active
*/
static inline float leds_limit_status_utilization(const struct leds_limit_status *status)
static inline float leds_limit_status_util(const struct leds_limit_status *status)
{
if (status->limit) {
return (float) status->power / (float) status->limit;
Expand All @@ -43,19 +59,37 @@ static inline float leds_limit_status_utilization(const struct leds_limit_status
}

/*
* Get power limit applied.
* Get applied output power limit.
*
* This is applied using integer math internally, the floating point value is an approximation.
*
* @return 0.0 .. 1.0, with 1.0 meaning power is not being limited and numbers closer to 0.0 meaning more power limiting is being applied.
*/
static inline float leds_limit_status_active(const struct leds_limit_status *status)
static inline float leds_limit_status_applied(const struct leds_limit_status *status)
{
if (status->power) {
return (float) status->output / (float) status->power;
} else {
return 1.0f;
}

}
/*
* Get output power used.
*
* This is applied using integer math internally, the floating point value is an approximation.
*
* @return 0.0 .. 1.0
* 0.0 -> all LEDs are off, minimum output power
* 1.0 -> at power limit
*/
static inline float leds_limit_status_output(const struct leds_limit_status *status)
{
if (status->limit) {
return (float) status->output / (float) status->limit;
} else {
return 0.0f;
}
}

void leds_get_limit_total_status(struct leds *leds, struct leds_limit_status *total_status);
Expand Down
10 changes: 6 additions & 4 deletions main/artnet_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,18 @@ int artnet_cmd_info(int argc, char **argv, void *ctx)
for (int i = 0; i < inputs_size && i < ARTNET_INPUTS_MAX; i++) {
struct artnet_input_options *options = &artnet_input_options[i];
struct artnet_input_state state;
TickType_t tick = xTaskGetTickCount();

if ((err = artnet_get_input_state(artnet, i, &state))) {
LOG_ERROR("artnet_get_input_state");
continue;
}

printf("\t%2d: port=%1d index=%3u @ net %3u subnet %2u universe %2u: len %3u\n", i,
printf("\t%2d: port=%1d index=%3u @ net %3u subnet %2u universe %2u: len %3u @ %d ms\n", i,
options->port, options->index,
artnet_address_net(options->address), artnet_address_subnet(options->address), artnet_address_universe(options->address),
state.len
state.len,
state.tick ? (tick - state.tick) / portTICK_RATE_MS : 0
);
}

Expand All @@ -75,15 +77,15 @@ int artnet_cmd_info(int argc, char **argv, void *ctx)
continue;
}

printf("\t%2d: port=%1d index=%3u @ net %3u subnet %2u universe %2u -> %16.16s[%3u]: seq %3u @ %d ticks\n", i,
printf("\t%2d: port=%1d index=%3u @ net %3u subnet %2u universe %2u -> %16.16s[%3u]: seq %3u @ %d ms\n", i,
options->port, options->index,
artnet_address_net(options->address),
artnet_address_subnet(options->address),
artnet_address_universe(options->address),
options->name,
options->index,
state.seq,
state.tick ? tick - state.tick : 0
state.tick ? (tick - state.tick) * portTICK_RATE_MS : 0
);
}

Expand Down
78 changes: 74 additions & 4 deletions main/artnet_http.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@
#include <logging.h>
#include <json.h>

#define TICK_MS(current_tick, tick) (tick ? (current_tick - tick) * portTICK_RATE_MS : 0)

static int artnet_api_write_input_object(struct json_writer *w, const struct artnet_input_options *options, const struct artnet_input_state *state)
{
TickType_t tick = xTaskGetTickCount();

return (
JSON_WRITE_MEMBER_UINT(w, "port", options->port)
|| JSON_WRITE_MEMBER_UINT(w, "index", options->index)
Expand All @@ -19,13 +23,15 @@ static int artnet_api_write_input_object(struct json_writer *w, const struct art
|| JSON_WRITE_MEMBER_UINT(w, "universe", artnet_address_universe(options->address))
|| JSON_WRITE_MEMBER_OBJECT(w, "state",
JSON_WRITE_MEMBER_UINT(w, "tick", state->tick)
|| JSON_WRITE_MEMBER_UINT(w, "tick_ms", TICK_MS(tick, state->tick))
|| JSON_WRITE_MEMBER_UINT(w, "len", state->len)
)
);
}

static int artnet_api_write_inputs_array(struct json_writer *w)
static int artnet_api_write_inputs_array(struct json_writer *w, void *ctx)
{
struct artnet *artnet = ctx;
struct artnet_input_options options;
struct artnet_input_state state;
int err;
Expand All @@ -50,6 +56,8 @@ static int artnet_api_write_inputs_array(struct json_writer *w)

static int artnet_api_write_output_object(struct json_writer *w, const struct artnet_output_options *options, const struct artnet_output_state *state)
{
TickType_t tick = xTaskGetTickCount();

return (
JSON_WRITE_MEMBER_UINT(w, "port", options->port)
|| JSON_WRITE_MEMBER_UINT(w, "index", options->index)
Expand All @@ -59,14 +67,16 @@ static int artnet_api_write_output_object(struct json_writer *w, const struct ar
|| JSON_WRITE_MEMBER_UINT(w, "universe", artnet_address_universe(options->address))
|| JSON_WRITE_MEMBER_OBJECT(w, "state",
JSON_WRITE_MEMBER_UINT(w, "tick", state->tick)
|| JSON_WRITE_MEMBER_UINT(w, "tick_ms", TICK_MS(tick, state->tick))
|| JSON_WRITE_MEMBER_UINT(w, "seq", state->seq)
)
);
}


static int artnet_api_write_outputs_array(struct json_writer *w)
static int artnet_api_write_outputs_array(struct json_writer *w, void *ctx)
{
struct artnet *artnet = ctx;
struct artnet_output_options options;
struct artnet_output_state state;
int err;
Expand All @@ -89,6 +99,20 @@ static int artnet_api_write_outputs_array(struct json_writer *w)
return 0;
}

static int artnet_api_write_inputs(struct json_writer *w, void *ctx)
{
struct artnet *artnet = ctx;

return JSON_WRITE_ARRAY(w, artnet_api_write_inputs_array(w, artnet));
}

static int artnet_api_write_outputs(struct json_writer *w, void *ctx)
{
struct artnet *artnet = ctx;

return JSON_WRITE_ARRAY(w, artnet_api_write_outputs_array(w, artnet));
}

static int artnet_api_write(struct json_writer *w, void *ctx)
{
struct artnet *artnet = ctx;
Expand Down Expand Up @@ -118,8 +142,8 @@ static int artnet_api_write(struct json_writer *w, void *ctx)
|| JSON_WRITE_MEMBER_STRING(w, "short_name", options.metadata.short_name)
|| JSON_WRITE_MEMBER_STRING(w, "long_name", options.metadata.long_name)
)
|| JSON_WRITE_MEMBER_ARRAY(w, "inputs", artnet_api_write_inputs_array(w))
|| JSON_WRITE_MEMBER_ARRAY(w, "outputs", artnet_api_write_outputs_array(w))
|| JSON_WRITE_MEMBER_ARRAY(w, "inputs", artnet_api_write_inputs_array(w, artnet))
|| JSON_WRITE_MEMBER_ARRAY(w, "outputs", artnet_api_write_outputs_array(w, artnet))
);
}

Expand All @@ -144,3 +168,49 @@ int artnet_api_handler(struct http_request *request, struct http_response *respo

return 0;
}

int artnet_api_inputs_handler(struct http_request *request, struct http_response *response, void *ctx)
{
int err;

if ((err = http_request_headers(request, NULL))) {
LOG_WARN("http_request_headers");
return err;
}

if (!artnet) {
// disabled
return HTTP_NO_CONTENT;
}

if ((err = write_http_response_json(response, artnet_api_write_inputs, artnet))) {
LOG_WARN("write_http_response_json -> artnet_api_write_inputs");
return err;
}

return 0;

}

int artnet_api_outputs_handler(struct http_request *request, struct http_response *response, void *ctx)
{
int err;

if ((err = http_request_headers(request, NULL))) {
LOG_WARN("http_request_headers");
return err;
}

if (!artnet) {
// disabled
return HTTP_NO_CONTENT;
}

if ((err = write_http_response_json(response, artnet_api_write_outputs, artnet))) {
LOG_WARN("write_http_response_json -> artnet_api_write_outputs");
return err;
}

return 0;

}
8 changes: 8 additions & 0 deletions main/http_routes.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,20 @@ const struct http_route http_routes[] = {

/* artnet_http.c */
{ "GET", "api/artnet", artnet_api_handler, NULL },
{ "GET", "api/artnet/inputs", artnet_api_inputs_handler, NULL },
{ "GET", "api/artnet/outputs", artnet_api_outputs_handler, NULL },

/* leds_http.c */
{ "GET", "api/leds", leds_api_get, NULL },
{ "GET", "api/leds/status", leds_api_get_status, NULL },
{ "POST", "api/leds", leds_api_post, NULL },

{ "GET", "api/leds/test", leds_api_test_get, NULL },
{ "POST", "api/leds/test", leds_api_test_post, NULL },

/* user_http.c */
{ "GET", "api/status", user_api_get_status, NULL },
{ "POST", "api/button", user_api_post_button, NULL },

{}
};
7 changes: 7 additions & 0 deletions main/http_routes.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,17 @@ int wifi_api_scan_handler(struct http_request *request, struct http_response *re

/* artnet_http.c */
int artnet_api_handler(struct http_request *request, struct http_response *response, void *ctx);
int artnet_api_inputs_handler(struct http_request *request, struct http_response *response, void *ctx);
int artnet_api_outputs_handler(struct http_request *request, struct http_response *response, void *ctx);

/* leds_http.c */
int leds_api_get(struct http_request *request, struct http_response *response, void *ctx);
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);

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);

/* 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);
6 changes: 4 additions & 2 deletions main/leds.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ void clear_leds_active(struct leds_state *state)
clear_atx_psu_bit(ATX_PSU_BIT_LEDS1 + state->index);
}

int update_leds(struct leds_state *state)
int update_leds(struct leds_state *state, enum user_activity leds_activity)
{
int err;

Expand All @@ -192,7 +192,9 @@ int update_leds(struct leds_state *state)
return err;
}

user_activity(USER_ACTIVITY_LEDS);
if (leds_activity) {
user_activity(leds_activity);
}

if ((err = leds_tx(state->leds))) {
LOG_ERROR("leds_tx");
Expand Down
14 changes: 11 additions & 3 deletions main/leds_artnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ int leds_artnet_update(struct leds_state *state, EventBits_t event_bits)

bool sync_mode = false;
bool update = false;
bool timeout = false;

if (state->test) {
if (data || sync) {
Expand Down Expand Up @@ -341,15 +342,16 @@ int leds_artnet_update(struct leds_state *state, EventBits_t event_bits)

// timeouts
if (data || sync) {
state->artnet->dmx_tick = xTaskGetTickCount();
leds_artnet_timeout_reset(state);
} else if (state->artnet->timeout_tick) {
if (xTaskGetTickCount() >= state->artnet->timeout_tick) {
timeout = true;

if (leds_artnet_timeout(state)) {
LOG_WARN("leds_artnet_timeout");
}

update = true;

// repeat
leds_artnet_timeout_reset(state);
}
Expand All @@ -359,7 +361,13 @@ int leds_artnet_update(struct leds_state *state, EventBits_t event_bits)
leds_artnet_sync_reset(state);
}

return update;
if (timeout) {
return LEDS_ARTNET_UPDATE_TIMEOUT;
} else if (update) {
return LEDS_ARTNET_UPDATE;
} else {
return 0;
}
}

int init_leds_artnet(struct leds_state *state, int index, const struct leds_config *config)
Expand Down
4 changes: 4 additions & 0 deletions main/leds_artnet.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ struct leds_artnet_state {
unsigned universe_count;
unsigned universe_leds_count;

TickType_t dmx_tick; // last dmx frame
struct artnet_dmx dmx;
struct artnet_output **outputs;

Expand All @@ -37,3 +38,6 @@ bool leds_artnet_active(struct leds_state *state, EventBits_t event_bits);

/* Update LEDs from artnet outputs */
int leds_artnet_update(struct leds_state *state, EventBits_t event_bits);

#define LEDS_ARTNET_UPDATE 1
#define LEDS_ARTNET_UPDATE_TIMEOUT 2
Loading

0 comments on commit 3dbb8a1

Please sign in to comment.