partofthething / infopanel

Show live data, animations, pictures, or anything on simple displays like RGB matrices
https://partofthething.com/infopanel/
GNU General Public License v3.0
31 stars 12 forks source link

image_path fails with frequent updates #5

Open jonhanford opened 6 years ago

jonhanford commented 6 years ago

Hey there - I know I'm using this beyond the intended use - but I have a subway-arrival-time display going, and I'm updating logos for 4 routes via 4 sprites on the display.

I've found that unless I rate limit the updates to 1-every-3-seconds the updates aren't applied. The rate limit is a serviceable workaround, but if there's a way to address this in the underlying code - that would be awesome.

jonhanford commented 6 years ago

So, I figured out that this happens because there's a single image_path variable that stores incoming data, which is only checked at an interval. During the check, if it updates the image path of a sprite, it clears the variable out - but if a second update comes in between when the first one arrived and when it's checked for update, the first update is overwritten and ignored.

I worked around the issue in a kludgy fashion in driver.py-

if self.data_source['image_path']: self.change_image_path(self.data_source['image_path']) self.data_source['image_path'] = '' # clear it out in anticipation of next command. if self.data_source['image_path2']: self.change_image_path(self.data_source['image_path2']) self.data_source['image_path2'] = '' # clear it out in anticipation of next command. if self.data_source['image_path3']: self.change_image_path(self.data_source['image_path3']) self.data_source['image_path3'] = '' # clear it out in anticipation of next command. if self.data_source['image_path4']: self.change_image_path(self.data_source['image_path4']) self.data_source['image_path4'] = '' # clear it out in anticipation of next command. if self.data_source['image_path5']: self.change_image_path(self.data_source['image_path5']) self.data_source['image_path5'] = '' # clear it out in anticipation of next command.

Yep. I just duplicated it with corresponding declarations of image_path2 through 5 in data.py and send the different updates to different topics.

I think this could be better handled by a list or an array which stores incoming updates and walks through them removing them as they're applied. A little over my head right now but this has been a learning project for me.

Also, I sped up responsiveness to MQTT in general by changing some of the values in driver.py. I'm not sure if the default scene duration was at issue, but I have a hunch this might have been globally applied as a minimum scene duration.

FRAME_DELAY_S = 0.0025 # changed from 0.005 MODE_ALL_DURATION = 1 # 5 second default scene duration.

and later on in the Driver class self.interval = 1 #changed from 2

which directly affects how often it's checking for updates.

Also, after compiling the latest HZeller Lib with the experimental "FIXED_FRAME_MICROSECONDS" option, the display doesn't flicker when the system is under heavy load - so I am not as worried about pushing the script a little harder with more frequent checking and less sleeping. (setting the time to 0 does not work out well though)

I also added a MQTT qos specification parameter via the yaml, since I think my server was specifying qos 2 which was also slowing things down.

In any event, MQTT updates are almost instantaneous now. I'm trying to make my changes to the sprites more parametric and I'll eventually get a pull request together - everything is a little too duct-taped together right now to share :-)

partofthething commented 6 years ago

Oh sweet! Yeah there are good ways to do this right similar to how GUI frameworks deal instantly with users pressing buttons, etc. in another thread. I'm happy to hear that there's no flickering with the latest HZeller lib. I definitely don't like the MQTT slowness so I'm excited to use your work to get it more responsive. Want to do a PR? It'd be our first external one which could be fun.

jonhanford commented 6 years ago

Definitely going to do a PR - will take me a little while though. My hacked-together version has been humming along quite nicely on the hardware I built it for, but I'd like to make the stuff I've changed a little less restricted to my specific use-case.