Display-o-tron Plugin Gallery

Hi!

I think I made some changes to the plugins script as the storage space part was imported from that. I haven’t got my pi up and running at the mo having moved house recently, but did you do anything to the plugins bit as well?

Thanks for answering so quickly :-)

I have managed to get the first part to work using gadgetoid’s suggestion

df -h /media/usbhdd | grep G | awk ‘{print $5}’

this appears to work for the used space but if I repeat the above in the

def get_space(self):
section then it gives the same result as the
def get_storage(self): i.e. the used space.

Many thanks again
T

I managed to get this working better after playing around, but I cannot remember exactly what I used. I’ll try and dig out my Pi’s backup image and find the code I used later for you.

1 Like

Ok, I’ve managed to find what I think you are looking for. This is my modified graph.py plugin, which I reference in the sys-monitor.py I put together based on the original.

This is what I added to graph.py:

class GraphStorageSpace(MenuOption):
  """
  How much storage space is left on the external HDD.
  """
  def __init__(self):
    self.last = self.millis()
    MenuOption.__init__(self)

  def get_total(self):
    show_dl_raw = ""
    show_tl_sp = "df /your/location/here | grep T | awk '{print $2}'"
    hr_dl = run_cmd(show_tl_sp)
    return hr_dl

  def get_percent(self):
    show_dl_raw = ""
    show_per_sp = "df -h /your/location/here | grep T | awk '{print $5}'"
    hr_dl = run_cmd(show_per_sp)
    return hr_dl

  def get_used(self):
    show_dl_raw = ""
    show_st_sp = "df -h /media/brightbox | grep G | awk '{print $3}'"
    hr_dl = run_cmd(show_st_sp) 
    return hr_dl

  def get_free(self):
    show_dl_raw = ""
    show_dl_hr = "df -h /your/location/here | grep G | awk '{print $4}'"
    hr_dl = run_cmd(show_dl_hr) 
    return hr_dl

  def redraw(self, menu):
    now = self.millis()
    if now - self.last < 1000:
      return false

    menu.write_row(0,str('Total:' + self.get_total()[:-1]))
    menu.write_row(1,str('Used:' + self.get_used())[:-1] + ' / ' + self.get_percent()[:-1])
    menu.write_row(2,str('Free:' + self.get_free())[:-1])

My sys-monitor.py then looks like this:

#!/usr/bin/env python

import dot3k.joystick as joystick
import dot3k.lcd as lcd
import dot3k.backlight as backlight
from dot3k.menu import Menu, MenuOption
from plugins.utils import Backlight, Contrast
from plugins.graph import IPAddress, GraphTemp, GraphCPU, GraphNetSpeed, GraphNetTrans, GraphStorageSpace, GraphSysReboot, GraphSysShutdown
from plugins.clock import Clock
from plugins.wlan import Wlan
import time

"""
Using a set of nested lists you can describe
the menu you want to display on dot3k.

Instances of classes derived from MenuOption can
be used as menu items to show information or change settings.

See GraphTemp, GraphCPU, Contrast and Backlight for examples.
"""

menu = Menu({
    'Data':GraphNetTrans(),
    'Speed':GraphNetSpeed(),
    'IP':IPAddress(),
    'CPU':GraphCPU(),
    'Temp':GraphTemp(),
    'Storage':GraphStorageSpace(),
    'Settings': {
      'Maintenance': {
	'Reboot':GraphSysReboot(),
        'Shutdown':GraphSysShutdown(),
	'Contrast':Contrast(lcd),
        'Backlight':Backlight(backlight)
      }
    }
  },
  lcd,
  30)

"""
You can use anything to control dot3k.menu,
but you'll probably want to use dot3k.joystick
"""
REPEAT_DELAY = 0.5
@joystick.on(joystick.UP)
def handle_up(pin):
  menu.up()
  joystick.repeat(joystick.UP,menu.up,REPEAT_DELAY,0.9)

@joystick.on(joystick.DOWN)
def handle_down(pin):
  menu.down()
  joystick.repeat(joystick.DOWN,menu.down,REPEAT_DELAY,0.9)

@joystick.on(joystick.LEFT)
def handle_left(pin):
  menu.left()
  joystick.repeat(joystick.LEFT,menu.left,REPEAT_DELAY,0.9)

@joystick.on(joystick.RIGHT)
def handle_right(pin):
  menu.right()
  joystick.repeat(joystick.RIGHT,menu.right,REPEAT_DELAY,0.9)

@joystick.on(joystick.BUTTON)
def handle_button(pin):
  menu.select()

while 1:
  menu.redraw()
  time.sleep(0.05)

I hope this helps!

That would be fantastic :-)

Many thanks

See above! We must have been typing at the same time!

1 Like

Also, I added a line based on a recommendation on here, so that the backlight would change colour if the CPU was running too high. This goes in the graph.py plugin too, the part I’m referring to here is the second to last paragraph:

class GraphCPU(MenuOption):
  """
  A simple "plug-in" example, this gets the CPU load
  and draws it to the LCD when active
  """
  def __init__(self):
    self.cpu_samples = [0,0,0,0,0]
    self.last = self.millis()
    MenuOption.__init__(self)
  
  def redraw(self, menu):
    now = self.millis()
    if now - self.last < 1000:
      return false

    self.cpu_samples.append(psutil.cpu_percent())
    self.cpu_samples.pop(0)
    self.cpu_avg = sum(self.cpu_samples) / len(self.cpu_samples)

    menu.write_row(0, 'CPU Load')
    menu.write_row(1, str(self.cpu_avg) + '%')
    menu.write_row(2, '*' * int(16*(self.cpu_avg/100.0)))
    
    dot3k.backlight.set_graph(self.cpu_avg/100.0)

    if self.cpu_avg > 50:
      dot3k.backlight.rgb(212,225,2)
    else:
      dot3k.backlight.rgb(75,255,198)

  def left(self):
    dot3k.backlight.set_graph(0)
    return False

Indeed.

That’s great, I will have a play when I am finished with attending to my duties doled out by the missus :-)

Ah! excellent feature.

Google calendar plugin, anyone? (It also runs as a standalone script once set up with OAuth credentials)

Here’s my version as it stands…

So far, it includes the following features

  • Clock
  • Displays the next 9 events from your calendar, including ones that have started but not finished. Use the buttons to scroll through them
  • Shows time until each event
  • Backlight colour changes from green to red as an event draws closer (starting at 5 hours)
  • Auto screensaver with configurable timeout
  • Activity ticker using the graph LEDs even if the screen is off
  • Auto-reloads the calendar when an event finishes (or can manual refresh with select button)
  • If an event has a ‘pop up’ reminder, it will flash the graph LEDs during the reminder period, though you can’t ‘dismiss’ the reminder.
  • If an event has started but not finished, it shows time remaining until the event ends

Note: before I started this, I knew precisely zero python, so some of the code might not be good practice, but it seems to work.
Note 2: I’ve not yet tested it across Daylight Savings Times boundaries or anything like that, it’s really not in the slightest bit Time Zone aware yet, which is probably a massive can of worms waiting to happen next spring! :D

[EDIT: Yes it was - hopefully it now behaves a bit better approaching and crossing timezone changes!]

It’s reasonably well documented in the comments, but I guess I should get around to slapping it up on github at some point…

EDIT 2: Have thrown it up onto github now - the version I had here isn’t the newest any more. : Code moved here

4 Likes

Hey All,

Happy New Year.

I’m trying to get a straight forward line of text scrolling on the displayotron hat, but i don’t want to use a menu.

It is it possible to make this happen? I’ve been through all the examples, but it seems the only way to make it scroll is with the menu option?

Any help would be much appreciated

Thanks

Steven

I created a text-entry plugin for the Display-O-Tron menu system; I wrote about it here.

You can get the code here.

2 Likes

Wow! Looks great, and is fantastically well documented. Can’t wait to give this a try when I’m back in full-swing. Good work! Always like a good community project to shout about on BilgeTank :D

Thanks; glad you like it. Hopefully it’ll be useful to someone. :)

(If you do give it a mention, the name is “geh-mul”, not the “jeh-mul” or “jeh-mell” I get constantly!)

Hi just joined and got this going great! I would love to be able to assign athe rainbow light sequence when a certain tweet I’d comes up. Can you help?
Thanks Carl

@gadgetoid do you have any words of wisdom on how to display a degree symbol on the LCD screen for the DOT3K? I tried adding this to the top of my Python:

# -*- coding: utf-8 -*-

Then added the degree symbol in my code:

lcd.write("Temperture: "+str(temp)+" °C")

But when it shows on the screen, it’s a strange (Japanese?) symbol instead…

@Mr_A the DOT3k display actually has a hard-coded character set, like the good ol’ days. That is to say, it’s immutable, fixed in a ROM chip in the display driver IC itself.

That said, there is a degrees symbol in there, see page 5 of: https://www.lcd-module.com/eng/pdf/doma/dog-me.pdf

Looks like degrees is at 0b11110010 which is decimal 242 and hex 0xf2. You can use chr(242) (or chr(0b11110010) in your string to get this character on the display:

lcd.write("Temperature: {temp}{deg}C".format(temp=temp, deg=chr(242))

In hindsight, I should probably have included remapping to the Dot3k’s bonkers character set.

The “°” character or u"°" is actually "\xb0" which translates to 0b10110000 which would display as, from what I can tell, thee horizontal bars with a little accent dot on the bottom one. (it’s read backwards from right to left, with 0000 being bits 0 to 3 (vertical in the character table), and 1101 being bits 4 to 7 (horizontal in the table).

1 Like

Thanks @gadgetoid, I managed to get it to work by using the following in mine as the example you gave kept giving me a syntax error for the lcd.set_cursor_position line after:

lcd.write("Temp: "+temp+"\xf2C")

This now shows the degree symbol followed by a capital “C”. Thanks!