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

6.4 KiB
Raw Blame History

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:

- *cupsFilter: "application/vnd.cups-postscript 0 kyofilter_E"
+ *cupsFilter: "application/vnd.cups-postscript 0 kyofilter"

KmManagment-Sektion (ersetzt die alte Liste 0000000000000030):

*% 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

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:

#!/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):

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

Stufe Methode Erfolgskriterium
1 Filter mit Beispiel-PS über stdin aufrufen Injection vor %%EndSetup im Output
2 cupstestppd ppd/TA3505ci_AS.ppd Ausgabe: PASS
3 Manuelle Installation, Testseite drucken Seite kommt raus
4 CUPS-Log + Kyocera-Webinterface Job-Log Kostenstelle korrekt erfasst
5 .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