You didn’t provide a picture of the Piston, so I have to guess at a few things. E.g., I’m guessing you’re only saving time, and not date & time (i.e., time variable vs datetime variable.) In any case, if I understood your ultimate goal, I came up with this simple example. (FYI, I’m using a virtual switch instead of a contact sensor, but it should work for that, too.)
The date & time of the current event is available in the system variable $currentEventDate. (I believe this is the same as the Virtual device “Date & Time.”) I’m comparing that to the previously saved event date & time + 20 seconds.
A comment about the variable previousChangeTimeValid. When the Piston is first created, the variable previousChangeTime will not have been initialized. (It will show as an invalid date & time.) If that was used in the condition, it’s my experience that webCoRE will use the value of $now for it. Therefore, the test would (effectively) be is $now before $now + 20, which would be true. To avoid that “false positive”, I added the variable previousChangeTimeValid. At first it will also be uninitialized, but my experience is that webCoRE will effectively treat that as false. Therefore, given the way I have it written, the complete condition group will not evaluate to true until at least the second time the Piston runs (when there will be a valid previous timestamp.)
I don’t know that I would attack the overall problem this way, but since I don’t have the complete picture of what you’re trying to do, I’m only providing feedback on your direct questions, and this is a concrete, working example of what my previous reply was trying to say.
Hope this helps.