silly_clock.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #!/usr/bin/env python
  2. import time
  3. from datetime import datetime
  4. from luma.led_matrix.device import max7219
  5. from luma.core.interface.serial import spi, noop
  6. from luma.core.render import canvas
  7. from luma.core.legacy import text, show_message
  8. from luma.core.legacy.font import proportional, CP437_FONT, TINY_FONT
  9. def minute_change(device):
  10. '''When we reach a minute change, animate it.'''
  11. hours = datetime.now().strftime('%H')
  12. minutes = datetime.now().strftime('%M')
  13. def helper(current_y):
  14. with canvas(device) as draw:
  15. text(draw, (0, 1), hours, fill="white", font=proportional(CP437_FONT))
  16. text(draw, (15, 1), ":", fill="white", font=proportional(TINY_FONT))
  17. text(draw, (17, current_y), minutes, fill="white", font=proportional(CP437_FONT))
  18. time.sleep(0.1)
  19. for current_y in range(1, 9):
  20. helper(current_y)
  21. minutes = datetime.now().strftime('%M')
  22. for current_y in range(9, 1, -1):
  23. helper(current_y)
  24. def animation(device, from_y, to_y):
  25. '''Animate the whole thing, moving it into/out of the abyss.'''
  26. hourstime = datetime.now().strftime('%H')
  27. mintime = datetime.now().strftime('%M')
  28. current_y = from_y
  29. while current_y != to_y:
  30. with canvas(device) as draw:
  31. text(draw, (0, current_y), hourstime, fill="white", font=proportional(CP437_FONT))
  32. text(draw, (15, current_y), ":", fill="white", font=proportional(TINY_FONT))
  33. text(draw, (17, current_y), mintime, fill="white", font=proportional(CP437_FONT))
  34. time.sleep(0.1)
  35. current_y += 1 if to_y > from_y else -1
  36. def main():
  37. # Setup for Banggood version of 4 x 8x8 LED Matrix (https://bit.ly/2Gywazb)
  38. serial = spi(port=0, device=0, gpio=noop())
  39. device = max7219(serial, cascaded=4, block_orientation=-90, blocks_arranged_in_reverse_order=False)
  40. device.contrast(16)
  41. # The time ascends from the abyss...
  42. animation(device, 8, 1)
  43. toggle = False # Toggle the second indicator every second
  44. while True:
  45. toggle = not toggle
  46. sec = datetime.now().second
  47. if sec == 59:
  48. # When we change minutes, animate the minute change
  49. minute_change(device)
  50. elif sec == 30:
  51. # Half-way through each minute, display the complete date/time,
  52. # animating the time display into and out of the abyss.
  53. full_msg = time.ctime()
  54. animation(device, 1, 8)
  55. show_message(device, full_msg, fill="white", font=proportional(CP437_FONT))
  56. animation(device, 8, 1)
  57. else:
  58. # Do the following twice a second (so the seconds' indicator blips).
  59. # I'd optimize if I had to - but what's the point?
  60. # Even my Raspberry PI2 can do this at 4% of a single one of the 4 cores!
  61. hours = datetime.now().strftime('%H')
  62. minutes = datetime.now().strftime('%M')
  63. with canvas(device) as draw:
  64. text(draw, (0, 1), hours, fill="white", font=proportional(CP437_FONT))
  65. text(draw, (15, 1), ":" if toggle else " ", fill="white", font=proportional(TINY_FONT))
  66. text(draw, (17, 1), minutes, fill="white", font=proportional(CP437_FONT))
  67. time.sleep(0.5)
  68. if __name__ == "__main__":
  69. main()