Skip to content

Commit 9f795e7

Browse files
committed
Update README AppFrame class description
1 parent df9481d commit 9f795e7

File tree

1 file changed

+25
-14
lines changed

1 file changed

+25
-14
lines changed

examples/led-matrix-painter/README.md

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,35 @@ Web Browser ──► HTTP API ──► Python Backend ──► Router B
8484

8585
1. **Web Interface**: The `app.js` script captures clicks on the grid. It debounces these events and sends the pixel data to the backend via the `/persist_frame` endpoint.
8686
2. **Python Backend**:
87-
* **Persistence**: The `store.py` module uses `SQLStore` to save the frame data (pixels, duration, position) to a `frames` table in a SQLite database.
88-
* **Bridge**: The `main.py` script converts the frame into a raw byte array and calls `Bridge.call("draw", frame_bytes)`.
87+
* **Data Model**: The `AppFrame` class normalizes the data, converting between frontend JSON, database records, and hardware byte arrays.
88+
* **Persistence**: The `store.py` module uses `SQLStore` to save the frame data to a `frames` table in a SQLite database.
89+
* **Bridge**: The `main.py` script sends the raw byte array to the board via `Bridge.call("draw", frame_bytes)`.
8990
3. **Arduino Sketch**: The sketch receives the raw byte data and uses the `Arduino_LED_Matrix` library to render the grayscale image.
9091

9192
## Understanding the Code
9293

94+
### 📦 Data Model (`app_frame.py`)
95+
96+
The `AppFrame` class is the core data structure that acts as a bridge between the different components. It extends the base `Frame` class to add application-specific metadata like `id`, `name`, `position`, and `duration`.
97+
98+
It handles three distinct data contracts:
99+
- **API Contract**: `to_json()` / `from_json()` formats data for the web frontend.
100+
- **Database Contract**: `to_record()` / `from_record()` formats data for `SQLStore` storage.
101+
- **Hardware Contract**: `to_board_bytes()` packs pixels into the specific byte format expected by the Arduino sketch.
102+
103+
```python
104+
class AppFrame(Frame):
105+
def to_record(self) -> dict:
106+
"""Convert to a database record dict for storage."""
107+
return {
108+
"id": self.id,
109+
"name": self.name,
110+
"rows": json.dumps(self.arr.tolist()), # Serialize pixels to JSON string
111+
"brightness_levels": int(self.brightness_levels),
112+
# ...
113+
}
114+
```
115+
93116
### 🔧 Backend (`main.py` & `store.py`)
94117

95118
The Python backend manages the application logic, database, and hardware communication.
@@ -116,18 +139,6 @@ def apply_frame_to_board(frame: AppFrame):
116139
Bridge.call("draw", frame_bytes)
117140
```
118141

119-
- **Code Generation**: The `AppFrame` class generates the C++ code displayed in the UI. It formats the internal array data into `uint32_t` hex values.
120-
121-
```python
122-
# app_frame.py
123-
def to_c_string(self) -> str:
124-
c_type = "uint32_t"
125-
parts = [f"const {c_type} {self.name}[] = {{"]
126-
# ... logic to format array data ...
127-
parts.append("};")
128-
return "\n".join(parts)
129-
```
130-
131142
### 🔧 Arduino Component (`sketch.ino`)
132143

133144
The sketch is designed to be a passive renderer, accepting commands from the Python backend.

0 commit comments

Comments
 (0)