PlummersSoftwareLLC / NightDriverStrip

NightDriver client for ESP32

Home Page:https://plummerssoftwarellc.github.io/NightDriverStrip/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Web UI Bugs: reset doesn't reset + other cosmetic glitches

robertlipe opened this issue · comments

Bug report

The reset/restart button in the the web UI doesn't restart remaining count.

Problem
Prev and Next work as expected. I'd expec the 'reset' button to reset the remaining time on this effect. It just doesn't.

Steps

  1. Click (Why is this step needed? Why isn't 'home' 'home'?
  2. Click on next and prev a few times. Watch current effect cycle. This verifies that your clicking finger works. :-)
  3. Click on reset. Nothing visible changes. I'd expect counter to reset to the cumber on the left.

Example
It's not intermittent. It just doesn't seem to be hooked up.

Bonus points to the assignee of this bug for reconsidering if milliseconds really is the appropriate unit of measure to show (without units or a decimal place) and to accept for input on 'interval'. If you type '120' for interval, is it really because you wanted 8 changes per second?

Bonus Bonus bug (maybe this should be three reports...) if you set the interval to '1000', the 'time remaining' field flashes for a cycle or two, but decided it can't keep up and just displays a constant number. Seems it should blank or something. Or maybe we don't allow setting times below a second.

Bonus Bonus Bonue (OK, four reports) if you type a negative number (!) it sets the time to 2^32 - 10000. Time remaining then overlaps the "Previojs" button.

Notes
image

image

I aborted nothing. What are the other five errors?

TL;DR regarding the main report: the "reset" button behavior is the expected behavior.

The reset button is actually a "refresh" button. The interaction between the UI and the API is currently pull-only, which means that the interval timer updates and the tracking of what effect is playing are largely done in the browser. The actual state is pulled from the device API at some meaningful interval, i.e. seconds.
Specifically when the web UI browser tab is not shown, this means the device and the UI can/will get out of sync. The refresh button forces the UI to pull the current state of affairs from the device API, to resync what the UI is showing.

Issue #302 includes a few comments about the merits of adding (a) web socket(s) to the on-device web server implementation; one could be used to "push" on-device effect changes to the web UI. On top of that, issue #356 describes a feature that would absolutely require one.

As for the other points: I think setting the timer in milliseconds is indeed way too granular. Showing the countdown in some fraction of seconds may make sense, but maybe tens of seconds would be enough.
Setting the timeout in seconds would automatically address bug 3.

Bug 4 I'd have to look into, which I'm currently not able to. I'll try to remember to do so at a later time.

I am late to the party here @robertlipe Bug 1 and Bug 4 should be fixed in the main branch now. As of #431

@KeiranHines Just for my understanding: what's Bug 1 in your reference?

Ahh yes that wasn't clear at all.
Bug 1

Click (Why is this step needed? Why isn't 'home' 'home'?

and Bug 4

Bonus Bonus Bonue (OK, four reports) if you type a negative number (!) it sets the time to 2^32 - 10000. Time remaining then overlaps the "Previojs" button.

have been fixed.

Check, thanks for clarifying that!

The remaining time for an effect is determined by the back-end; the front-end should just report what the back-end is doing. When the effect changes, the "remaining time" at the back-end will always reset. If this is not reflected in the front-end, then that is a bug.

No, UpdateOTA does not force a sync of anything. A reboot triggered via the /reset endpoint does.

From the device's firmware perspective (i.e. what we control) the upload via serial is not manageable in any way. We don't get told and we don't get the chance to say "hang on a second while we save this". The upload is triggered at a lower level and when it starts the firmware is aborted wherever it is at the time.

Concerning persistence, when it comes to this part of it, it's simpler than you seem to think. When the running effect changes, all that's persisted after a few seconds is the index of the newly started effect in the effect list. This means that if the device is rebooted after an effect change (and the new effect's index has a chance to be persisted) then the effect that was running at the time of reboot will be started again, and it will run the full interval.

Pinning the running effect is already possible. If you set the default interval time to 0, EffectManager will actually never switch effects. I'm not totally sure if the Web UI will let you do this, but I know the ON button on the remote actually does exactly that. That is to say, pressing ON on the remote will freeze the effect cycle at whichever is the current effect. So, if you set the effect time to 0 (like by pressing ON on the remote) and then switch to the effect you want it to stay at, it will. Due to the effect index persistence I just described and the fact that the effect interval is also persisted, this behavior will persist across reboots as well until you change the effect interval to a value other than 0.

If you have a web session open and are watching the 120 qadzillion
zilliseconds march down and beat on Brightness Up or Brightness Down (sigh)
to change effect, I have confirmed that the timer does NOT get reset to
12000000000000; it continues marching on. Its' like there's a timer in the
web app and a timer on the board and they're not REALLY synchronized.

Ah, you're changing the effect using the IR remote, and flagging that the "time remaining" indicator in the web UI doesn't change along when you do. In itself, that is a new bug in my opinion. What I'm curious about is if the web UI does represent that the effect has changed when this happens?
If not, we may "just" be looking at the fact that the device does not "push" changes that happen to the web UI that may be relevant for what the web UI is showing. One reason for that is that there currently is no channel in place that allows this to happen. This would require a web socket to be added to the on-board webserver mix, which currently just isn't there.

That working theory seems pretty valid. By memory the useEffect hook managing the time update. I'd have to take a look at it closer to understand it's update mechanics.

Though the web was the boss that told the board to change, the web
didn't reset its own timer.

What's really important here is if the effect change was effectuated through the IR remote or not. If so, it makes sense the web UI is unaware.

That working theory seems pretty valid. By memory the useEffect hook managing the time update. I'd have to take a look at it closer to understand it's update mechanics.

I know for certain that the web front-end keeps its own timer. It does not retrieve the amount of time left from the device every microsecond - for one because it technically can't. My point is basically that:

  • if changes are made via the web UI (like changing an effect, or the effect interval, or ...) that don't reflect in the web UI itself, then that's a bug in the web UI.
  • if similar changes are made via another channel (like the infrared remote control) then the web UI currently can't know that they happen exactly when they happen. That's not so much a bug as a limitation in our current software architecture - that being that updates that take place on the device can't be pushed to (potentially) interested parties outside of it.

Some work has been done to improve this in #477 There is now a global effect state and a period refresh call to the /effects endpoint (currently 30s) to try to improve the sync between what the UI has and what the device has.

It's been some time since I looked at this. Really nice progress! Thanx to all of you.

The (user-selectable) units should probably be something other than milliseconds. Integer seconds wouldn't be unreasonable. Anything below a tenth of a second seems a bit silly.

It would be nice if there was a callback for onEnterPressed (or whatever it's called) so you could just type a number and press enter without having to click on something - anything - else for the change to register.

Any change to that timer (onEnter or a click on the spinner) should probably force a resync between the two timers.

I had set an infinite timeout because i was working on one effect and was tired of touching the remote. So I had effectively a -1 (or something) in my Interval. That's what started me down a path of exploring a pathological case.

Even with auto-advance turned off, the Time Remaining counts down. I know it'll be a zillion years before it hits zero, but it should probably just quit counting. Even if it counts internally, it should lie about it and just hide the field.

Is there an event for something like onDismiss or onEscapePressed to dismiss editing that field without changing it?

You can click the spinner to click "up" from 4294967295 (2^32-1). It should probably either disable the 'up' or trigger a wrap to zero. I'm sure the impedance matching between Javascript 53-bit numbers and 32-bit numbers is super weird of stuff like this.

Changing the setting via the settings panel lets the currently displayed value and the current timer get out of sync. Test case: apply a setting of 10000. Open Settings panel. 20000-> apply. The displayed interval and the current timer won't update until either they expire, the random (to the user) resync timer fires, or the effect next/prev are selected.

I've worked on UIs like this that let you control the same thing in multiple ways where the view and the controller are "far" from each other and they're always a huge pain to nail all the corner cases.

Overall, the behavior is pretty great. I think to boil that to actionable items.

  1. Implement onChange, onSave, onCancel for Interval.
  2. Make the settings panel resync the field and timer.
  3. Hide or stop the timer if negative (zero?)
  4. Display/edit seconds instead of milliseconds.

With the possible case of # 4, These are all super trivial. Why is 4 special? Be a normal human that doesn't read and just type "10" into the box. From your view, both the device and the web UI are now locked locked up.

OTOH, as a developer, setting it to super short values IS pretty handy for testing. Speed running all the effect is nice for development, but even a minimum of 1000 (1 effect per second) still lets you touch-test the list in under a minute and lets each effect draw enough frames that you'd recognize a leak or misdrawn frames or something.

Thanx for the fixes so far!

@robertlipe Just for your information: a few of the things you mention will be addressed by #477. Some others won't (yet).

Sweet! Thank you.

With the merge of #532, I believe the points in this issue that matter have been addressed. It would still be nice if the front-end picks up (effect) changes that happen at the back-end, but that is now covered by the discussion in #356.

@robertlipe Are you okay with me closing this?

I haven't gone down the list, but if you think they're sufficiently covered, that works for me. Thanx, all, for making the product more awesome.