105 lines
4.1 KiB

Developer Guide
This document provides guide to hacking and extending PieTime.
To develop PieTime or cards, some additional setup is required. First, it's
recommended to use a virtual environment, to separate from OS Python and
extensions. Secondly, use ``requirements-dev.txt`` to install additional
modules and tools used in development.
Custom card example
.. sourcecode:: python
from pie_time.card import AbstractCard
import pygame
class ExampleCard(AbstractCard):
def initialize(self):
self.sprite = pygame.surface.Surface((20, 20))
self.sprite.fill((255, 0, 0))
self.orig_sprite_rect = self.sprite.get_rect()
self.orig_speed = [2, 2]
self.sprite_rect = self.orig_sprite_rect
self.speed = self.orig_speed
def show(self):
self.sprite_rect = self.orig_sprite_rect
self.speed = self.orig_speed
def tick(self):
self.sprite_rect = self.sprite_rect.move(self.speed)
if self.sprite_rect.left < 0 or self.sprite_rect.right > self.width:
self.speed[0] = -self.speed[0]
if self.sprite_rect.top < 0 or self.sprite_rect.bottom > self.height:
self.speed[1] = -self.speed[1]
self.surface.blit(self.sprite, self.sprite_rect)
This example shows how easy it is to create custom cards for use in PieTime
Start by creating a custom class that inherits from *AbstractCard*. Then
implement a few methods to make it display the information you need (in this
example, a red square moving on the screen). Having done that, you'll be ready to use your custom card in a deck.
Head on to :py:class:`pie_time.AbstractCard` documentation for more
information about PieTime card API.
Speed considerations
Since PieTime targets the Raspberry Pi, it's important to keep speed in mind.
When developing cards, take care to do as little work as possible in the
:py:meth:`pie_time.AbstractCard.tick` method.
For example, WeatherCard redraws its surface only when weather conditions
change. By doing so, the CPU load is reduced because the only thing PieTime has to do is blit the surface to screen.
Always test the behavior of your card in low FPS. Remember, that PieTime
targets small GPIO-connected LCD screens. For many of them, 20 FPS will be the best refresh rate. If your card behaves badly in such conditions, users may refrain from using it.
Threading considerations
Sometimes, it's required to perform background tasks during lifetime of the
card. API exposed by Python's builtin ``threading`` module should come in handy
is such situations.
Take WeatherCard as an example. Once every 10 minutes, it fetches current
conditions from the Internet. If you look into the card's code, there's
``_refresh_conditions`` method. It uses ``threading.Timer`` class to schedule
fetching of the conditions in a separate thread of control. This way, the
HTTP request (which may take some time depending on the network conditions)
won't cause the PieTime application to freeze.
As always with threads, you should be aware of the standard pitfalls - variable
access synchronization, error handling, the GIL. Also, spawning too many
threads will impact PieTime's performance. If you use threads in your card,
make sure to test it on the device to see how it impacts the load.
Handling events
In every iteration of the main loop, PieTime reads list of current events from
PyGame. This list is available for the cards to use through
The application itself handles the following events:
* ``QUIT`` (e.g. SIGTERM) - if this event appears, the application quits.
* ``KEYDOWN`` on the key specified by :py:attr:`pie_time.PieTime.KEY_QUIT` -
quits the application,
* ``MOUSEBUTTONDOWN`` anywhere on the screen when it's blanked -
if click to unblank is enabled,
* ``MOUSEBUTTONDOWN`` in one of the regions used to manually switch bedween