Mercurial > louis > mq > lightsd
changeset 485:0062162318d2
WIP on power transition, keeps getting better, I think I'm gonna change apply_cnt to count the number of periods left instead of going up
author | Louis Opter <kalessin@kalessin.fr> |
---|---|
date | Sat, 09 Jul 2016 19:17:07 -0700 |
parents | 8f5a1a4862dc |
children | 5afd4568a2f6 |
files | add_power_transition.patch ask_for_remote_dest_before_running_hg_out.patch series |
diffstat | 3 files changed, 87 insertions(+), 55 deletions(-) [+] |
line wrap: on
line diff
--- a/add_power_transition.patch Sat Jul 09 13:23:18 2016 -0700 +++ b/add_power_transition.patch Sat Jul 09 19:17:07 2016 -0700 @@ -1,5 +1,5 @@ # HG changeset patch -# Parent 401bd90c164a23e6b23aa4842135d4ad142894b2 +# Parent b711b804c1c54e31174c68fc13e3227967f16786 Add a transition argument to the power functions Unlike LIFX's implementation, lightsd will properly get the bulbs to @@ -59,7 +59,7 @@ new file mode 100644 --- /dev/null +++ b/core/effect.c -@@ -0,0 +1,242 @@ +@@ -0,0 +1,243 @@ +// Copyright (c) 2015, Louis Opter <kalessin@kalessin.fr> +// +// This file is part of lighstd. @@ -121,7 +121,8 @@ + struct lgtd_effect *effect = (struct lgtd_effect *)ctx.as_ptr; + if (effect->duration_cb) { + lgtd_time_mono_t now = lgtd_time_monotonic_msecs(); -+ if (effect->ends_at - now < LGTD_EFFECT_STALE_THRESHOLD_MS) { ++ if (effect->ends_at < now || // let's not go negative with unsigned ints ++ effect->ends_at - now < LGTD_EFFECT_STALE_THRESHOLD_MS) { + lgtd_info( + "calling duration callback for effect %s, id=%p", + effect->name, effect @@ -131,8 +132,8 @@ + lgtd_warnx( + "not calling duration callback for stale effect %s created " + "%jums ago, id=%p, duration=%jums", -+ effect->name, now - effect->created_at, effect, -+ effect->ends_at - effect->created_at ++ effect->name, (uintmax_t)(now - effect->created_at), effect, ++ (uintmax_t)(effect->ends_at - effect->created_at) + ); + } + } @@ -150,21 +151,21 @@ + if (effect->ends_at && now > effect->ends_at) { + // check if the effect is stale (e.g: the computer went to sleep) + // and stop it if it is the case: -+ if (effect->ends_at - now > LGTD_EFFECT_STALE_THRESHOLD_MS) { ++ if (now - effect->ends_at > LGTD_EFFECT_STALE_THRESHOLD_MS) { + lgtd_warnx( + "stopping stale periodic effect %s created %jums ago, " + "id=%p, duration=%jums", -+ effect->name, now - effect->created_at, effect, -+ effect->ends_at - effect->created_at ++ effect->name, (uintmax_t)(now - effect->created_at), effect, ++ (uintmax_t)(effect->ends_at - effect->created_at) + ); + lgtd_effect_stop(effect); + return; + } -+ // if there is a duration callback pending then stop the periodic -+ // timer but apply the effect one last time (we're not stale yet). ++ // if a duration callback pending then just stop the periodic timer: + if (event_pending(effect->duration_timer->event, EV_TIMEOUT, NULL)) { + lgtd_timer_stop(effect->timer); + effect->timer = NULL; ++ return; + } + } + @@ -246,13 +247,13 @@ + lgtd_info( + "starting effect %s, id=%p, created_at=%jums, " + "tick=%dms, duration=%dms", -+ name, effect, effect->created_at, timer_ms, duration ++ name, effect, (uintmax_t)effect->created_at, timer_ms, duration + ); + } else { + lgtd_info( + "starting effect %s, id=%p, created_a=%jums, " + "tick=%dms, duration=infinite", -+ name, effect, effect->created_at, timer_ms ++ name, effect, (uintmax_t)effect->created_at, timer_ms + ); + } + } else { // finite or instant effect @@ -260,13 +261,13 @@ + lgtd_info( + "starting effect %s, id=%p, created_at=%jums, " + "duration=%dms", -+ name, effect, effect->created_at, duration ++ name, effect, (uintmax_t)effect->created_at, duration + ); + } else { + lgtd_info( + "starting effect %s, id=%p, created_at=%jums, " + "duration=instant", -+ name, effect, effect->created_at ++ name, effect, (uintmax_t)effect->created_at + ); + } + if (effect->apply_cb) { @@ -306,7 +307,7 @@ new file mode 100644 --- /dev/null +++ b/core/effect.h -@@ -0,0 +1,59 @@ +@@ -0,0 +1,61 @@ +// Copyright (c) 2015, Louis Opter <kalessin@kalessin.fr> +// +// This file is part of lighstd. @@ -340,6 +341,8 @@ + void (*duration_cb)(const struct lgtd_effect *); + struct lgtd_timer *timer; + void (*apply_cb)(const struct lgtd_effect *); ++ // number of times apply_cb has been called (therefore this will be 0 the ++ // first time apply_cb is called): + uint32_t apply_cnt; + union lgtd_effect_ctx ctx; +}; @@ -940,22 +943,13 @@ struct lgtd_timer * lgtd_timer_start(int flags, int ms, -@@ -60,6 +72,8 @@ - timer->ctx = ctx; - LIST_INSERT_HEAD(&lgtd_timers, timer, link); - -+ enum lgtd_event_priority priority = lgtd_timer_flags_to_priority(flags); -+ lgtd_info("timer priority = %u", priority); - struct timeval tv = LGTD_MSECS_TO_TIMEVAL(ms); - timer->event = event_new( - lgtd_ev_base, -@@ -68,7 +82,9 @@ +@@ -68,7 +80,9 @@ lgtd_timer_callback, timer ); - if (!timer->event || evtimer_add(timer->event, &tv)) { + if (!timer->event -+ || event_priority_set(timer->event, priority) ++ || event_priority_set(timer->event, lgtd_timer_flags_to_priority(flags)) + || evtimer_add(timer->event, &tv)) { LIST_REMOVE(timer, link); if (timer->event) { @@ -1063,7 +1057,7 @@ new file mode 100644 --- /dev/null +++ b/effects/power_transition.c -@@ -0,0 +1,333 @@ +@@ -0,0 +1,345 @@ +// Copyright (c) 2015, Louis Opter <kalessin@kalessin.fr> +// +// This file is part of lighstd. @@ -1121,17 +1115,16 @@ +} + +static struct lgtd_lifx_bulb * -+lgtd_effect_power_transition_off_possibly_get_bulb(uint8_t *device_id) ++lgtd_effect_power_transition_possibly_get_bulb(uint8_t *device_id) +{ + assert(device_id); + + struct lgtd_lifx_bulb *bulb = lgtd_lifx_bulb_get(device_id); + if (!bulb) { + char addr[LGTD_LIFX_ADDR_STRLEN]; -+ LGTD_IEEE8023MACTOA(device_id, addr); + lgtd_warnx( -+ "bulb %s is unavailable: can't restore its original brightness " -+ "at the end of a power_off transition", addr ++ "bulb %s is unavailable: can't apply a power transition on it", ++ LGTD_IEEE8023MACTOA(device_id, addr) + ); + } + return bulb; @@ -1143,16 +1136,18 @@ +{ + assert(effect); + ++ lgtd_info( ++ "now = %ju, effect->ends_at=%ju", ++ (uintmax_t)lgtd_time_monotonic_msecs(), (uintmax_t)effect->ends_at ++ ); ++ + struct lgtd_effect_power_transition_ctx *ctx = effect->ctx.as_ptr; -+ lgtd_info( -+ "now = %ju, end_time=%ju", lgtd_time_monotonic_msecs(), ctx->end_time -+ ); + + struct lgtd_effect_power_transition_target *target; + SLIST_FOREACH(target, &ctx->targets, link) { + struct lgtd_lifx_bulb *bulb; + uint8_t *device_id = target->device_id; -+ bulb = lgtd_effect_power_transition_off_possibly_get_bulb(device_id); ++ bulb = lgtd_effect_power_transition_possibly_get_bulb(device_id); + if (bulb) { // restore the original brightness + struct lgtd_lifx_packet_light_color pkt_light_color = { + .hue = bulb->state.hue, @@ -1186,7 +1181,7 @@ + // condition: + struct lgtd_lifx_bulb *bulb; + uint8_t *device_id = target->device_id; -+ bulb = lgtd_effect_power_transition_off_possibly_get_bulb(device_id); ++ bulb = lgtd_effect_power_transition_possibly_get_bulb(device_id); + if (bulb) { + struct lgtd_lifx_packet_light_color pkt = { + .hue = bulb->state.hue, @@ -1211,7 +1206,7 @@ + SLIST_FOREACH(target, targets, link) { + struct lgtd_lifx_bulb *bulb; + uint8_t *device_id = target->device_id; -+ bulb = lgtd_effect_power_transition_off_possibly_get_bulb(device_id); ++ bulb = lgtd_effect_power_transition_possibly_get_bulb(device_id); + if (bulb) { + struct lgtd_lifx_packet_power pkt = { + .power = LGTD_LIFX_POWER_OFF @@ -1227,18 +1222,20 @@ + assert(effect); + + struct lgtd_effect_power_transition_ctx *ctx = effect->ctx.as_ptr; ++ + lgtd_time_mono_t now = lgtd_time_monotonic_msecs(); -+ lgtd_time_mono_t next_tick = ( -+ now + LGTD_EFFECT_POWER_TRANSITION_TIMER_MS ++ lgtd_info( ++ "now = %ju, next_tick = %ju, ends_at=%ju, apply_cnt=%d/%d", ++ (uintmax_t)now, (uintmax_t)now + LGTD_EFFECT_POWER_TRANSITION_TIMER_MS, ++ (uintmax_t)ctx->ends_at, effect->apply_cnt, ctx->periods + ); + -+ lgtd_info("now = %ju, next_tick = %ju, end_time=%ju", now, next_tick, ctx->end_time); -+ if (next_tick >= ctx->end_time) { ++ if (effect->apply_cnt >= ctx->periods) { + lgtd_effect_power_transition_off_power_off(&ctx->targets); + return; + } + lgtd_effect_power_transition_off_set_brightness_to_zero( -+ &ctx->targets, ctx->end_time - lgtd_time_monotonic_msecs() ++ &ctx->targets, ctx->ends_at - lgtd_time_monotonic_msecs() + ); +} + @@ -1247,10 +1244,12 @@ +{ + assert(effect); + ++ lgtd_info( ++ "now = %ju, effect->ends_at=%ju", ++ (uintmax_t)lgtd_time_monotonic_msecs(), (uintmax_t)effect->ends_at ++ ); ++ + struct lgtd_effect_power_transition_ctx *ctx = effect->ctx.as_ptr; -+ lgtd_info( -+ "now = %ju, end_time=%ju", lgtd_time_monotonic_msecs(), ctx->end_time -+ ); + lgtd_effect_power_transition_clear_target_list(&ctx->targets); + free(ctx); +} @@ -1262,19 +1261,21 @@ + + struct lgtd_effect_power_transition_ctx *ctx = effect->ctx.as_ptr; + uint32_t transition = LGTD_MIN( -+ UINT32_MAX, ctx->end_time - lgtd_time_monotonic_msecs() ++ UINT32_MAX, ctx->ends_at - lgtd_time_monotonic_msecs() + ); + + lgtd_time_mono_t now = lgtd_time_monotonic_msecs(); -+ lgtd_time_mono_t next_tick = ( -+ now + LGTD_EFFECT_POWER_TRANSITION_TIMER_MS ++ lgtd_info( ++ "now = %ju, next_tick = %ju, ends_at=%ju", ++ (uintmax_t)now, (uintmax_t)now + LGTD_EFFECT_POWER_TRANSITION_TIMER_MS, ++ (uintmax_t)ctx->ends_at + ); -+ lgtd_info("now = %ju, next_tick = %ju, end_time=%ju", now, next_tick, ctx->end_time); ++ + struct lgtd_effect_power_transition_target *target; + SLIST_FOREACH(target, &ctx->targets, link) { + struct lgtd_lifx_bulb *bulb; + uint8_t *device_id = target->device_id; -+ bulb = lgtd_effect_power_transition_off_possibly_get_bulb(device_id); ++ bulb = lgtd_effect_power_transition_possibly_get_bulb(device_id); + if (!bulb) { + continue; + } @@ -1357,7 +1358,12 @@ + const char *name = NULL; + void (*duration_cb)(const struct lgtd_effect *) = NULL; + void (*apply_cb)(const struct lgtd_effect *) = NULL; -+ lgtd_time_mono_t end_time = duration; ++ int timer_ms = LGTD_EFFECT_POWER_TRANSITION_TIMER_MS; ++ ctx->periods = duration / timer_ms; ++ // align the timer with the duration: ++ timer_ms += (duration % timer_ms) / ctx->periods; ++ // save the duration before it gets skewed for the power off transition: ++ ctx->ends_at = duration; + if (state == LGTD_EFFECT_POWER_TRANSITION_OFF) { + name = "power_transition[off]"; + apply_cb = lgtd_effect_power_transition_off_apply_callback; @@ -1375,12 +1381,12 @@ + duration, + duration_cb, + LGTD_TIMER_ACTIVATE_NOW|LGTD_TIMER_PERSISTENT, -+ LGTD_EFFECT_POWER_TRANSITION_TIMER_MS, ++ timer_ms, + apply_cb, + effect_ctx + ); + if (effect) { -+ ctx->end_time = effect->created_at + end_time; ++ ctx->ends_at += effect->created_at; + return effect; + } + @@ -1401,7 +1407,7 @@ new file mode 100644 --- /dev/null +++ b/effects/power_transition.h -@@ -0,0 +1,53 @@ +@@ -0,0 +1,55 @@ +// Copyright (c) 2015, Louis Opter <kalessin@kalessin.fr> +// +// This file is part of lighstd. @@ -1447,9 +1453,11 @@ + +struct lgtd_effect_power_transition_ctx { + struct lgtd_effect_power_transition_target_list targets; ++ // how many times the apply_cb will be called ++ uint32_t periods; + // This doesn't include the delay to restore the light color after a + // power off: -+ lgtd_time_mono_t end_time; ++ lgtd_time_mono_t ends_at; +}; + +const struct lgtd_effect *lgtd_effect_power_transition(const struct lgtd_proto_target_list *,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ask_for_remote_dest_before_running_hg_out.patch Sat Jul 09 19:17:07 2016 -0700 @@ -0,0 +1,23 @@ +# HG changeset patch +# Parent f3edec018825871eb7b80631f3c4411a5e349b7c +Ask for the remote before checking for pending changes in release.py + +diff --git a/dist/release.py.in b/dist/release.py.in +--- a/dist/release.py.in ++++ b/dist/release.py.in +@@ -364,11 +364,11 @@ + "commit", "-m", "Back to development, {}".format(next_version) + ]) + +- subprocess.check_call([HG_EXECUTABLE, "-R", LIGHTSD_SOURCE_DIR, "out"]) ++ remote = click.prompt("Confirm the remote destination", default="default") ++ subprocess.check_call([ ++ HG_EXECUTABLE, "-R", LIGHTSD_SOURCE_DIR, "out", remote ++ ]) + if click.confirm("Are you ready to push those commit?"): +- remote = click.prompt( +- "Confirm the remote destination", default="default", +- ) + subprocess.check_call([ + HG_EXECUTABLE, "-R", LIGHTSD_SOURCE_DIR, "push", remote + ])