Keep a small slider where the finger left it while the light fades towards it (0.2.71)
A light group's lamps fade, Home Assistant reports every step, and the tile's slider followed each one: after a drag it jumped back to the old value and crept up. The Tile now holds the sent value (brightness, fan percent, volume) until Home Assistant reports within 3 % of it, reports the entity off, refuses, or reports once and stays quiet for 1.5 s; never longer than 8 s, and without any report the hold ends with the wait. A cover's position slider keeps following the blind. Firmware 0.2.60; host checks 17/17 on both boards. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -64,6 +64,50 @@ int main() {
|
||||
assert(!lamp.optimistic_tap);
|
||||
lamp.undo_optimistic(); assert(lamp.state=="off");
|
||||
|
||||
// A slider the finger let go stays put while the light fades towards it (firmware 0.2.60+).
|
||||
runtime_tiles::Tile group;
|
||||
group.entity="light.living_room"; group.received=true; group.state="on"; group.brightness=51; group.revision=rev("on");
|
||||
group.hold_slider(1000,204); group.begin(1000);
|
||||
assert(group.brightness==204); assert(group.slider_holding(1200));
|
||||
// The fade reports 80, 128, 180: each keeps the sent value in front, and each keeps the hold alive.
|
||||
for (float step : {80.0f, 128.0f, 180.0f}) {
|
||||
group.brightness=step; group.observe(rev("on")); group.slider_reported(1500+(int)step*10);
|
||||
assert(group.brightness==204); assert(group.slider_holding(1500+(int)step*10+1400));
|
||||
}
|
||||
// Within 3 % of the target the hold ends and the reported value shows.
|
||||
group.brightness=200; group.slider_reported(4000);
|
||||
assert(!std::isfinite(group.slider_sent)); assert(group.brightness==200);
|
||||
// A fan that only knows 33/66/100 reports 66 once and then stays quiet: after 1.5 s the slider follows it.
|
||||
runtime_tiles::Tile fan;
|
||||
fan.entity="fan.attic"; fan.received=true; fan.state="on"; fan.percentage=33; fan.revision=rev("on");
|
||||
fan.hold_slider(1000,50); fan.begin(1000);
|
||||
fan.percentage=66; fan.observe(rev("on")); fan.slider_reported(1400);
|
||||
assert(fan.percentage==50); assert(fan.slider_holding(2800)); assert(!fan.slider_holding(2900));
|
||||
fan.release_slider(); assert(fan.percentage==66); assert(!std::isfinite(fan.slider_sent));
|
||||
// No report at all: the hold ends with the wait, and what was there before comes back.
|
||||
runtime_tiles::Tile lone;
|
||||
lone.entity="light.lone"; lone.received=true; lone.state="on"; lone.brightness=100; lone.revision=rev("on");
|
||||
lone.hold_slider(1000,200); lone.begin(1000);
|
||||
assert(lone.slider_holding(3999)); assert(!lone.slider_holding(4000));
|
||||
lone.release_slider(); assert(lone.brightness==100);
|
||||
// "It worked" without a state (the value was already there) keeps it until the cap.
|
||||
lone.hold_slider(5000,200); lone.begin(5000); lone.answered_at=5400;
|
||||
assert(lone.slider_holding(9000)); assert(!lone.slider_holding(13000));
|
||||
// A slider on an off light lights the tile up at once; Home Assistant reporting it off ends the hold.
|
||||
runtime_tiles::Tile dark;
|
||||
dark.entity="light.dark"; dark.received=true; dark.state="off"; dark.brightness=NAN; dark.revision=rev("off");
|
||||
dark.hold_slider(1000,128); dark.begin(1000);
|
||||
assert(dark.state=="on"); assert(dark.brightness==128);
|
||||
dark.state="off"; dark.brightness=NAN; dark.observe(rev("off")); dark.slider_reported(1500);
|
||||
assert(!std::isfinite(dark.slider_sent)); assert(!std::isfinite(dark.brightness));
|
||||
// A refusal puts the reported value back.
|
||||
dark.state="on"; dark.brightness=40; dark.hold_slider(2000,128); dark.begin(2000);
|
||||
dark.refused_at=2500; assert(!dark.slider_holding(2600)); dark.release_slider(); assert(dark.brightness==40);
|
||||
// A cover's position slider follows the blind as it moves: no hold.
|
||||
runtime_tiles::Tile blind;
|
||||
blind.entity="cover.blind"; blind.received=true; blind.state="open"; blind.position=20;
|
||||
blind.hold_slider(1000,80); assert(!std::isfinite(blind.slider_sent)); assert(blind.position==20);
|
||||
|
||||
// The fingerprint follows state and attributes, and the streaming writer (what receive() hands to
|
||||
// ArduinoJson) gives the same value as hashing the joined text.
|
||||
assert(runtime_tiles::state_revision("on","{\"brightness\":255}")!=runtime_tiles::state_revision("on","{\"brightness\":254}"));
|
||||
|
||||
Reference in New Issue
Block a user