Metadata-Version: 2.5
Name: part2kicad
Version: 0.1.0
Summary: LCSC/EasyEDA-Bauteile als KiCad-Bibliothek, mit nachvollziehbarer Herkunft
Author: Emil Menzel
License-Expression: GPL-3.0-or-later
License-File: LICENSE
Keywords: easyeda,eda,footprint,jlcpcb,kicad,lcsc,pcb,symbol
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Manufacturing
Classifier: Natural Language :: German
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
Classifier: Topic :: Utilities
Requires-Python: >=3.11
Requires-Dist: platformdirs>=4.0
Requires-Dist: sexpdata>=1.0.2
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == 'dev'
Description-Content-Type: text/markdown

# part2kicad

Aus einer LCSC-Nummer ein fertiges KiCad-Bauteil mit **nachvollziehbarer Herkunft** —
Symbol, Footprint und 3D-Modell — direkt im eigenen Projekt.

Der Unterschied zu bestehenden Werkzeugen ist nicht die Bequemlichkeit, sondern die
Nachvollziehbarkeit. Heute heißt das: jedes erzeugte Bauteil trägt seine Herkunft als
Felder am Symbol — Quelle, Abrufdatum und Bauteilnummer, bei über die Suche geholten
Teilen zusätzlich Preis und Lagerbestand mit dem Datum ihres Abrufs. Den Bericht, der
Feld für Feld ausweist, woher ein Wert stammt und welche KLC-Regeln er erfüllt, **gibt es
heute noch nicht** — er ist das Ziel und kommt mit Phase 3.

## Stand

Frühe Entwicklung, aber der Weg von der Nummer zum eingebundenen Bauteil steht:
`part2kicad search` und `part2kicad add` erzeugen im KiCad-Projekt Symbol, Footprint und
3D-Modell und tragen beide Bibliothekstabellen ein. Was noch fehlt — Multi-Unit-Bauteile,
Normalisierung der Feldnamen, Qualitätsbericht, lokaler Zwischenspeicher — steht
vollständig unter [Bekannte Grenzen](#bekannte-grenzen).

## Voraussetzungen

- Python 3.11 oder neuer
- **KiCad 10.0 oder neuer.** Das Werkzeug ruft `kicad-cli` als eigenen Prozess auf.
  Liegt `kicad-cli` nicht im Suchpfad — unter Windows ist das der Normalfall —, wird es an
  den üblichen Installationsorten gesucht. Notfalls den Pfad ausdrücklich setzen:

  ```
  set PART2KICAD_KICAD_CLI=C:\Program Files\KiCad\10.0\bin\kicad-cli.exe
  ```

## Installation

Heute aus dem selbst gebauten Wheel:

```
uv build
uv pip install dist/part2kicad-*.whl
```

Das Paket ist ein reines `py3-none-any`-Wheel; auf dem Zielrechner wird kein Compiler
gebraucht.

**Die Veröffentlichung auf PyPI steht noch aus** und ist ein eigener Schritt, nicht ein
vergessener. Sie wirkt nach außen und lässt sich nicht zurücknehmen: sie belegt den Namen
dauerhaft und macht den Befehlszuschnitt (`search`, `add`) zur veröffentlichten
Schnittstelle, an der sich jedes Skript und jede Anleitung festmacht. Deshalb kommt sie
ans Ende und nicht in die Mitte der Entwicklung. Bis dahin gilt der Weg über `uv build`
oben; `uv pip install part2kicad` funktioniert noch nicht.

## Benutzung

```
part2kicad search rp2040          # suchen, auswählen, im selben Aufruf übernehmen
part2kicad add C2040              # wenn die Bauteilnummer schon bekannt ist
part2kicad add C2040 --force      # ein bereits vorhandenes Bauteil ersetzen
```

Das Zielprojekt wird wie bei git gesucht: vom Arbeitsverzeichnis aufwärts nach einer
`.kicad_pro`-Datei. `--project <pfad>` gibt es ausdrücklich an. Wird keines gefunden,
bricht das Werkzeug ab, statt irgendwohin zu schreiben.

`--json` gibt maschinenlesbar aus und fragt nichts, `--verbose` schreibt zu jedem Abruf
eine Zeile mit Adresse und Statuscode auf die Fehlerausgabe.

### Zweiter Import desselben Bauteils

Liegt das Bauteil schon in der Projektbibliothek, meldet `part2kicad` das samt dem Datum
des ersten Abrufs und **schreibt nichts**. Wer am Bauteil von Hand nachgebessert hat,
verliert das nicht durch einen unbedachten zweiten Aufruf. `--force` ersetzt es; ein
bereits im Schaltplan platziertes Symbol muss dort über „Symbole aus Bibliothek
aktualisieren" nachgezogen werden.

### Was am erzeugten Bauteil steht

| Gruppe | Felder |
|---|---|
| Herkunft und Nachverfolgung | `Supplier Part`, `Manufacturer`, `Manufacturer Part`, `Datasheet`, `Quelle`, `Abrufdatum` |
| Handelsdaten | `Preis` und `Lagerbestand`, jeweils mit `Preis Stand` bzw. `Lagerbestand Stand` — dem Datum des Abrufs |
| Technische Parameter | was die Quelle liefert, unter ihren **unveränderten** Feldnamen |
| Bestückung | `JLCPCB Part Class` (Basic/Extended) — sie entscheidet über die Bestückungskosten |

Preis und Lagerbestand stehen nur in der Suchantwort. Wer sie am Bauteil braucht, holt es
über `part2kicad search`; der Abruf über die Bauteilnummer liefert sie nicht mit, und
`part2kicad` erfindet keinen Preis. Alle Felder außer `Reference` und `Value` werden
versteckt angelegt, damit der Schaltplan lesbar bleibt.

## Umgang mit den Datenquellen

`part2kicad` fragt fremde Server ab, die dafür keinen Vertrag mit uns haben. Was es dabei
tut, steht hier vollständig.

### Benutzte Endpunkte

Alle Adressen stehen in `src/part2kicad/rezept.toml` und **nicht** im Programmcode.
Ändert die Gegenseite sich, ist die Reparatur eine Änderung dort — kein Programmupdate.

| Zweck | Adresse | Wann |
|---|---|---|
| Suche | `https://pro.easyeda.com/api/eda/product/search` | einmal je `search`-Aufruf |
| Geometrie (Symbol **und** Footprint) | `https://easyeda.com/api/products/{lcsc}/components` | einmal je übernommenem Bauteil |
| 3D-Modell (STEP) | `https://modules.easyeda.com/…/{uuid}` | einmal je übernommenem Bauteil, sofern eines hinterlegt ist |

Symbol und Footprint kommen aus **einem** Abruf; es gibt keinen zweiten für den
Footprint. Liegt ein Bauteil bereits in der Bibliothek, findet ohne `--force` gar kein
Abruf statt.

### Kennung

`part2kicad` meldet sich mit

```
part2kicad/<version> (+https://pypi.org/project/part2kicad/)
```

Eine ehrliche, das Produkt benennende Kennung. Ausdrücklich **nicht**: ein gefälschter
Browser-User-Agent oder ein Umbiegen der Namensauflösung, um Sperren zu umgehen. Das ist
keine Zierde — gemessen kommt der ehrliche Weg durch, und der unehrliche wäre auch dann
nicht in Ordnung, wenn er nötig wäre.

Ändern lässt sich die Kennung ohne Programmänderung: eine eigene Datei `rezept.toml` im
plattformüblichen Konfigurationsordner (Windows `%LOCALAPPDATA%\part2kicad\`, Linux
`~/.config/part2kicad/`) überschreibt **punktuell** einzelne Werte:

```toml
[kennung]
user_agent = "meine-kennung/1.0 (+https://beispiel.example)"
```

### Mindestabstände und Verhalten bei einer Sperre

Jeder Endpunkt hat sein **eigenes** Zeitbudget — die gemessene Sperre ist pfadgebunden,
ein gemeinsames Budget würde die Suche ausbremsen, sobald ein Geometrieabruf ansteht.

| Endpunkt | Mindestabstand | Höchstversuche |
|---|---|---|
| Suche | 2,5 s | 3 |
| Geometrie | 3,0 s | 3 |
| 3D-Modell | 1,0 s | 3 |

Die Gegenseite sperrt nach etwa 45 Abrufen innerhalb weniger Minuten — kumulativ, nicht
nach Spitzenrate. Sie antwortet dann mit einem nackten **HTTP 403**, ohne `Retry-After`
und ohne HTTP 429; vorhersehen lässt sich die Sperre also nicht, nur erkennen. Die Sperre
löst sich nach etwa zwei Minuten von selbst.

`part2kicad` wartet in diesem Fall, beginnend bei 120 Sekunden und je Versuch
verdoppelnd, höchstens drei Versuche — zusammen also 120 + 240 = **sechs Minuten**. Mehr
wäre außer Verhältnis: die Sperre löst sich gemessen nach rund zwei Minuten, und steht sie
nach der dreifachen Zeit noch, ist es nicht die gewöhnliche Ratenbremse; weiteres Warten
ist dann keine bessere Wette als ein Hinweis an den Nutzer. Die Wartezeit wird als
Statuszeile angezeigt — eine zweiminütige stille Pause wäre von einem Absturz nicht zu
unterscheiden, und **Strg-C** beendet sie jederzeit mit einer Meldung statt mit einem
Stapelauszug. Lässt die Gegenseite auch danach nicht locker, bricht der Aufruf mit einer
Meldung ab, die sagt, dass es nicht am eigenen Rechner liegt. Geschrieben wird dabei
nichts: solange nicht alle Bestandteile beisammen sind, bleibt die Bibliothek unberührt.

Die Zahlen stehen alle in `rezept.toml` und lassen sich in der eigenen Nutzerdatei
ändern — ein Deckel im Programmcode würde diese Möglichkeit nehmen.

### Die Ausschlussliste der Gegenseite

`easyeda.com/robots.txt` sperrt `//api/`-Pfade — und damit den Geometrie-Endpunkt. Das
wird hier offen benannt statt übergangen:

- Der Weg wird **bewusst** benutzt, weil es keinen anderen gibt, über den die CAD-Daten
  eines Bauteils zu bekommen wären.
- Er wird **minimiert**: ein Abruf je Bauteil, nie ein Vollkatalog, und bei einem bereits
  vorhandenen Bauteil gar keiner.
- Ein Ergebnisspeicher, der auch den *wiederholten* Abruf desselben Bauteils erspart,
  **gibt es heute noch nicht** — er kommt mit Phase 5. Ein zweites
  `part2kicad add C2040 --force` holt die Geometrie also ein zweites Mal. Das steht hier,
  weil eine Offenlegung, die eine noch nicht ergriffene Maßnahme aufzählt, keine ist.
- Der **Suchverkehr** — also das Volumen — läuft über `pro.easyeda.com`, das in seiner
  eigenen Ausschlussliste nur `/login` und benannte SEO-Bots führt, nicht `/api/`.

Wer das anders bewertet, kann `part2kicad add` ganz lassen und das Werkzeug nur zum
Suchen benutzen.

## Bekannte Grenzen

Ehrlich statt vollständig klingend:

- **Zwei gleichzeitige Aufrufe auf dieselbe Bibliothek können ein Symbol verlieren.** Der
  Tausch der fertigen Datei ist atomar, das Lesen-Ändern-Schreiben davor nicht. Für ein
  interaktives Einzelplatzwerkzeug ist eine Dateisperre bewusst nicht eingebaut worden.
- **macOS ist ungetestet, und auf Linux ist noch niemand gelaufen.** Entwickelt und
  geprüft wird unter Windows. Für Linux sind die Plattformannahmen statisch abgesichert —
  kein fest verdrahteter Pfad, kein Shell-Aufruf, kein Dateizugriff ohne angegebenen
  Zeichensatz, Konfigurationsordner aus `platformdirs` —, ein Lauf steht aus. Für macOS
  ist zusätzlich der Suchpfad zu `kicad-cli` hinterlegt, aber auch dort hat niemand es
  laufen lassen.
- **Bauteile aus mehreren Einheiten** werden erkannt und ausdrücklich abgelehnt, statt ein
  Symbol mit null Pins abzulegen. Das Zusammenführen kommt später.
- **Die Feldnamen der technischen Parameter bleiben, wie die Quelle sie liefert** — also
  uneinheitlich. Das Vereinheitlichen ist ein eigener Schritt und noch nicht gemacht.
- **Den Qualitätsbericht gibt es noch nicht.** Herkunft und Abrufdatum stehen als Felder
  am Bauteil; ein Bericht, der Feld für Feld die Herkunft ausweist und die geprüften
  KLC-Regeln samt Ergebnis auflistet, kommt mit Phase 3. Bis dahin ist „geprüft" die
  Zusicherung, dass jeder Wert von der Quelle stammt — nicht, dass eine Regelprüfung
  gelaufen wäre.
- **Einen lokalen Zwischenspeicher gibt es noch nicht.** Jeder Abruf geht an die
  Gegenseite; ein zweites `add … --force` holt dieselbe Geometrie erneut. Der
  Zwischenspeicher kommt mit Phase 5, siehe auch oben unter der Ausschlussliste.
- **Preis und Lagerbestand gibt es nur über `part2kicad search`**, siehe oben.

## Tests

| Lauf | Befehl |
|---|---|
| Schnelllauf, ohne KiCad | `pytest -m "not kicad and not live"` |
| Voller Lauf (Vorgabe) | `pytest -m "not live"` |
| Live-Tests gegen die echte Gegenseite | `pytest -m live --live` |

Live-Tests laufen **nie** versehentlich mit: sie brauchen sowohl die Markierung als auch den
Schalter `--live`. Tests, die ein installiertes KiCad brauchen, überspringen sich mit
sichtbarer Begründung, wenn keines gefunden wird.

## Lizenz

GPL-3.0-or-later, siehe [LICENSE](LICENSE).
