Skip to content

Commit

Permalink
Make colors configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
caksoylar committed Oct 21, 2024
1 parent 0e6817e commit ef0b6c0
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 44 deletions.
76 changes: 65 additions & 11 deletions Kconfig
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# Color definitions to use with color settings
COLOR_BLACK := 0 # no blink
COLOR_RED := 1
COLOR_GREEN := 2
COLOR_YELLOW := 3
COLOR_BLUE := 4
COLOR_MAGENTA := 5
COLOR_CYAN := 6
COLOR_WHITE := 7

config RGBLED_WIDGET
bool "Enable RGB LED widget for showing battery and output status"

Expand All @@ -6,18 +16,16 @@ if RGBLED_WIDGET
config LED
default y

config RGBLED_WIDGET_BATTERY_BLINK_MS
int "Duration of battery level blink in ms"
default 2000

config RGBLED_WIDGET_OUTPUT_BLINK_MS
int "Duration of BLE connection status blink in ms"
default 1000

config RGBLED_WIDGET_INTERVAL_MS
int "Minimum wait duration between two blinks in ms"
default 500

# Battery level settings

config RGBLED_WIDGET_BATTERY_BLINK_MS
int "Duration of battery level blink in ms"
default 2000

config RGBLED_WIDGET_BATTERY_LEVEL_HIGH
int "High battery level percentage"
default 80
Expand All @@ -30,21 +38,67 @@ config RGBLED_WIDGET_BATTERY_LEVEL_CRITICAL
int "Critical battery level percentage"
default 5

config RGBLED_WIDGET_BATTERY_COLOR_HIGH
int "Color for high battery level (above LEVEL_HIGH)"
range 0 7
default $(COLOR_GREEN)

config RGBLED_WIDGET_BATTERY_COLOR_MEDIUM
int "Color for medium battery level (between LEVEL_LOW and LEVEL_HIGH)"
range 0 7
default $(COLOR_YELLOW)

config RGBLED_WIDGET_BATTERY_COLOR_LOW
int "Color for low battery level (below LEVEL_LOW)"
range 0 7
default $(COLOR_RED)

config RGBLED_WIDGET_BATTERY_COLOR_CRITICAL
int "Color for critical battery level (below LEVEL_CRITICAL)"
range 0 7
default $(COLOR_RED)

# Connectivity indicator settings
config RGBLED_WIDGET_CONN_BLINK_MS
int "Duration of BLE connection status blink in ms"
default RGBLED_WIDGET_OUTPUT_BLINK_MS

config RGBLED_WIDGET_OUTPUT_BLINK_MS # DEPRECATED, do not use
int
default 1000

config RGBLED_WIDGET_CONN_COLOR_CONNECTED
int "Color for connected BLE connection status"
range 0 7
default $(COLOR_BLUE)

config RGBLED_WIDGET_CONN_COLOR_ADVERTISING
int "Color for advertising BLE connection status"
range 0 7
default $(COLOR_YELLOW)

config RGBLED_WIDGET_CONN_COLOR_DISCONNECTED
int "Color for disconnected BLE connection status"
range 0 7
default $(COLOR_RED)

# Layer indicator settings
config RGBLED_WIDGET_SHOW_LAYER_CHANGE
bool "Indicate highest active layer on each layer change with a sequence of blinks"

config RGBLED_WIDGET_LAYER_BLINK_MS
int "Blink and wait duration for layer indicator"
default 100

if RGBLED_WIDGET_SHOW_LAYER_CHANGE
config RGBLED_WIDGET_LAYER_COLOR
int "Color to use for layer indicator"
range 0 7
default $(COLOR_CYAN)

config RGBLED_WIDGET_LAYER_DEBOUNCE_MS
int "Wait duration after a layer change before showing the highest active layer"
default 100

endif # RGBLED_WIDGET_SHOW_LAYER_CHANGE

endif # RGBLED_WIDGET

DT_COMPAT_ZMK_BEHAVIOR_RGBLED_WIDGET := zmk,behavior-rgbled-widget
Expand Down
71 changes: 38 additions & 33 deletions src/widget.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,23 @@ static const uint8_t rgb_idx[] = {DT_NODE_CHILD_IDX(DT_ALIAS(led_red)),
DT_NODE_CHILD_IDX(DT_ALIAS(led_green)),
DT_NODE_CHILD_IDX(DT_ALIAS(led_blue))};

// color values as specified by an RGB bitfield
enum led_color_t {
LED_BLACK, // 0b000
LED_RED, // 0b001
LED_GREEN, // 0b010
LED_YELLOW, // 0b011
LED_BLUE, // 0b100
LED_MAGENTA, // 0b101
LED_CYAN, // 0b110
LED_WHITE // 0b111
};
// map from color values to names, for logging
static const char *color_names[] = {"black", "red", "green", "yellow",
"blue", "magenta", "cyan", "white"};
// log shorthands
#define LOG_CONN_CENTRAL(index, status, color_label) \
LOG_INF("Profile %d %s, blinking %s", index, status, \
color_names[CONFIG_RGBLED_WIDGET_CONN_COLOR_##color_label])
#define LOG_CONN_PERIPHERAL(status, color_label) \
LOG_INF("Peripheral %s, blinking %s", status, \
color_names[CONFIG_RGBLED_WIDGET_CONN_COLOR_##color_label])
#define LOG_BATTERY(battery_level, color_label) \
LOG_INF("Battery level %d, blinking %s", battery_level, \
color_names[CONFIG_RGBLED_WIDGET_BATTERY_COLOR_##color_label])

// a blink work item as specified by the color and duration
struct blink_item {
enum led_color_t color;
uint8_t color;
uint16_t duration_ms;
bool first_item;
uint16_t sleep_ms;
Expand All @@ -69,22 +71,22 @@ void indicate_connectivity(void) {
#if !IS_ENABLED(CONFIG_ZMK_SPLIT) || IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
uint8_t profile_index = zmk_ble_active_profile_index();
if (zmk_ble_active_profile_is_connected()) {
LOG_INF("Profile %d connected, blinking blue", profile_index);
blink.color = LED_BLUE;
LOG_CONN_CENTRAL(profile_index, "connected", CONNECTED);
blink.color = CONFIG_RGBLED_WIDGET_CONN_COLOR_CONNECTED;
} else if (zmk_ble_active_profile_is_open()) {
LOG_INF("Profile %d open, blinking yellow", profile_index);
blink.color = LED_YELLOW;
LOG_CONN_CENTRAL(profile_index, "open", ADVERTISING);
blink.color = CONFIG_RGBLED_WIDGET_CONN_COLOR_ADVERTISING;
} else {
LOG_INF("Profile %d not connected, blinking red", profile_index);
blink.color = LED_RED;
LOG_CONN_CENTRAL(profile_index, "not connected", DISCONNECTED);
blink.color = CONFIG_RGBLED_WIDGET_CONN_COLOR_DISCONNECTED;
}
#else
if (zmk_split_bt_peripheral_is_connected()) {
LOG_INF("Peripheral connected, blinking blue");
blink.color = LED_BLUE;
LOG_CONN_PERIPHERAL("connected", CONNECTED);
blink.color = CONFIG_RGBLED_WIDGET_CONN_COLOR_CONNECTED;
} else {
LOG_INF("Peripheral not connected, blinking red");
blink.color = LED_RED;
LOG_CONN_PERIPHERAL("not connected", DISCONNECTED);
blink.color = CONFIG_RGBLED_WIDGET_CONN_COLOR_DISCONNECTED;
}
#endif

Expand Down Expand Up @@ -121,16 +123,16 @@ void indicate_battery(void) {

if (battery_level == 0) {
LOG_INF("Battery level undetermined (zero), blinking magenta");
blink.color = LED_MAGENTA;
blink.color = 5;
} else if (battery_level >= CONFIG_RGBLED_WIDGET_BATTERY_LEVEL_HIGH) {
LOG_INF("Battery level %d, blinking green", battery_level);
blink.color = LED_GREEN;
LOG_BATTERY(battery_level, HIGH);
blink.color = CONFIG_RGBLED_WIDGET_BATTERY_COLOR_HIGH;
} else if (battery_level >= CONFIG_RGBLED_WIDGET_BATTERY_LEVEL_LOW) {
LOG_INF("Battery level %d, blinking yellow", battery_level);
blink.color = LED_YELLOW;
LOG_BATTERY(battery_level, MEDIUM);
blink.color = CONFIG_RGBLED_WIDGET_BATTERY_COLOR_MEDIUM;
} else {
LOG_INF("Battery level %d, blinking red", battery_level);
blink.color = LED_RED;
LOG_BATTERY(battery_level, LOW);
blink.color = CONFIG_RGBLED_WIDGET_BATTERY_COLOR_LOW;
}

k_msgq_put(&led_msgq, &blink, K_NO_WAIT);
Expand All @@ -145,10 +147,10 @@ static int led_battery_listener_cb(const zmk_event_t *eh) {
uint8_t battery_level = as_zmk_battery_state_changed(eh)->state_of_charge;

if (battery_level > 0 && battery_level <= CONFIG_RGBLED_WIDGET_BATTERY_LEVEL_CRITICAL) {
LOG_INF("Battery level %d, blinking red for critical", battery_level);
LOG_BATTERY(battery_level, CRITICAL);

struct blink_item blink = {.duration_ms = CONFIG_RGBLED_WIDGET_BATTERY_BLINK_MS,
.color = LED_RED};
.color = CONFIG_RGBLED_WIDGET_BATTERY_COLOR_CRITICAL};
k_msgq_put(&led_msgq, &blink, K_NO_WAIT);
}
return 0;
Expand All @@ -163,10 +165,13 @@ ZMK_SUBSCRIPTION(led_battery_listener, zmk_battery_state_changed);
void indicate_layer(void) {
uint8_t index = zmk_keymap_highest_layer_active();
static const struct blink_item blink = {.duration_ms = CONFIG_RGBLED_WIDGET_LAYER_BLINK_MS,
.color = LED_CYAN,
.color = CONFIG_RGBLED_WIDGET_LAYER_COLOR,
.sleep_ms = CONFIG_RGBLED_WIDGET_LAYER_BLINK_MS};
static const struct blink_item last_blink = {.duration_ms = CONFIG_RGBLED_WIDGET_LAYER_BLINK_MS,
.color = LED_CYAN};
.color = CONFIG_RGBLED_WIDGET_LAYER_COLOR};
LOG_INF("Blinking %d times %s for layer change", index,
color_names[CONFIG_RGBLED_WIDGET_LAYER_COLOR]);

for (int i = 0; i < index; i++) {
if (i < index - 1) {
k_msgq_put(&led_msgq, &blink, K_NO_WAIT);
Expand Down

0 comments on commit ef0b6c0

Please sign in to comment.