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
33 stars 12 forks source link

allow mqtt string-based data_source of generic fancytext object #6

Closed jonhanford closed 6 years ago

jonhanford commented 6 years ago

More of a request than an issue, I would love if the standard fancytext object accepted a data_source. Also for that subway-arrival-time clock. I've finagled the code on my own to show the minutes for the arrival time - but the next step is actually showing the route destination rather than just the direction.

I'm not great with python - I know the data_source is looking for an integer, and I haven't been able to figure out how to make it just pass a plain string. If you have any time to implement this, I think that would be awesome. If not, I'll share my results if I'm able to eventually get it working. Seems simple enough - I'm just a novice at this.

jonhanford commented 6 years ago

Actually I got it going. New bit of sprites.py looks like this. (yes, it's modified destination sprite and yes theres lots of stuff I could drop from this)

`class GreenMqttPlain(FancyText): # pylint:disable=too-many-instance-attributes

CONF = FancyText.CONF.extend({'label': vol.Coerce(str),
                              vol.Optional('low_val', default=13.0):vol.Coerce(float),
                              vol.Optional('high_val', default=23.0): vol.Coerce(float),
                              vol.Optional('data_label'): vol.Coerce(str),
                              vol.Optional('label_fmt', default='{}'): str,
                              vol.Optional('val_fmt', default='     {}'): str})

def __init__(self, max_x, max_y, data_source):
    FancyText.__init__(self, max_x, max_y, data_source=data_source)
    self.last_val = None
    self.color = None
    self.low_val = None
    self.high_val = None
    self.label = None
    self.value = None
    self.label_fmt = None
    self.val_fmt = None
    self.data_label = None
    self.cmap = colors.GREEN_RED

def apply_config(self, conf):
    conf = FancyText.apply_config(self, conf)
    if conf['data_label']:
        # make function to get live data off of object
        self.value = lambda: self.data_source[conf['data_label']]
    self._make_text()
    return conf

def _make_text(self):
    """Make elements of a duration with label and text."""

    val = self.value() if callable(self.value) else self.value  # pylint: disable=not-callable
    if val is None:
        color = colors.rgb_from_name('black')
        text = 'N/A'
    else:
        color = colors.rgb_from_name('green')
        text = self.val_fmt.format(val)
        FancyText.add(self, text, color)
    self.last_val = val

def update_color(self):
    """Update the interpolated color if value changed."""
    val = self.value() if callable(self.value) else self.value  # pylint: disable=not-callable
    if val != self.last_val:
        # only do lookup when things change for speed.
        self.clear()
        self._make_text()

def render(self, canvas):
    self.update_color()
    return FancyText.render(self, canvas)

`

partofthething commented 6 years ago

Nice! That's definitely something infopanel should support natively. I'll try to get your code integrated or if you want to submit a pull request on it I'd be happy to look it over and accept it.

partofthething commented 6 years ago

I added this feature to the main code. Just use DynamicFancyText and add a data_label and it should work for you. Also added label_color and value_color for ya. Hope that works!