I think you may have the execution model of webCoRE wrong in your head.
Like any other app in SmartThings, webCoRE is event driven. Pistons are event handlers.
In your case, the piston doesn’t have any explicit trigger conditions to guide it so subscribes to the events of interest to your conditions. It subscribes to switch events for your Tablet Charge switch.
When the switch turns off the piston is fired and runs from the top. It sees the switch is off so turns it on. It then waits for 30 seconds (or whatever), which in practice means it sets a timer for 30 seconds time and exits. If it woke up and continued (that’s covered next) there would be nothing to do anyway as there are no more statements in the flow.
As you have turned on the switch you get another event so the piston fires again. The previous piston has probably entered the wait by now so it can run straight away. It sees the switch isn’t off and invokes some webCoRE magic called the Task Cancellation Policy. That says that as the condition has changed you probably don’t want the old scheduled task and cancels it (that means when the piston wakes up after the thirty seconds timer it immediately exits again, rather than continuing where it left off).
The piston progresses to the else section and as the switch is on it turns it off and starts another wait.
The switch has been turned off so that generates another event and so it continues looping.
Meanwhile a timer mountain will be building up ready to start running 30 seconds (or whatever) later.
If you swapped the position of the wait and turn on/off tasks the piston would probably work OK. A more elegant solution might be to use a ‘timer’ block instead. This would let you create a block saying ‘every three hours …’. WebCoRE also simulates a toggle function so you could simply toggle the switch.