vincibot 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
vincibot-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dronakurl
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,273 @@
1
+ Metadata-Version: 2.4
2
+ Name: vincibot
3
+ Version: 0.2.0
4
+ Summary: VinciBot (MatataStudio) per Bluetooth mit Python steuern – einfach und auf Deutsch
5
+ Author: Dronakurl
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Dronakurl/vincibot
8
+ Project-URL: Issues, https://github.com/Dronakurl/vincibot/issues
9
+ Keywords: vincibot,matatastudio,roboter,bluetooth,scratch,lernen
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Natural Language :: German
12
+ Classifier: Intended Audience :: Education
13
+ Classifier: Topic :: Education
14
+ Classifier: Typing :: Typed
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: bleak>=0.22
19
+ Provides-Extra: test
20
+ Requires-Dist: pytest; extra == "test"
21
+ Dynamic: license-file
22
+
23
+ # vincibot – den VinciBot mit Python steuern
24
+
25
+ Mit diesem Paket steuerst du den Lernroboter **VinciBot** von MatataStudio mit Python – per Bluetooth, auf Deutsch und ganz ohne Vorkenntnisse. Die Befehle lesen sich wie normale Sätze:
26
+
27
+ ```python
28
+ from vincibot import VinciBot
29
+
30
+ with VinciBot() as roboter:
31
+ roboter.licht("gruen") # alle Lichter grün
32
+ roboter.vorwaerts(10) # 10 Zentimeter nach vorne
33
+ roboter.rechts(90) # nach rechts drehen
34
+ roboter.schreibe("Hallo!") # Laufschrift auf dem Display
35
+ roboter.tanze("samba") # tanzen
36
+ ```
37
+
38
+ > Dieses Projekt ist **inoffiziell** und steht in keiner Verbindung zu MatataStudio / Matatalab.
39
+ > Es wurde mit einem VinciBot unter Linux entwickelt und getestet.
40
+
41
+ ## Inhalt
42
+
43
+ 1. [Was du brauchst](#1-was-du-brauchst)
44
+ 2. [Installieren](#2-installieren)
45
+ 3. [Roboter verbinden](#3-roboter-verbinden)
46
+ 4. [Dein erstes Programm](#4-dein-erstes-programm)
47
+ 5. [Alle Befehle im Überblick](#5-alle-befehle-im-überblick)
48
+ 6. [Beispielprogramme](#6-beispielprogramme)
49
+ 7. [Mehrere Dinge gleichzeitig (async)](#7-mehrere-dinge-gleichzeitig-async)
50
+ 8. [Scratch und Python umwandeln](#8-scratch-und-python-umwandeln)
51
+ 9. [Wenn etwas nicht klappt](#9-wenn-etwas-nicht-klappt)
52
+ 10. [Wie funktioniert das?](#10-wie-funktioniert-das)
53
+ 11. [Für Entwickler](#11-für-entwickler)
54
+
55
+ ## 1. Was du brauchst
56
+
57
+ - einen **VinciBot** (eingeschaltet, Akku geladen)
58
+ - einen Computer mit **Bluetooth** (Linux getestet; Windows und macOS sollten mit der Bluetooth-Bibliothek `bleak` funktionieren, sind aber nicht getestet)
59
+ - **Python 3.10 oder neuer**
60
+
61
+ ## 2. Installieren
62
+
63
+ Öffne ein Terminal im Ordner dieses Projekts und gib ein:
64
+
65
+ ```bash
66
+ python3 -m venv .venv # eigene Python-Umgebung anlegen (einmalig)
67
+ source .venv/bin/activate # Umgebung einschalten (Windows: .venv\Scripts\activate)
68
+ pip install -e . # vincibot installieren
69
+ ```
70
+
71
+ Danach kannst du Programme starten, zum Beispiel: `python beispiele/01_hallo.py`
72
+
73
+ ## 3. Roboter verbinden
74
+
75
+ 1. **Roboter einschalten.**
76
+ 2. Am Programmende trennt `vincibot` die Verbindung von selbst, auch wenn du `trennen()` vergessen hast. Bleibt der Roboter nach einem abgebrochenen Programm unter Linux als „verbunden“ hängen, löst `vincibot` das beim nächsten Verbinden selbst.
77
+ 3. Der Roboter darf **nicht gleichzeitig** mit einem anderen Programm verbunden sein, zum Beispiel mit der MatataCode-Seite im Browser (dort vorher auf "Trennen" klicken oder den Tab schließen). Er kann nur mit einem Gerät sprechen.
78
+ 4. Dein Programm sucht den Roboter selbst. Beim Verbinden piept er einmal – das ist normal.
79
+
80
+ Gibt es mehrere Roboter in der Nähe, nutzt du die Adresse deines Roboters: `VinciBot(adresse="AA:BB:CC:DD:EE:FF")`. Auf Linux findest du sie mit `bluetoothctl devices`.
81
+
82
+ ## 4. Dein erstes Programm
83
+
84
+ Speichere dies als `hallo.py` und starte es mit `python hallo.py`:
85
+
86
+ ```python
87
+ from vincibot import VinciBot
88
+
89
+ with VinciBot() as roboter:
90
+ roboter.licht("blau")
91
+ roboter.vorwaerts(10)
92
+ roboter.licht_aus()
93
+ ```
94
+
95
+ Was passiert hier?
96
+
97
+ - `from vincibot import VinciBot` holt den Roboter in dein Programm.
98
+ - `with VinciBot() as roboter:` verbindet sich mit dem Roboter und nennt ihn `roboter`. Am Ende wird die Verbindung automatisch beendet.
99
+ - Jede Zeile darunter (**eingerückt**!) ist ein Befehl an den Roboter. Er führt sie nacheinander aus.
100
+
101
+ Mit **Schleifen** wiederholst du Befehle, mit **if** triffst du Entscheidungen:
102
+
103
+ ```python
104
+ with VinciBot() as roboter:
105
+ for ecke in range(4): # 4-mal wiederholen
106
+ roboter.vorwaerts(15)
107
+ roboter.rechts(90)
108
+
109
+ if roboter.abstand() < 20: # ist etwas näher als 20 cm?
110
+ roboter.licht("rot")
111
+ ```
112
+
113
+ ## 5. Alle Befehle im Überblick
114
+
115
+ Die wichtigsten Befehle (`roboter.` davor schreiben). Die **vollständige Liste mit Erklärungen** steht in [docs/referenz.md](docs/referenz.md).
116
+
117
+ | Das willst du … | Befehl |
118
+ |---|---|
119
+ | vorwärts / rückwärts fahren | `vorwaerts(10)` · `rueckwaerts(10)` (Zentimeter) |
120
+ | drehen | `links(90)` · `rechts(45)` (Grad) |
121
+ | dauerhaft fahren und anhalten | `fahre("vorwaerts", tempo=50)` · `stoppe()` |
122
+ | Lichter einschalten | `licht("rot")` · `licht((255, 0, 128))` |
123
+ | ein einzelnes Licht | `licht_einzeln("links oben", "gelb")` – Positionen siehe unten |
124
+ | mehrere Lichter bunt | `lichter({"links oben": "rot", "rechts unten": "blau"})` |
125
+ | Lichter ausschalten | `licht_aus()` |
126
+ | etwas auf das Display schreiben | `schreibe("Hallo")` |
127
+ | ein Bild zeigen | `zeige_bild([...])` – siehe Beispiel 06 |
128
+ | einen Punkt leuchten lassen | `zeige_pixel(spalte, zeile)` · `display_aus()` |
129
+ | ein Gefühl zeigen | `gefuehl("froehlich")` |
130
+ | tanzen | `tanze("tango")` |
131
+ | eine Bewegung machen | `bewege_dich("umschauen")` |
132
+ | ein Geräusch abspielen | `geraeusch("polizei")` |
133
+ | ein Lied abspielen | `lied("funkel")` |
134
+ | Englisch sprechen | `sprich("hello")` |
135
+ | Töne spielen | `ton("c", 1)` · `instrument("gitarre")` |
136
+ | lauter / leiser | `lautstaerke(80)` |
137
+ | Entfernung messen | `abstand()` (Zentimeter) |
138
+ | Helligkeit messen | `helligkeit("links")` |
139
+ | Farbe am Boden erkennen | `sieht_farbe("rot")` |
140
+ | alle Sensorwerte | `sensorwerte()` |
141
+ | warten | `warte(2)` (Sekunden) |
142
+
143
+ **Die sechs Lichter** heißen nach ihrer Position (von vorne gesehen):
144
+
145
+ ```
146
+ links oben rechts oben
147
+ links mitte rechts mitte
148
+ links unten rechts unten
149
+ ```
150
+
151
+ **Werte, die du verwenden kannst**
152
+
153
+ - **Farben:** rot, gruen, blau, gelb, orange, lila, tuerkis, rosa, weiss, schwarz – oder drei Zahlen von 0 bis 255 für Rot, Grün und Blau, z. B. `(255, 128, 0)`.
154
+ - **Gefühle:** froehlich, wuetend, traurig, ueberrascht, aengstlich, angeekelt, begeistert, schwindelig, muede, schlaefrig, wach, stolz
155
+ - **Tänze:** tango, walzer, steppen, samba, polonaise, jazz, rock, polka
156
+ - **Bewegungen:** umschauen, verletzt, sprinten, kreisen, schuetteln
157
+ - **Geräusche:** krankenwagen, polizei, feuerwehr, zug, zugpfeife, schiffshorn, flugzeug, auto, automotor, magnetbahn
158
+ - **Lieder:** funkel, jingle bells, geburtstag, freude, holzsoldaten, jagdpolka
159
+ - **Noten:** c, d, e, f, g, a, h (mit `oktave=3`, `4` oder `5` tiefer oder höher)
160
+
161
+ Gibst du etwas Unbekanntes an, sagt dir das Programm in einer deutschen Fehlermeldung, welche Werte möglich sind.
162
+
163
+ **Tippfehler erkennt schon dein Editor:** Alle Befehle mit festen Wörtern (Farben, Gefühle, Richtungen …) haben passende Typangaben. Schreibst du `roboter.gefuehl("froelich")`, unterstreicht der Editor (z. B. Zed oder VS Code mit basedpyright/Pylance) das Wort rot, und die Autovervollständigung schlägt dir die erlaubten Wörter vor. Die Listen stehen in [`vincibot/_typen.py`](vincibot/_typen.py).
164
+
165
+ ## 6. Beispielprogramme
166
+
167
+ Im Ordner [`beispiele/`](beispiele/) liegen kleine Programme zum Ausprobieren und Verändern:
168
+
169
+ | Datei | Was passiert |
170
+ |---|---|
171
+ | `01_hallo.py` | Der Roboter begrüßt dich mit Licht, Text und Gesicht |
172
+ | `02_quadrat.py` | Er fährt ein Quadrat (Schleife) |
173
+ | `03_ampel.py` | Eine Ampel aus den sechs Lichtern |
174
+ | `04_abstandswarner.py` | Wie ein Einparkpiepser: je näher, desto roter |
175
+ | `05_hindernis_ausweichen.py` | Er fährt los und weicht Hindernissen aus |
176
+ | `06_zeichnen.py` | Ein Herz auf dem Display |
177
+ | `07_musik.py` | Eine kleine Melodie |
178
+ | `08_tanzparty.py` | Tanzen und blinken |
179
+ | `09_gleichzeitig_async.py` | Fahren und leuchten zur gleichen Zeit |
180
+
181
+ Tipp: Ändere Zahlen und Farben und schau, was passiert. So lernst du am schnellsten!
182
+
183
+ ## 7. Mehrere Dinge gleichzeitig (async)
184
+
185
+ Normalerweise wartet das Programm bei jedem Befehl, bis der Roboter fertig ist. Willst du, dass er **gleichzeitig** fährt und leuchtet, nimmst du die Klasse `VinciBotAsync`. Sie kann alles, was `VinciBot` kann; du schreibst nur `async`/`await` dazu:
186
+
187
+ ```python
188
+ import asyncio
189
+ from vincibot import VinciBotAsync
190
+
191
+ async def haupt():
192
+ async with VinciBotAsync() as roboter:
193
+ await asyncio.gather(
194
+ roboter.vorwaerts(20),
195
+ roboter.lichter({"links oben": "rot", "rechts oben": "gruen"}),
196
+ )
197
+
198
+ asyncio.run(haupt())
199
+ ```
200
+
201
+ Außerdem gibt es `await roboter.warte_bis(lambda werte: werte["abstand_cm"] < 10)` und `async for werte in roboter.sensorstrom(): ...` für fortlaufende Sensorwerte.
202
+
203
+ ## 8. Scratch und Python umwandeln
204
+
205
+ Du kennst die Blockprogrammierung von MatataCode (Scratch)? Dann kannst du Projekte in Python-Programme
206
+ umwandeln und so sehen, wie die Blöcke als Text aussehen – oder umgekehrt:
207
+
208
+ ```bash
209
+ python -m vincibot.scratch projekt.mc # Scratch -> projekt.py
210
+ python -m vincibot.scratch programm.py # Python -> programm.mc (in MatataCode über Datei → Load from your computer öffnen)
211
+ ```
212
+
213
+ Aus „when robot start → move forward 10 cm → turn right 90“ wird:
214
+
215
+ ```python
216
+ with VinciBot() as roboter:
217
+ roboter.vorwaerts(10)
218
+ roboter.rechts(90)
219
+ ```
220
+
221
+ Was sich nicht umwandeln lässt, meldet der Konverter als **Warnung** – nichts verschwindet stillschweigend.
222
+ Zurück nach Scratch klappt nur bei einfachen Programmen (Befehle, Schleifen, if/else, Variablen, Rechnen).
223
+ Die Tabelle der Blöcke und alle Grenzen stehen in [docs/scratch.md](docs/scratch.md); Beispiele liegen in
224
+ [`projekte/`](projekte/).
225
+
226
+ ## 9. Wenn etwas nicht klappt
227
+
228
+ | Problem | Lösung |
229
+ |---|---|
230
+ | „Kein VinciBot gefunden“ | Roboter einschalten, näher an den Computer, Bluetooth am Computer aktivieren. Prüfen, dass er nicht mit einem anderen Gerät (Tablet, Browser) verbunden ist. Unter Linux hilft `bluetoothctl disconnect <Adresse>`. |
231
+ | Der Roboter piept mehrmals | Ein Befehl war unpassend (z. B. ein Wert außerhalb des erlaubten Bereichs). Ein Piepen beim Verbinden ist normal. |
232
+ | Der Roboter reagiert gar nicht mehr | Aus- und wieder einschalten, danach neu verbinden. |
233
+ | `ModuleNotFoundError: vincibot` | Die Python-Umgebung ist nicht eingeschaltet (`source .venv/bin/activate`). |
234
+ | Umlaute auf dem Display fehlen | Das Display zeigt nicht alle Sonderzeichen. Schreibe „ae“, „oe“, „ue“. |
235
+ | `sprich(...)` versteht deutsche Wörter nicht | Der Roboter spricht nur Englisch. |
236
+
237
+ ## 10. Wie funktioniert das?
238
+
239
+ Der VinciBot ist ein kleiner Computer (ESP32-S3), auf dem MicroPython läuft. Dieses Paket sendet per Bluetooth Low Energy kleine Pakete mit MicroPython-Befehlen wie `motion.move_position("forward", 10, "cm")`. Der Roboter führt sie aus, antwortet und meldet laufend seine Sensorwerte. Das Paketformat wurde aus der offiziellen Web-Oberfläche (vinci.matatastudio.com) abgeleitet und gegen deren Bluetooth-Verkehr geprüft. Details: [docs/protokoll.md](docs/protokoll.md). Die offizielle Beschreibung der Roboter-Befehle findest du im Python-Editor auf vinci.matatastudio.com.
240
+
241
+ ## 11. Für Entwickler
242
+
243
+ ```
244
+ vincibot/
245
+ roboter.py einfache Klasse VinciBot (ohne async), AUTOMATISCH erzeugt aus asynchron.py
246
+ asynchron.py VinciBotAsync – alle Befehle, async
247
+ _woerter.py deutsche Namen (Farben, Tänze …) -> Befehle des Roboters
248
+ _verbindung.py Bluetooth-Verbindung, Antworten, Sensorstrom
249
+ _protokoll.py Paketformat, Prüfsumme
250
+ scratch.py Konverter Scratch (.mc/.sb3) <-> Python
251
+ beispiele/ Beispielprogramme
252
+ projekte/ Scratch-Beispielprojekte und ihre Python-Umwandlung
253
+ docs/ Referenz, Protokoll, Roboter-API
254
+ tests/ Tests (laufen ohne Roboter): pytest
255
+ werkzeuge/ erzeuge_roboter.py (erzeugt roboter.py) und erzeuge_referenz.py (docs/referenz.md)
256
+ ```
257
+
258
+ ```bash
259
+ pip install -e ".[test]"
260
+ pytest # Tests ohne Roboter
261
+ python werkzeuge/erzeuge_roboter.py # roboter.py neu erzeugen, nachdem asynchron.py geändert wurde
262
+ python werkzeuge/erzeuge_referenz.py # Referenz neu erzeugen
263
+ ```
264
+
265
+ Für Befehle, die dieses Paket nicht kennt, gibt es `roboter.roh("<MicroPython-Befehl>")`. Nicht unterstützt sind bisher die Erweiterungen mit Kamera-Modul (`vision`, `lcd`), WLAN/MQTT und Zusatzmotoren – die API-Beschreibung dafür findest du im Python-Editor auf vinci.matatastudio.com, und über `roh()` sind sie prinzipiell erreichbar.
266
+
267
+ ### Teststand
268
+
269
+ Getestet am echten Roboter (Linux, BlueZ): Fahren, Drehen, Lichter, Display (Text, Bild, Pixel), Töne, Noten, Lied „funkel“, Sprechen, Gefühle, Bewegungen, Tänze, Sensorabfragen und gleichzeitige Befehle. Die Namen aller Geräusche, Tänze, Gefühle und Bewegungen wurden einmal durchgespielt und vom Roboter angenommen. Der Scratch-Konverter ist mit einem Beispielprojekt und per Rundlauf getestet; ein erzeugtes Scratch-Projekt wurde in der Web-Oberfläche geladen. Am Roboter bestätigt: Anordnung der Lichter, Bildanzeige, Farben und die Drehrichtung von `drehe_mit_tempo` (positiv = links). Infrarot: Senden und Abfragen laufen ohne Fehler, ein Empfang wurde aber nicht beobachtet. Nicht ausprobiert: ob der Roboter ein umgewandeltes Programm genauso ausführt wie die Blöcke, die übrigen Lieder (außer „funkel“), `spiele_datei`, Empfang von Infrarot und Fernbedienung, Farbsensor-Kalibrierung und die Trommel-Namen.
270
+
271
+ ## Lizenz
272
+
273
+ MIT, siehe [LICENSE](LICENSE). Inoffizielles Projekt; „VinciBot“ und „MatataStudio“ sind Marken ihrer Inhaber.
@@ -0,0 +1,251 @@
1
+ # vincibot – den VinciBot mit Python steuern
2
+
3
+ Mit diesem Paket steuerst du den Lernroboter **VinciBot** von MatataStudio mit Python – per Bluetooth, auf Deutsch und ganz ohne Vorkenntnisse. Die Befehle lesen sich wie normale Sätze:
4
+
5
+ ```python
6
+ from vincibot import VinciBot
7
+
8
+ with VinciBot() as roboter:
9
+ roboter.licht("gruen") # alle Lichter grün
10
+ roboter.vorwaerts(10) # 10 Zentimeter nach vorne
11
+ roboter.rechts(90) # nach rechts drehen
12
+ roboter.schreibe("Hallo!") # Laufschrift auf dem Display
13
+ roboter.tanze("samba") # tanzen
14
+ ```
15
+
16
+ > Dieses Projekt ist **inoffiziell** und steht in keiner Verbindung zu MatataStudio / Matatalab.
17
+ > Es wurde mit einem VinciBot unter Linux entwickelt und getestet.
18
+
19
+ ## Inhalt
20
+
21
+ 1. [Was du brauchst](#1-was-du-brauchst)
22
+ 2. [Installieren](#2-installieren)
23
+ 3. [Roboter verbinden](#3-roboter-verbinden)
24
+ 4. [Dein erstes Programm](#4-dein-erstes-programm)
25
+ 5. [Alle Befehle im Überblick](#5-alle-befehle-im-überblick)
26
+ 6. [Beispielprogramme](#6-beispielprogramme)
27
+ 7. [Mehrere Dinge gleichzeitig (async)](#7-mehrere-dinge-gleichzeitig-async)
28
+ 8. [Scratch und Python umwandeln](#8-scratch-und-python-umwandeln)
29
+ 9. [Wenn etwas nicht klappt](#9-wenn-etwas-nicht-klappt)
30
+ 10. [Wie funktioniert das?](#10-wie-funktioniert-das)
31
+ 11. [Für Entwickler](#11-für-entwickler)
32
+
33
+ ## 1. Was du brauchst
34
+
35
+ - einen **VinciBot** (eingeschaltet, Akku geladen)
36
+ - einen Computer mit **Bluetooth** (Linux getestet; Windows und macOS sollten mit der Bluetooth-Bibliothek `bleak` funktionieren, sind aber nicht getestet)
37
+ - **Python 3.10 oder neuer**
38
+
39
+ ## 2. Installieren
40
+
41
+ Öffne ein Terminal im Ordner dieses Projekts und gib ein:
42
+
43
+ ```bash
44
+ python3 -m venv .venv # eigene Python-Umgebung anlegen (einmalig)
45
+ source .venv/bin/activate # Umgebung einschalten (Windows: .venv\Scripts\activate)
46
+ pip install -e . # vincibot installieren
47
+ ```
48
+
49
+ Danach kannst du Programme starten, zum Beispiel: `python beispiele/01_hallo.py`
50
+
51
+ ## 3. Roboter verbinden
52
+
53
+ 1. **Roboter einschalten.**
54
+ 2. Am Programmende trennt `vincibot` die Verbindung von selbst, auch wenn du `trennen()` vergessen hast. Bleibt der Roboter nach einem abgebrochenen Programm unter Linux als „verbunden“ hängen, löst `vincibot` das beim nächsten Verbinden selbst.
55
+ 3. Der Roboter darf **nicht gleichzeitig** mit einem anderen Programm verbunden sein, zum Beispiel mit der MatataCode-Seite im Browser (dort vorher auf "Trennen" klicken oder den Tab schließen). Er kann nur mit einem Gerät sprechen.
56
+ 4. Dein Programm sucht den Roboter selbst. Beim Verbinden piept er einmal – das ist normal.
57
+
58
+ Gibt es mehrere Roboter in der Nähe, nutzt du die Adresse deines Roboters: `VinciBot(adresse="AA:BB:CC:DD:EE:FF")`. Auf Linux findest du sie mit `bluetoothctl devices`.
59
+
60
+ ## 4. Dein erstes Programm
61
+
62
+ Speichere dies als `hallo.py` und starte es mit `python hallo.py`:
63
+
64
+ ```python
65
+ from vincibot import VinciBot
66
+
67
+ with VinciBot() as roboter:
68
+ roboter.licht("blau")
69
+ roboter.vorwaerts(10)
70
+ roboter.licht_aus()
71
+ ```
72
+
73
+ Was passiert hier?
74
+
75
+ - `from vincibot import VinciBot` holt den Roboter in dein Programm.
76
+ - `with VinciBot() as roboter:` verbindet sich mit dem Roboter und nennt ihn `roboter`. Am Ende wird die Verbindung automatisch beendet.
77
+ - Jede Zeile darunter (**eingerückt**!) ist ein Befehl an den Roboter. Er führt sie nacheinander aus.
78
+
79
+ Mit **Schleifen** wiederholst du Befehle, mit **if** triffst du Entscheidungen:
80
+
81
+ ```python
82
+ with VinciBot() as roboter:
83
+ for ecke in range(4): # 4-mal wiederholen
84
+ roboter.vorwaerts(15)
85
+ roboter.rechts(90)
86
+
87
+ if roboter.abstand() < 20: # ist etwas näher als 20 cm?
88
+ roboter.licht("rot")
89
+ ```
90
+
91
+ ## 5. Alle Befehle im Überblick
92
+
93
+ Die wichtigsten Befehle (`roboter.` davor schreiben). Die **vollständige Liste mit Erklärungen** steht in [docs/referenz.md](docs/referenz.md).
94
+
95
+ | Das willst du … | Befehl |
96
+ |---|---|
97
+ | vorwärts / rückwärts fahren | `vorwaerts(10)` · `rueckwaerts(10)` (Zentimeter) |
98
+ | drehen | `links(90)` · `rechts(45)` (Grad) |
99
+ | dauerhaft fahren und anhalten | `fahre("vorwaerts", tempo=50)` · `stoppe()` |
100
+ | Lichter einschalten | `licht("rot")` · `licht((255, 0, 128))` |
101
+ | ein einzelnes Licht | `licht_einzeln("links oben", "gelb")` – Positionen siehe unten |
102
+ | mehrere Lichter bunt | `lichter({"links oben": "rot", "rechts unten": "blau"})` |
103
+ | Lichter ausschalten | `licht_aus()` |
104
+ | etwas auf das Display schreiben | `schreibe("Hallo")` |
105
+ | ein Bild zeigen | `zeige_bild([...])` – siehe Beispiel 06 |
106
+ | einen Punkt leuchten lassen | `zeige_pixel(spalte, zeile)` · `display_aus()` |
107
+ | ein Gefühl zeigen | `gefuehl("froehlich")` |
108
+ | tanzen | `tanze("tango")` |
109
+ | eine Bewegung machen | `bewege_dich("umschauen")` |
110
+ | ein Geräusch abspielen | `geraeusch("polizei")` |
111
+ | ein Lied abspielen | `lied("funkel")` |
112
+ | Englisch sprechen | `sprich("hello")` |
113
+ | Töne spielen | `ton("c", 1)` · `instrument("gitarre")` |
114
+ | lauter / leiser | `lautstaerke(80)` |
115
+ | Entfernung messen | `abstand()` (Zentimeter) |
116
+ | Helligkeit messen | `helligkeit("links")` |
117
+ | Farbe am Boden erkennen | `sieht_farbe("rot")` |
118
+ | alle Sensorwerte | `sensorwerte()` |
119
+ | warten | `warte(2)` (Sekunden) |
120
+
121
+ **Die sechs Lichter** heißen nach ihrer Position (von vorne gesehen):
122
+
123
+ ```
124
+ links oben rechts oben
125
+ links mitte rechts mitte
126
+ links unten rechts unten
127
+ ```
128
+
129
+ **Werte, die du verwenden kannst**
130
+
131
+ - **Farben:** rot, gruen, blau, gelb, orange, lila, tuerkis, rosa, weiss, schwarz – oder drei Zahlen von 0 bis 255 für Rot, Grün und Blau, z. B. `(255, 128, 0)`.
132
+ - **Gefühle:** froehlich, wuetend, traurig, ueberrascht, aengstlich, angeekelt, begeistert, schwindelig, muede, schlaefrig, wach, stolz
133
+ - **Tänze:** tango, walzer, steppen, samba, polonaise, jazz, rock, polka
134
+ - **Bewegungen:** umschauen, verletzt, sprinten, kreisen, schuetteln
135
+ - **Geräusche:** krankenwagen, polizei, feuerwehr, zug, zugpfeife, schiffshorn, flugzeug, auto, automotor, magnetbahn
136
+ - **Lieder:** funkel, jingle bells, geburtstag, freude, holzsoldaten, jagdpolka
137
+ - **Noten:** c, d, e, f, g, a, h (mit `oktave=3`, `4` oder `5` tiefer oder höher)
138
+
139
+ Gibst du etwas Unbekanntes an, sagt dir das Programm in einer deutschen Fehlermeldung, welche Werte möglich sind.
140
+
141
+ **Tippfehler erkennt schon dein Editor:** Alle Befehle mit festen Wörtern (Farben, Gefühle, Richtungen …) haben passende Typangaben. Schreibst du `roboter.gefuehl("froelich")`, unterstreicht der Editor (z. B. Zed oder VS Code mit basedpyright/Pylance) das Wort rot, und die Autovervollständigung schlägt dir die erlaubten Wörter vor. Die Listen stehen in [`vincibot/_typen.py`](vincibot/_typen.py).
142
+
143
+ ## 6. Beispielprogramme
144
+
145
+ Im Ordner [`beispiele/`](beispiele/) liegen kleine Programme zum Ausprobieren und Verändern:
146
+
147
+ | Datei | Was passiert |
148
+ |---|---|
149
+ | `01_hallo.py` | Der Roboter begrüßt dich mit Licht, Text und Gesicht |
150
+ | `02_quadrat.py` | Er fährt ein Quadrat (Schleife) |
151
+ | `03_ampel.py` | Eine Ampel aus den sechs Lichtern |
152
+ | `04_abstandswarner.py` | Wie ein Einparkpiepser: je näher, desto roter |
153
+ | `05_hindernis_ausweichen.py` | Er fährt los und weicht Hindernissen aus |
154
+ | `06_zeichnen.py` | Ein Herz auf dem Display |
155
+ | `07_musik.py` | Eine kleine Melodie |
156
+ | `08_tanzparty.py` | Tanzen und blinken |
157
+ | `09_gleichzeitig_async.py` | Fahren und leuchten zur gleichen Zeit |
158
+
159
+ Tipp: Ändere Zahlen und Farben und schau, was passiert. So lernst du am schnellsten!
160
+
161
+ ## 7. Mehrere Dinge gleichzeitig (async)
162
+
163
+ Normalerweise wartet das Programm bei jedem Befehl, bis der Roboter fertig ist. Willst du, dass er **gleichzeitig** fährt und leuchtet, nimmst du die Klasse `VinciBotAsync`. Sie kann alles, was `VinciBot` kann; du schreibst nur `async`/`await` dazu:
164
+
165
+ ```python
166
+ import asyncio
167
+ from vincibot import VinciBotAsync
168
+
169
+ async def haupt():
170
+ async with VinciBotAsync() as roboter:
171
+ await asyncio.gather(
172
+ roboter.vorwaerts(20),
173
+ roboter.lichter({"links oben": "rot", "rechts oben": "gruen"}),
174
+ )
175
+
176
+ asyncio.run(haupt())
177
+ ```
178
+
179
+ Außerdem gibt es `await roboter.warte_bis(lambda werte: werte["abstand_cm"] < 10)` und `async for werte in roboter.sensorstrom(): ...` für fortlaufende Sensorwerte.
180
+
181
+ ## 8. Scratch und Python umwandeln
182
+
183
+ Du kennst die Blockprogrammierung von MatataCode (Scratch)? Dann kannst du Projekte in Python-Programme
184
+ umwandeln und so sehen, wie die Blöcke als Text aussehen – oder umgekehrt:
185
+
186
+ ```bash
187
+ python -m vincibot.scratch projekt.mc # Scratch -> projekt.py
188
+ python -m vincibot.scratch programm.py # Python -> programm.mc (in MatataCode über Datei → Load from your computer öffnen)
189
+ ```
190
+
191
+ Aus „when robot start → move forward 10 cm → turn right 90“ wird:
192
+
193
+ ```python
194
+ with VinciBot() as roboter:
195
+ roboter.vorwaerts(10)
196
+ roboter.rechts(90)
197
+ ```
198
+
199
+ Was sich nicht umwandeln lässt, meldet der Konverter als **Warnung** – nichts verschwindet stillschweigend.
200
+ Zurück nach Scratch klappt nur bei einfachen Programmen (Befehle, Schleifen, if/else, Variablen, Rechnen).
201
+ Die Tabelle der Blöcke und alle Grenzen stehen in [docs/scratch.md](docs/scratch.md); Beispiele liegen in
202
+ [`projekte/`](projekte/).
203
+
204
+ ## 9. Wenn etwas nicht klappt
205
+
206
+ | Problem | Lösung |
207
+ |---|---|
208
+ | „Kein VinciBot gefunden“ | Roboter einschalten, näher an den Computer, Bluetooth am Computer aktivieren. Prüfen, dass er nicht mit einem anderen Gerät (Tablet, Browser) verbunden ist. Unter Linux hilft `bluetoothctl disconnect <Adresse>`. |
209
+ | Der Roboter piept mehrmals | Ein Befehl war unpassend (z. B. ein Wert außerhalb des erlaubten Bereichs). Ein Piepen beim Verbinden ist normal. |
210
+ | Der Roboter reagiert gar nicht mehr | Aus- und wieder einschalten, danach neu verbinden. |
211
+ | `ModuleNotFoundError: vincibot` | Die Python-Umgebung ist nicht eingeschaltet (`source .venv/bin/activate`). |
212
+ | Umlaute auf dem Display fehlen | Das Display zeigt nicht alle Sonderzeichen. Schreibe „ae“, „oe“, „ue“. |
213
+ | `sprich(...)` versteht deutsche Wörter nicht | Der Roboter spricht nur Englisch. |
214
+
215
+ ## 10. Wie funktioniert das?
216
+
217
+ Der VinciBot ist ein kleiner Computer (ESP32-S3), auf dem MicroPython läuft. Dieses Paket sendet per Bluetooth Low Energy kleine Pakete mit MicroPython-Befehlen wie `motion.move_position("forward", 10, "cm")`. Der Roboter führt sie aus, antwortet und meldet laufend seine Sensorwerte. Das Paketformat wurde aus der offiziellen Web-Oberfläche (vinci.matatastudio.com) abgeleitet und gegen deren Bluetooth-Verkehr geprüft. Details: [docs/protokoll.md](docs/protokoll.md). Die offizielle Beschreibung der Roboter-Befehle findest du im Python-Editor auf vinci.matatastudio.com.
218
+
219
+ ## 11. Für Entwickler
220
+
221
+ ```
222
+ vincibot/
223
+ roboter.py einfache Klasse VinciBot (ohne async), AUTOMATISCH erzeugt aus asynchron.py
224
+ asynchron.py VinciBotAsync – alle Befehle, async
225
+ _woerter.py deutsche Namen (Farben, Tänze …) -> Befehle des Roboters
226
+ _verbindung.py Bluetooth-Verbindung, Antworten, Sensorstrom
227
+ _protokoll.py Paketformat, Prüfsumme
228
+ scratch.py Konverter Scratch (.mc/.sb3) <-> Python
229
+ beispiele/ Beispielprogramme
230
+ projekte/ Scratch-Beispielprojekte und ihre Python-Umwandlung
231
+ docs/ Referenz, Protokoll, Roboter-API
232
+ tests/ Tests (laufen ohne Roboter): pytest
233
+ werkzeuge/ erzeuge_roboter.py (erzeugt roboter.py) und erzeuge_referenz.py (docs/referenz.md)
234
+ ```
235
+
236
+ ```bash
237
+ pip install -e ".[test]"
238
+ pytest # Tests ohne Roboter
239
+ python werkzeuge/erzeuge_roboter.py # roboter.py neu erzeugen, nachdem asynchron.py geändert wurde
240
+ python werkzeuge/erzeuge_referenz.py # Referenz neu erzeugen
241
+ ```
242
+
243
+ Für Befehle, die dieses Paket nicht kennt, gibt es `roboter.roh("<MicroPython-Befehl>")`. Nicht unterstützt sind bisher die Erweiterungen mit Kamera-Modul (`vision`, `lcd`), WLAN/MQTT und Zusatzmotoren – die API-Beschreibung dafür findest du im Python-Editor auf vinci.matatastudio.com, und über `roh()` sind sie prinzipiell erreichbar.
244
+
245
+ ### Teststand
246
+
247
+ Getestet am echten Roboter (Linux, BlueZ): Fahren, Drehen, Lichter, Display (Text, Bild, Pixel), Töne, Noten, Lied „funkel“, Sprechen, Gefühle, Bewegungen, Tänze, Sensorabfragen und gleichzeitige Befehle. Die Namen aller Geräusche, Tänze, Gefühle und Bewegungen wurden einmal durchgespielt und vom Roboter angenommen. Der Scratch-Konverter ist mit einem Beispielprojekt und per Rundlauf getestet; ein erzeugtes Scratch-Projekt wurde in der Web-Oberfläche geladen. Am Roboter bestätigt: Anordnung der Lichter, Bildanzeige, Farben und die Drehrichtung von `drehe_mit_tempo` (positiv = links). Infrarot: Senden und Abfragen laufen ohne Fehler, ein Empfang wurde aber nicht beobachtet. Nicht ausprobiert: ob der Roboter ein umgewandeltes Programm genauso ausführt wie die Blöcke, die übrigen Lieder (außer „funkel“), `spiele_datei`, Empfang von Infrarot und Fernbedienung, Farbsensor-Kalibrierung und die Trommel-Namen.
248
+
249
+ ## Lizenz
250
+
251
+ MIT, siehe [LICENSE](LICENSE). Inoffizielles Projekt; „VinciBot“ und „MatataStudio“ sind Marken ihrer Inhaber.
@@ -0,0 +1,44 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "vincibot"
7
+ license = "MIT"
8
+ version = "0.2.0"
9
+ description = "VinciBot (MatataStudio) per Bluetooth mit Python steuern – einfach und auf Deutsch"
10
+ readme = "README.md"
11
+ requires-python = ">=3.10"
12
+ authors = [{ name = "Dronakurl" }]
13
+ keywords = ["vincibot", "matatastudio", "roboter", "bluetooth", "scratch", "lernen"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "Natural Language :: German",
17
+ "Intended Audience :: Education",
18
+ "Topic :: Education",
19
+ "Typing :: Typed",
20
+ ]
21
+ dependencies = ["bleak>=0.22"]
22
+
23
+ [project.urls]
24
+ Homepage = "https://github.com/Dronakurl/vincibot"
25
+ Issues = "https://github.com/Dronakurl/vincibot/issues"
26
+
27
+ [project.scripts]
28
+ vincibot-konverter = "vincibot.scratch:haupt"
29
+
30
+ [project.optional-dependencies]
31
+ test = ["pytest"]
32
+
33
+ [tool.setuptools]
34
+ packages = ["vincibot"]
35
+
36
+ [tool.setuptools.package-data]
37
+ vincibot = ["py.typed"]
38
+
39
+ [tool.basedpyright]
40
+ venvPath = "."
41
+ venv = ".venv"
42
+ include = ["vincibot", "beispiele", "tests", "werkzeuge"]
43
+ pythonVersion = "3.10"
44
+ ignore = ["werkzeuge"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,56 @@
1
+ # pyright: reportPrivateUsage=false, reportAny=false, reportImplicitStringConcatenation=false
2
+ from vincibot import _protokoll as p
3
+
4
+
5
+ def test_befehlspaket_stimmt_mit_der_offiziellen_web_app_ueberein():
6
+ # Mitschnitt der Web-App (vinci.matatastudio.com): 10 cm vorwärts
7
+ erwartet = bytes.fromhex(
8
+ "fe 2e 70 00 00 6d 6f 74 69 6f 6e 2e 6d 6f 76 65 5f 70 6f 73 69 74 69 6f 6e 28 22 66 6f "
9
+ "72 77 61 72 64 22 2c 20 31 30 2c 20 22 63 6d 22 29 29 fa")
10
+ assert p.baue_befehlspaket('motion.move_position("forward", 10, "cm")', 0) == erwartet
11
+
12
+
13
+ def test_begruessung_stimmt_mit_der_web_app_ueberein():
14
+ assert p.baue_paket([126, 2, 2, 0, 0]) == bytes.fromhex("fe 07 7e 02 02 00 00 97 77")
15
+ assert p.baue_paket([1, 1]) == bytes.fromhex("fe 04 01 01 33 4c")
16
+
17
+
18
+ def test_entpacken_der_antwort():
19
+ puffer = list(bytes.fromhex("fe 06 7e 01 00 00 0b 96"))
20
+ assert p.entpacke(puffer) == [[0x7E, 0x01, 0x00, 0x00]]
21
+ assert puffer == []
22
+
23
+
24
+ def test_text_mit_umlauten():
25
+ assert p.text_literal("Grüße") == "'Gr\\u00fc\\u00dfe'"
26
+
27
+
28
+ def test_roboter_py_ist_aktuell():
29
+ """vincibot/roboter.py muss zu asynchron.py passen (sonst: python werkzeuge/erzeuge_roboter.py)."""
30
+ import importlib.util
31
+ import pathlib
32
+ wurzel = pathlib.Path(__file__).resolve().parent.parent
33
+ spez = importlib.util.spec_from_file_location("erzeuge_roboter",
34
+ wurzel / "werkzeuge" / "erzeuge_roboter.py")
35
+ assert spez is not None and spez.loader is not None
36
+ modul = importlib.util.module_from_spec(spez)
37
+ spez.loader.exec_module(modul)
38
+ assert (wurzel / "vincibot" / "roboter.py").read_text(encoding="utf-8") == modul.erzeuge()
39
+
40
+
41
+ def test_bild_bytes_wie_die_hersteller_oberflaeche():
42
+ """Erstes Pixel einer 8er-Gruppe = niedrigstes Bit (binaryToHex der Web-Oberfläche)."""
43
+ from vincibot.asynchron import VinciBotAsync
44
+ zeilen = ["#" + "." * 15, ".#" + "." * 6 + "#" + "." * 7] + ["." * 16] * 6
45
+ daten = VinciBotAsync._bild_daten(zeilen)
46
+ assert daten[0] == 0x01 and daten[1] == 0x00
47
+ assert daten[2] == 0x02 and daten[3] == 0x01
48
+ # Beispiel aus der API-Beschreibung (Auge): 0x38 = Pixel 3, 4, 5
49
+ assert VinciBotAsync._bild_daten(["...###.." + "." * 8] + ["." * 16] * 7)[0] == 0x38
50
+
51
+
52
+ def test_positionen_der_lichter():
53
+ from vincibot._woerter import POSITIONEN, POSITION_NAMEN
54
+ assert POSITIONEN["links oben"] == 1 and POSITIONEN["rechts oben"] == 6
55
+ assert POSITIONEN["rechts unten"] == 4 and POSITIONEN["links_unten"] == 3
56
+ assert POSITION_NAMEN[5] == "rechts mitte"