kydriv/docs/superpowers/specs/2026-06-02-kydriv-design.md

172 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# kydriv — Kyocera 3505ci Treiber für Apple Silicon
## Kontext
Der Kyocera/TA 3505ci Multifunktionsdrucker erfordert zur Nutzung einen Abteilungscode (Kostenstelle). Der bisherige Intel-Mac-Treiber bot dafür ein Textfeld im Druckdialog. Der aktuelle Apple-Silicon-Treiber von Kyocera hat diese Funktion nicht. Dieses Projekt entwickelt einen Ersatztreiber für macOS auf Apple Silicon, der die fehlenden Funktionen — insbesondere die Kostenstelle — wiederherstellt.
## Ursachenanalyse
Der alte Intel-Treiber bestand aus drei Schichten:
1. **APDialogExtension-Plugins** (`.plugin`-Bundles) — Objective-C/Cocoa-Panels im Druckdialog. Intel-only, von Apple deprecated. Zuständig für die UI (Textfelder, Checkboxen).
2. **CUPS-Filter** (`kyoprefilter_E`, `kyofilter_E`) — kompilierte Intel-Binaries. Zuständig für PostScript-Verarbeitung und Einschleusen von Gerätebefehlen.
3. **PPD-Datei** — Textdatei, architekturunabhängig.
Auf Apple Silicon fehlen die Punkte 1 und 2. Der neue Kyocera-Treiber hat nur eine abgespeckte PPD ohne die Plugin-Mechanismen.
## Lösungsansatz
**PPD + Python CUPS-Filter**, verteilt als signiertes `.pkg`.
- Die APDialogExtension-Plugins werden nicht ersetzt (deprecated API). Stattdessen werden Kostenstellen als benannte Optionen in der PPD geführt und per Preset gespeichert.
- Die Intel-Filter werden durch ein Python-Script ersetzt, das architekturunabhängig ist.
- Der Kyocera-Treiber wird vollständig umgangen — die Lösung ist eigenständig.
## Komponenten
```
kydriv/
├── ppd/
│ └── TA3505ci_AS.ppd # modifizierte PPD
├── filter/
│ └── kyofilter # Python CUPS-Filter
├── installer/
│ ├── root/ # Dateisystem-Abbild für pkgbuild
│ │ ├── Library/Printers/PPDs/Contents/Resources/TA3505ci_AS.ppd
│ │ └── usr/libexec/cups/filter/kyofilter
│ ├── scripts/
│ │ └── postinstall
│ └── build.sh
└── docs/superpowers/specs/
```
**Datenfluss:**
```
macOS App (PDF) → CUPS pdftops → PostScript → kyofilter (Python) → Drucker
```
## PPD-Datei (`TA3505ci_AS.ppd`)
Basis: `TA3505ci.PPD` (Intel-Treiber, Version 8.6006).
**Entfernt:**
- Alle 11 `*APDialogExtension:`-Zeilen
- `*cupsPreFilter: "application/pdf 0 kyoprefilter_E"`
**Geändert:**
```diff
- *cupsFilter: "application/vnd.cups-postscript 0 kyofilter_E"
+ *cupsFilter: "application/vnd.cups-postscript 0 kyofilter"
```
**KmManagment-Sektion** (ersetzt die alte Liste 0000000000000030):
```ppd
*% Kostenstelle (5-stellig) direkt eintragen — keine führenden Nullen nötig.
*% Zeile kopieren und Zahl ersetzen:
*% *KmManagment MG12345/Code 12345: ""
*OpenUI *KmManagment/Job Accounting: PickOne
*DefaultKmManagment: Default
*OrderDependency: 60 AnySetup *KmManagment
*KmManagment Default/Aus: ""
*KmManagment MG12345/Code 12345: ""
*?KmManagment: ""
*End
*CloseUI: *KmManagment
```
Der PPD-Wert bleibt leer (`""`), da der Filter die PostScript-Injection übernimmt.
**Unverändert:** alle anderen Optionen — InputSlot, PageSize, KCStaple, OutputBin, Duplex, Farbe etc.
## Python CUPS-Filter (`kyofilter`)
**Installationspfad:** `/usr/libexec/cups/filter/kyofilter`
**Rechte:** 755, root:wheel
**Interpreter:** `/usr/bin/python3` (macOS vorinstalliert)
**CUPS-Schnittstelle:**
```
kyofilter <job-id> <user> <title> <copies> <options> [filename]
```
- Eingabe: PostScript (stdin oder Datei)
- Ausgabe: PostScript (stdout)
- Logs: stderr → CUPS error_log
**Logik:**
1. `argv[5]` parsen → Key=Value-Dict
2. `KmManagment`-Wert lesen
3. Startet mit `MG` und ist numerisch → Code extrahieren, auf 8 Stellen zero-padden
4. Sonst → reiner Passthrough
5. PostScript-Stream zeilenweise lesen:
- Vor `%%EndSetup`: `(XXXXXXXX) statusdict /setmanagementnumber get exec` injizieren
- Alle anderen Zeilen unverändert weiterleiten
6. Fallback: falls kein `%%EndSetup` gefunden → vor erstem `%%Page:` injizieren, Warning ins Log
**Beispiel:** Kostenstelle `12345``(00012345) statusdict /setmanagementnumber get exec`
## Installer (`.pkg`)
**Gebaut mit:** `pkgbuild` + Developer ID Installer Zertifikat
**Bundle-ID:** `de.kydriv.driver`
```bash
pkgbuild \
--root installer/root \
--scripts installer/scripts \
--identifier "de.kydriv.driver" \
--version "1.0.0" \
--sign "Developer ID Installer: NAME (TEAM-ID)" \
kydriv-driver-1.0.0.pkg
```
**postinstall-Script:**
```bash
#!/bin/bash
chmod 755 /usr/libexec/cups/filter/kyofilter
chown root:wheel /usr/libexec/cups/filter/kyofilter
launchctl kickstart -k system/org.cups.cupsd
```
**Notarisierung** (einmalig pro Release):
```bash
xcrun notarytool submit kydriv-driver-1.0.0.pkg \
--apple-id EMAIL --team-id TEAM-ID --password APP-PASSWORT --wait
xcrun stapler staple kydriv-driver-1.0.0.pkg
```
Notarisierte `.pkg`-Dateien bleiben dauerhaft gültig, auch nach Ablauf des Entwicklerzertifikats.
## Benutzer-Workflow nach Installation
1. Kostenstelle in PPD eintragen (einmalig, Texteditor)
2. `.pkg` installieren
3. Drucker in Systemeinstellungen hinzufügen → `TA3505ci_AS.ppd` auswählen
4. Druckdialog → Job Accounting → eigene Kostenstelle wählen
5. Preset speichern
6. Ab sofort: Preset auswählen → drucken
## Testing
Stufen 12 sind offline durchführbar. Stufen 35 erfordern eine aktive VPN-Verbindung zum Büronetz, da der Drucker nur darüber erreichbar ist.
| Stufe | VPN | Methode | Erfolgskriterium |
|-------|-----|---------|-----------------|
| 1 | Nein | Filter mit Beispiel-PS über stdin aufrufen | Injection vor `%%EndSetup` im Output |
| 2 | Nein | `cupstestppd ppd/TA3505ci_AS.ppd` | Ausgabe: PASS |
| 3 | Ja | Manuelle Installation, Testseite drucken | Seite kommt raus |
| 4 | Ja | CUPS-Log + Kyocera-Webinterface Job-Log | Kostenstelle korrekt erfasst |
| 5 | Ja | `.pkg` auf frischem System installieren | End-to-End-Workflow funktioniert |
## Hinweise
**Koexistenz mit Kyocera-Treiber:** Der vorhandene Kyocera Apple-Silicon-Treiber muss nicht entfernt werden. Beim Hinzufügen des Druckers in den Systemeinstellungen wählt man einfach unsere PPD (`TA3505ci_AS.ppd`) statt der Kyocera-PPD. Beide können nebeneinander existieren.
**Kostenstellen eintragen:** Vor dem ersten Build trägt der Benutzer seine Codes in die PPD ein (Abschnitt KmManagment). Format: `*KmManagment MG12345/Code 12345: ""` — die 5-stellige Zahl direkt, ohne führende Nullen. Zero-Padding übernimmt der Filter.
## Nächste Schritte
- Verifizieren, dass `setmanagementnumber` auf dem 3505ci die Kostenstelle korrekt bucht (Testing Stufe 4)
- Ggf. weitere Kyocera-spezifische PPD-Optionen aus dem alten Treiber prüfen