buba/README.md
Stefan Bethke 64a3c729be Refactor Animation to simplify
Also add some documentation on how to write animations.
2025-06-16 09:33:22 +02:00

84 lines
3.2 KiB
Markdown

# Bus- und Bahn-Anzeige (bus and train display)
This is the code to send information to the station display that is hanging in the hallway of CCCHH.
## Documentation
The [docs](./docs) directory contains a number of documents about the device, all in German.
## Development Environment
Use [Poetry](https://python-poetry.org) to manage a local environment:
```shell
poetry install
```
## Local Development
You can run the server without having a physical display attached. The server will open HTTP port 3000 on localhost, and
show an emulated display.
## Deployment
The server is deployed as a Docker image and run with Docker Compose. See below for the configuration.
You will need to allow access to the serial port. For example, in `compose.yaml`:
```yaml
services:
buba:
image: buba
environment:
BUBA_SERIAL: /dev/ttyUSB0
devices:
- /dev/ttyUSB0
```
## Configuration
Buba is configured completely through environment variables:
| Name | Default | Description |
|---------------|------------------|-------------------------------------------------------|
| `BUBA_LISTEN` | `127.0.0.1:3000` | IP and port to listen on. |
| `BUBA_SERIAL` | `/dev/ttyUSB0` | Serial port the display is connected to. |
| `DEBUG` | `false` | Set to any value except false to enable debug output. |
## Creating Animation Plugins
Buba instantiates objects of type `BubaAnimation` and runs through them in a loop. Each animation must implement the
`show()` method, which should send data to the display. The animation is run in its own thread, therefore, the animation
should sleep an appropriate time to let users take in the information. See the existing animations
in [buba/animations](./buba/animations) for inspiration.
To implement your own animation, subclass [BubaAnimation](buba/bubaanimation.py).
In the `__init__()` method, you will want to set `self.title`, and configure your data source.
Implement `update()` to fetch any data and fill in `self.rows` (list of rows). Each row in `self.rows` is a list of
values for the columns in the layout.
The default layout has a wide, left-aligned column for text, and a short, right-aligned column for a time period or a
value. You can define your own layout if necessary.
If you do not want to show tabular data, you can override `show()` and implement sending text to the display yourself.
## Character Set
The display uses [Code Page 437](https://en.wikipedia.org/wiki/Code_page_437), with a few exceptions. Due to the limited
resolution of the segments, the display can deviate significantly.
Note that the [Python codecs](https://docs.python.org/3/library/codecs.html) for `CP437` do not map all special
characters correctly.
| Code | CP437 | Geavision Spaltenschrift |
|------|--------------|--------------------------|
| 0xb4 | ┤ u2524 | Vehicle end left |
| 0xb5 | ╡ u2561 | Vehicle end right |
| 0xb6 | ╢ u2562 | Track |
| 0xff |   u00a0 | Three full segments |
In other displays, the vehicle ends can be used together with other special characters to show carriage information;
this set seems to be missing those extra characters.