Very aggressive power management?

I’ve recently noticed that my LEDs turn off after 10 seconds of disuse. This is a relatively new change, but I can’t say for certain how new—it could have been going for months, since I rarely see my LEDs (my halves are mounted vertically). I do have host power management set up, but I haven’t changed anything there since I first wrote it:

void hostPowerManagementEventHandler(
    kaleidoscope::plugin::HostPowerManagement::Event event) {
  switch (event) {
  case kaleidoscope::plugin::HostPowerManagement::Suspend:
  case kaleidoscope::plugin::HostPowerManagement::Sleep:
    LEDControl.set_all_leds_to({0, 0, 0});
    LEDControl.syncLeds();
    LEDControl.paused = true;
    break;
  case kaleidoscope::plugin::HostPowerManagement::Resume:
    LEDControl.paused = false;
    LEDControl.refreshAll();
    break;
  }
}

Running macOS Mojave 10.14.5.

Do you have the IdleLEDs plugin enabled, by any chance? That turns off LEDs after about 10 seconds of idleness by default, which is pretty much the symptom you described.

Whoops, I do have that enabled. I totally forgot about it. But now that I remember it, I could have sworn it defaulted to 600 seconds (10 minutes).

EDIT: From the documentation:

The amount of time that can pass without a single key being pressed, before
the plugin considers the keyboard idle, and turns the LEDs off.

Defaults to 600 seconds (10 minutes).

Yeah, it is supposed to default to 10 minutes (my bad). It might be broken and default to 10 seconds instead, that’s also a possibility. Or you may have set it to a shorter interval. Try turning the plugin off, and see if LEDs still turn off!

Disabling the plugin fixes it. I just took a look at IdleLEDs.cpp. idle_time_limit still defaults to 600, and I never change it anywhere in my sketch. Also:

Kaleidoscope.hasTimeExpired(start_time_, uint32_t(idle_time_limit * 1000)))

That at least looks correct to me. Is there possibly a bug in hasTimeExpired?

I’m pretty sure I know what’s wrong. idle_time_limit is a 16-bit integer, and when it’s multiplied by 1000, it’s still a 16-bit integer, but 600,000 gets truncated to 10,176, which is slightly more than ten seconds. The close paren for the type conversion needs to come before the multiplication:

(uint32_t(idle_time_limit) * 1000)

Sorry about that. I must have only tested it with a small value.

1 Like

Funny. I wondered if the problem might be along those lines, but then I thought, “Oh, wait, it’d max out at 65535, so it should still go for over a minute.” I see now where I messed up :slight_smile:

By the way, would it be more efficient to store the time limit in terms of milliseconds, rather than recalculating every cycle? Or does the compiler optimize that automatically? (Or does it just not matter?)

It would probably be better to store it in milliseconds, and provide a class method for setting the value, which converts from the user-meaningful seconds to the internal millisecond representation.