Skip to content

Galadiner


Theodor W. Adorno, Heidelberg 1964
Foto: Jeremy J. Shapiro
Lizenz: CC BY-SA 3.0
Wie Fortschritt und Regression heute sich verschränken, ist am Begriff der technischen Möglichkeiten zu lernen. Die mechanischen Reproduktionsverfahren haben sich unabhängig von dem zu Reproduzierenden entfaltet und verselbständigt.

Sie gelten für fortschrittlich, und was an ihnen nicht teilhat für reaktionär und krähwinklerisch. Solcher Glaube wird um so gründlicher gefördert, als die Superapparaturen, sobald sie irgend ungenützt bleiben, in Fehlinvestitionen sich zu verwandeln drohen. Da aber ihre Entwicklung wesentlich das betrifft, was unterm Liberalismus Aufmachung hieß, und zugleich durch ihr Eigengewicht die Sache selber erdrücke, der ohnehin die Apparatur äußerlich bleibe, so hat die Anpassung der Bedürfnisse an diese den Tod des sachlichen Anspruchs zur Folge. Der faszinierte Eifer, die jeweils neuesten Verfahren zu konsumieren, macht nicht nur gegen das Übermittelte gleichgültig, sondern komme dem stationären Schund und der kalkulierten Idiotie entgegen. Sie bestätigt den alten Kitsch in immer neuen Paraphrasen als haute nouveauté. Auf den technischen Fortschritt antwortet der

trotzige und bornierte Wunsch, nur ja keinen Ladenhüter zu kaufen, hinter dem losgelassenen Produktionsprozeß nicht zurückzubleiben, ganz gleichgültig, was der Sinn des Produzierten ist. Mitläufertum, das sich Drängeln, Schlange Stehen substituiert allenthalben das einigermaßen rationale Bedürfnis. Kaum geringer als der Haß gegen eine radikale, allzu moderne Komposition ist der gegen einen schon drei Monate alten Film, dem man den jüngsten, obwohl er von jenem in nichts sich unterscheidet, um jeden Preis vorzieht. Wie die Kunden der Massengesellschaft sogleich dabei sein wollen, können sie auch nichts auslassen. Wenn der Kenner des neunzehnten Jahrhunderts sich nur einen Akt der Oper ansah, mit dem barbarischen Seitenaspekt, daß er sein Diner von keinem Spektakel sich mochte verkürzen lassen, so kann mittlerweile die Barbarei, der die Auswegsmöglichkeit zum Diner abgeschnitten ist, an ihrer Kultur sich gar nicht sattfressen. Jedes Programm muß bis zu Ende abgesessen, jeder best seller gelesen, jeder Film während seiner Blütetage im Hauptpalast beguckt werden. Die Fülle des wahllos Konsumierten wird unheilvoll. Sie macht es unmöglich, sich zurechtzufinden, und wie man im monströsen Warenhaus nach einem Führer sucht, wartet die zwischen Angeboten eingepeilte Bevölkerung auf den ihren.

Theodor W. Adorno - Minima Moralia

Einen Blick auf Klipper riskieren

Screenshot
Ich habe das schlechte Wetter heute genutzt, um ein wenig mit der Firmware des AnyCubic i3 MEGA herum zu spielen. Normalerweise läuft hier Marlin, mich hatte aber interessiert, was hinter dem OctoPrint Plugin OctoKlipper steckt. Man muss ja elastisch bleiben. Dabei kam heraus, daß mit Klipper eine weitere Möglichkeit zur Steuerung der Druckerei besteht. Mindestens genau so frickelig wie Marlin, das Display des Druckers wird (leider) gar nicht unterstützt, auch sonst muss man sich halbwegs ordentlich einlesen, um den Drucker überhaupt in Betrieb nehmen zu können. Das ist auch gut so, denn nur so lassen sich Schäden am Drucker oder Druckgut oder schlimmer: an Leib und Leben verhindern.

Grob gesagt unterscheidet Klipper sich von Marlin darin, daß nur ein kleiner Bootloader auf dem Drucker selber verbleibt, der dann mit dem Hostrechner - zum Beispiel einem RaspBerry PI kommuniziert und diesem die ganze Rechenarbeit überlässt. Diese Arbeit stellt die Himbeere vor keine besonders großen Herausforderungen, trotzdem sollte man möglichst zum RaspBerry Pi 3B+ greifen. Zur Installation verweise ich mal auf das Tutorial bei selbstgedruckt.de, die Menschen dort beteiligen sich auch rege in einem deutschsprachigen Fratzenbuch Forum.

Für den AnyCubic i3 Mega habe ich als Einstieg zwar die entsprechende Beispielkonfigurationsdatei auf github verwendet, da unser Drucker jedoch wegen ungebührlichen Lärmens zu einem Austausch der Lüfter (Noctua NF-A4x10 FLX 40mm zur Kühlung von Hotend und der Treiber über den Lüftungskanal hier auf thingiverse und Noctua NF-A9x14 Lüfter für das Netzteil sowie Sunon MF50151VX-A99 Radiallüfter zur Bauteilkühlung) und der Steppertreiber auf TMC2208 V1.2 verdonnert wurde, mussten die Achsen der Steppermotoren invertiert werden. Es gibt u.a. auch in der FAQ zu Klipper den Hinweis, daß die TMCs mitten im Druck aussteigen können. Das ist wohl vor allem dann der Fall, wenn die Geschwindigkeit der Achsen zu sehr hoch gesetzt wurden. (Es soll ja Leute geben, die unter Klipper mit 100mm/sec statt mit 60mm/sec drucken, tstststss...)

Bislang konnte ich derartiges Verhalten bei uns nicht beobachten. Mit der in diesen Tagen erscheinenden neuen Klipper Version sollen jedoch wohl auch diese Problem gelöst sein.

Wie auch immer: Erwähnenswert ist, daß diverse G-Code Variablen zu seltsamem Verhalten führen können. Das betrifft jedoch meistens Start- oder Endcodes sowie diverse Plugins von OctoPrint, die z.B. mit G117 eine Bildschirmausgabe erzeugen wollen.

Ein Switchen zwischen Marlin und Klipper ist problemlos möglich und in 5 Minuten bewerkstelligt, falls mal etwas nicht so klappt, wie es soll. Ich schließe zur Installation von Marlin über die Arduino IDE den ausgeschalteten Drucker via USB an meinen Rechner an, starte die Arduino IDE und wähle kompilieren / hochladen, nachdem ich den Drucker eingeschaltet habe. Das bügelt alles von Klipper weg.

Umgekehrt installiere ich Klipper, indem ich mich als pi per ssh auf dem OctoPI/OctoPrint Server anmelde, mit

cd ~/Klipper

ins Klipper Verzeichnis wechsle und dann erst mal herausfinde, auf welchem USB Port denn der jetzt am OctoPI angeschlossene Drucker lauscht. Dazu

ls -l /dev/serial/by-id/

eingeben, den ausgegebenen Port merken und dann beherzt den Klipper Bootloader mit

make flash FLASH_DEVICE=/dev/gemerkterPort

auf den Drucker kopieren. Dazu sollte man beachten, daß der Drucker nicht mit OctoPrint verbunden ist. Am besten danach rebooten, dann klappt das mit dem Drucken. ;-)

Hier noch mein config File für den AnyCubic i3 MEGA mit TNC2208 V1.2, und 8 Bit Board sowie Ultrabase. Die Achsen sind in der Firmware bereits invertiert, dazu ist das "!" vor den jeweiligen dir_pin gesetzt bzw. entfernt. Die Angaben für das PID Tuning beziehen sich auf meinen Drucker, bei anderen sollte das PID über das OctoKlipper Plugin gemacht werden. In Ergänzung zur Standard Config befindet sich ein Teil zur Regelung der Temperaturtoleranzen, ohne die mein Drucker nach wenigen Layern gleich ausgestiegen ist, die ich 1:1 aus der examples-extras.cfg Datei von Klipper entnommen habe. Noch nicht gekümmert habe ich mich um die anderen Gründe, warum ich mal einen Blick auf Klipper riskiere wie schnelleres und noch schöneres Drucken, schnellere Filamentförderung - Stichwort "pressure advance", Kaffee kochen und die Wäsche waschen...

# Anpassung der Pin Mappings für den AnyCubic i3 MEGA, TMC2208 und Ultrabase 
#
# Verwendung auf eigene Gefahr! Code kopieren und in octopi.url#conf einfügen
# 12 / 12 / 2018 thomas@trueten.de still under developement
#
# https://www.trueten.de/permalink/Einen-Blick-auf-Klipper-riskieren.html
#
#
# This file contains pin mappings for the Anycubic i3 Mega with
# Ultrabase from 2017. (This config may work on an Anycubic i3 Mega v1
# prior to the Ultrabase if you comment out the definition of the
# endstop_pin in the stepper_z1 section.) To use this config, the
# firmware should be compiled for the AVR atmega2560.
# See the example.cfg file for a description of available parameters.

[stepper_x]
step_pin: ar54
dir_pin: ar55
enable_pin: !ar38
step_distance: .0125
endstop_pin: ^!ar3
position_min: -5
position_endstop: -5
position_max: 210
homing_speed: 30.0

[stepper_y]
step_pin: ar60
dir_pin: !ar61
enable_pin: !ar56
step_distance: .0125
endstop_pin: ^!ar42
position_endstop: 0
position_max: 210
homing_speed: 30.0

[stepper_z]
step_pin: ar46
dir_pin: !ar48
enable_pin: !ar62
step_distance: .0025
endstop_pin: ^!ar18
position_endstop: 0.0
position_max: 205
homing_speed: 5.0

[stepper_z1]
step_pin: ar36
dir_pin: !ar34
enable_pin: !ar30
step_distance: .0025
endstop_pin: ^!ar43

[extruder]
step_pin: ar26
dir_pin: !ar28
enable_pin: !ar24
step_distance: .010799
nozzle_diameter: 0.400
filament_diameter: 1.750
heater_pin: ar10
sensor_type: ATC Semitec 104GT-2
sensor_pin: analog13
control: pid
min_temp: 0
max_temp: 260
min_extrude_temp: 170

[heater_fan extruder_fan]
pin: ar44

[heater_bed]
heater_pin: ar8
sensor_type: EPCOS 100K B57560G104F
sensor_pin: analog14
control: pid
pid_Kp: 74.883
pid_Ki: 1.809
pid_Kd: 775.038
min_temp: 0
max_temp: 110

[verify_heater extruder]
heating_gain: 2
check_gain_time: 20
hysteresis: 5
max_error: 120

[fan]
pin: ar9

[mcu]
serial: /dev/ttyUSB0
pin_map: arduino

[printer]
kinematics: cartesian
max_velocity: 300
max_accel: 3000
max_z_velocity: 10
max_z_accel: 60

[heater_fan stepstick_fan]
pin: ar7

# Define the BLTouch servo
[servo bltouch]
pin: ar11
maximum_servo_angle: 180
minimum_pulse_width: 0.0006
maximum_pulse_width: 0.0024

# Define a probe using the BLTouch
[probe]
pin: ar2
x_offset: 26.0
y_offset: 0.0
z_offset: -1.7
activate_gcode:
    SET_SERVO SERVO=bltouch ANGLE=10
    SET_SERVO SERVO=bltouch ANGLE=60
    G4 P200
deactivate_gcode:
    SET_SERVO SERVO=bltouch ANGLE=90
    G4 P100

# Mesh Bed Leveling. One may define a [bed_mesh] config section
# to enable move transformations that offset the z axis based
# on a mesh generated from probed points. Note that bed_mesh
# and bed_tilt are incompatible, both cannot be defined.
[bed_mesh]
speed: 50
#   The speed (in mm/s) of non-probing moves during the
#   calibration. The default is 50.
horizontal_move_z: 5
#   The height (in mm) that the head should be commanded to move to
#   just prior to starting a probe operation. The default is 5.
samples: 1
#   The number of times to probe each point.  The probed z-values
#   will be averaged.  The default is to probe 1 time.
sample_retract_dist: 2.0
#   The distance (in mm) to retract between each sample if
#   sampling more than once.  Default is 2mm.
min_point: 19,32
#min_point: 0,32
#   An X,Y point defining the minimum coordinate to probe on
#   the bed. Note that this refers to the nozzle position,
#   and take care that you do not define a point that will move
#   the probe off of the bed. This parameter must be provided.
max_point: 199,212
#max_point: 175,198
#   An X,Y point defining the maximum coordinate to probe on
#   the bed. Follow the same precautions as listed in min_point.
#   Also note that this does not necessarily define the last point
#   probed, only the maximum coordinate. This parameter must be provided.
probe_count: 5,5
#   A comma separated pair of integer values (X,Y) defining the number
#   of points to probe along each axis. A single value is also valid,
#   in which case that value will be for both axes. Default is 3,3
#   which probes a 3x3 grid.
#fade_start: 1.0
#   The z-axis position in which to start phasing z-adjustment out.
#   Default is 1.0.
#fade_end: 0.0
#   The gcode z position in which phasing out completes.  When set
#   to a value below fade_start, fade is disabled. It should be
#   noted that fade may add unwanted scaling along the z-axis of a
#   print.  If a user wishes to enable fade, a value of 10.0 is
#   recommended. Default is 0.0, which disables fade.
#fade_target:
#   The z position in which fade should converge. When this value is set
#   to a non-zero value it must be within the range of z-values in the mesh.
#   Users that wish to converge to the z homing position should set this to 0.
#   Default is the average z value of the mesh.
#split_delta_z: .025
#   The amount of Z difference (in mm) along a move that will
#   trigger a split. Default is .025.
#move_check_distance: 5.0
#   The distance (in mm) along a move to check for split_delta_z.
#   This is also the minimum length that a move can be split. Default
#   is 5.0.
#mesh_pps: 2,2
#   A comma separated pair of integers (X,Y) defining the number of
#   points per segment to interpolate in the mesh along each axis. A
#   "segment" can be defined as the space between each probed
#   point. The user may enter a single value which will be applied
#   to both axes.  Default is 2,2.
#algorithm: lagrange
#   The interpolation algorthm to use. May be either "langrange"
#   or "bicubic". This option will not affect 3x3 grids, which
#   are forced to use lagrange sampling.  Default is lagrange.
#bicubic_tension: .2
#   When using the bicubic algoritm the tension parameter above
#   may be applied to change the amount of slope interpolated.
#   Larger numbers will increase the amount of slope, which
#   results in more curvature in the mesh. Default is .2.

#*# <---------------------- SAVE_CONFIG ---------------------->
#*# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated.
#*#
#*# [extruder]
#*# pid_kp = 18.387
#*# pid_ki = 0.936
#*# pid_kd = 90.325


HINWEIS:
Alle gemachten Angaben sind ohne Gewähr auf Funktion und Richtigkeit. Für eventuell entstehende Schäden übernehmen wir keinerlei Haftung. Sämtliche Veränderungen geschehen auf Eure Verantwortung und Gefahr.

Das Tutorial ist für das AnyCubic i3 MEGA Board verfasst worden. Bei anderen Boards und Herstellern bitte auf die aktuelle Beschreibung / Installationsanweisung auf https://github.com/KevinOConnor/klipper achten!

Irgendwie muss ich das alles finanzieren, daher sind die allermeisten Links Affiliate. D.h.: Solltet Ihr über diese Links zu einem Onlinehändler geraten und dort etwas bestellen, bekomme ich eine kleine Provision, für Euch ändert das am Preis natürlich nichts. Für die Inspirationen geht ein herzliches Dankeschön an die genannten Personen, insbesondere an die OctoPrint Community!

Keep on Coding Printing!

OnePlus 6T: Kaum da, schon gerootet ;-)

Zur Abwechslung mal wieder was über Telefone. Nach 4 Jahren mit dem OnePlus One, dem so allmählich die Puste ausging, war es mir mal nach Veränderung, so orderte ich mir eine neue Telefonzelle. Es musste mit 256 GB internem Speicher und 8 GB RAM natürlich gleich der dickste Bolzen sein. ;-) Da mich die Qualität des Gerätes und die Community in den letzten Jahren überzeugte - in unserem Haushalt werkelt ja auch noch ein OnePlus 3T - war eigentlich klar, daß ich markentreu bleibe. Das vor 5 Monaten erschienene 6er Modell hätte mich eigentlich schon gereizt, aber ich dachte mir, bau nochmal einen Austauschakku ein, vielleicht hält das Teil ja nochmal 4 Jahre durch. Naja, der Akku war bzw. ist ok, auch der Austausch war in 20 Minuten erledigt. Dennoch: Die heutige Software zieht schon etwas mehr Strom und letztlich reichte das nicht einmal mehr über den Tag.

Tests zum 6T gibt es genügend, für mich gab es keinen Grund mehr, zu Googles "Pixel" zurückzukehren, nachdem die Preispolitik der vergangenen Jahre konsequent fortgesetzt und dafür an der 1000€ Marke gekratzt wird. Ein Thema, bei dem Durchgeknallte, die mit einem iPhone "X" herumposen - wohl nur zu einem müde Lächeln können. Aber irgendwie bekommt Apple das mit den Mondpreisen schon zu spüren.

Wie auch immer, nachdem OnePlus sein 6T vor 14 Tagen vorgestellt hatte kam es am Dienstag zur Auslieferung, meines bekam ich dann gestern geliefert. Während ich einem Familienmitglied beim Umstieg von einem ebenfalls 4 Jahre alten iPhone auf ein 6T unterstützte, fand ich noch die Zeit, nach einer Lösung zum Rooten für das 6T, denn ich hätte ja doch ganz gerne meine diversen Apps 1:1 wieder auf dem neuen Handy. Mittels Titanium BackUp kein Problem, allerdings setzt das Root voraus. Kein Problem1:

blu_spark TWRP für das OnePlus 6T
dann noch

Magisk herunterladen


Bei uns an den Linux Rechner gehängt, nachdem ich das 6T eingeschaltet und einen "alles überspringen" Setup Lauf durchgeführt hatte, bin ich in die Einstellungen / Über das Telefon / 7 * auf "Build Number" tippen, um den Entwicklermodus freizuschalten, dann wieder in "Einstellungen / System / Entwickleroptionen" und dort "OEM Entsperrung", "USB-Debugging" und "USB-Debugging Authorisierungen aufheben" aktivieren und dem angeschlossenen Rechner Zugriffsrechte erteilen. (Am besten auch noch "erweiterter Neustart" aktivieren, aber das ist Komfortzone.)

Sodann als root berechtigter User das folgende in die Linux Kommandozeile 2 reinhacken:

fastboot oem unlock

Schwupps - so schnell ist das Handy platt. Genau: beim Entsperren des Bootloaders werden alle Daten gelöscht. Das macht nichts, da ich noch keine Daten darauf habe und deswegen ja auch im "alles überspringen" Setup Lauf unterwegs war ;-)

Nach dem Aufheben der OEM Sperre und der Freischaltung können nun TWRP, der blu_spark Kernel und Magisk installiert werden. Mit

fastboot boot twrp-3.2.3-x_blu_spark_v9.86_op6.img

wird das neue Recovery gebootet, anschließend erlaubt man Änderungen durch Wischen auf dem im unteren Bildschirrm angebotenen Schieberegler. Dann wird in dem nächsten Bildschirm unter "Advanced" der Menüpunkt"ADB Sideload" gewählt, "Wipe Dalvik Cache" und "Wipe Cache" gewählt und dann der ADB Zugriff durch Wischen am Schieberegler im unteren Bildschirmrand ermöglicht, der dann auf dem Computer per sideload aufs 6T gebügelt wird:

adb sideload twrp-3.2.3-xblusparkv9.86op6.zip

Dann kann z.B. mit dem blu_spark Kernel eine Alternative zum regulären Systemkern installiert werden:

adb sideload blusparkr56-oos-pieop6-6t9e9a352.zip

Als Abschluß gibt es dann noch die Installation von Magisk per sideload:

adb sideload Magisk-v17.3.zip

Dann lösche ich eigentlich immer den Cache und starte das Handy neu. Magisk lässt sich zukünftig dann direkt aus der App updaten.

Diese im Gegensatz zu früheren root / Flash Aktionen scheinbar etwas umständlichere Methode der Recovery Installation hängt mit den A/B Partitionen zusammen, die ursprünglich mit Googles Pixel 1 eingeführt und für mehr Sicherheit sorgen sollen. So existiert im Gegensatz zu früheren Versionen keine eigene Recovery Partition mehr, sondern das Recovery ist Bestandteil des Boot Images. Grob gesagt muss deshalb TWRP temporär gebootet werden, um erst mit einem weiteren Installationslauf in einem der Slots eingerichtet zu werden. Die beiden Slots sind in TWRP selbst auch anwählbar, zum Beispiel beim Backup. Auch beim Neustart aus dem Recovery lässt sich der gewünschte Slot wählen.

Die verwendete (inoffizielle) blue_spark TWRP 3.2.3-x Recovery Version v9.86 ist noch in einem recht frühen Entwicklungsstadium, das sollte man bedenken, ebenso wie die angepasste Magisk Version. Zum Beipiel läuft hier das Xposed Modul leider noch nicht, auch gibt es in Sachen LineAgeOS bis jetzt auch nur inoffizielle Versionen. Hier habe ich mich auch noch nicht dazu durchgerungen, auf den Zug aufzuspringen. Aber was nicht ist, kann ja noch werden. Momentan schaue ich mir noch sehr wohlwollend das installierte OxygenOS 9.05 an, das unmittelbar nach dem TWRP Flash zum Download bereit stand.

Die A/B Partitionen können wie alles andere in dem kurzen Beitrag hier dargestellte zu Problemen führen, bis dahin, das OnePlus 6T in einen 629€ teuren Briefbeschwerer zu "bricken". Von daher: Alles, was bei mir geklappt hat, kann woanders ins Auge gehen, daher: Nachahmung auf eigene Gefahr, informiert Euch zuvor über die möglichen Folgen, zum Beispiel auch über eventuellen Garantieverlust!

In dem Sinne freue ich mich über Hinweise, Vorschläge, Alternativen und Kritiken, gerne über die Kommentarfunktion!

1: Wem das zu stressig / langweilig / riskant / whatever ist, der kann natürlich auch per OnePlusSwitch bequem von einem alten Android Handy - und auch von iPhones - auf das neue umsteigen. Die App, die in Googles Play Store für Android und hier - leider außerhalb von dem Apple Dingens erhältlich und daher nicht ganz ungefährlich - zu installieren ist, erleichtert einem den Umzug doch sehr, indem ein Barcode auf dem alten durch das neue Handy abzufotografieren ist. Binnen kurzer Zeit landen dann alle Fotos und sonstigen Daten auf dem neuen Gerät.

2: Windows kann das natürlich auch. Möglicherweise gibt es dabei einiges zu beachten, daher verweise ich auf die DroidWiki Anleitung hier.

In diesem Beitrag sind einige Links auf Amazon und eBay gesetzt. Wenn Ihr über diese Links dort etwas bestellt, bekomme ich eine kleine Provision. Irgendwie muss die Kohle für das 629€ teure Teil ja wieder reinkommen. ;-) Für Euch bleibt der Preis derselbe wie bei einem Direktkauf.

Error 7: Modem- Firmwareupdate beim OnePlus3T

Ein kurzer Merkbeitrag zu einem Modem / Firmware Problem des OnePlus 3T, der beim Flashen eines beliebigen LineageOS Updates auftreten kann und sich mit dem Abbruch des Flashvorgangs mit der folgenden Fehlermeldung äußert:

"assert(op3.verify_modem("2017-06-27 21:43:31") == "1");"

Die Ursache besteht darin, daß das Handy zwischenzeitlich ein Upgrade der Firmware erhalten hatte, das jedoch in den LineageOS Zips nicht enthalten ist, von diesen aber erwartet wird. Zwischenzeitlich hatte ich mir so geholfen, daß ich in der Zip Datei vor jedem Flash Vorgang die Abfrage des Handymodells manuell geändert hatte.

Dazu im Archiv das Updater Script /META-INF/com/google/android/updater-script mit einem Texteditor öffnen und sämtliche Zeilen mit "assert" und "getprop" Einträgen löschen. Abspeichern und installieren. Klappt problemlos und ermöglicht, falsche Systeme auf dem Handy zu installieren und dies zu bricken. ;-)

Also ein funktionierernder Workaround, jedoch ziemlich weit entfernt von einem automatisierungsfähigen Vorgehen. Zufällig bin ich dann über den Eintrag von Lord Boeffla (Vielen Dank dafür!) bei XDA gestolpert, einem Entwickler von Kernelhacks für die OnePlus Geräte, der die Firmwareupgrades aus dem originalen OxygenOS extrahiert und auch für andere OS zur Verfügung gestellt hat. Diese Datei sollte auf einem der üblichen Wege auf das 3T verbracht und dann per TWRP geflasht werden. Danach klappt es endlich auch wieder mit dem automatischen Update auf die aktuellste LineageOS Version.

Edit: Für den (eher unwahrscheinlichen) Fall, das man das 3T gebrickt hat, findet sich hier einige Hinweise, das Ding wieder ans Laufen zu bekommen.

RaspBerry Pi: Überallklingel 1.2

Zu Beschleunigung der Zustellung dringend erwarteter Pakete habe ich mich in der Vergangenheit aller möglichen Tricks bedient:

• Duschen.
• Auf dem Klo sitzen.
• Im Keller oder auf dem Dachboden herum lungern.
• Verschlafen.
• Am Fenster auf das gelbe Fahrzeug warten.
• ...

Klappt im Grunde alles nicht richtig. Irgendwie war doch immer eine Benachrichtigung im Briefkasten, mit dem Vorwurf, der / die ZustellerIn hätte mich oder einen anderen Vertreter meiner Sippschaft nicht angetroffen.

Daher kam das Überallklingel Projekt der c't 17/2017, S. 84 wie gerufen. Flugs einen Pi Zero W (*) herausgekramt, einen Widerstand, eine Diode und einen Optokoppler auf ein Stück Lochrasterplatine gelötet und dann beherzt an das Kabelwirrwar der heimischen Siedle HT401a-01 Telefonanlage angeschlossen. Nach der Installation der Telefonanlagensoftware Asterisk und wenigen Stunden Konfigurationsarbeit funktionierte das ganze sehr schön. Bis die Postboten ihre Taktik änderten und die Klingel ungeduldig bearbeiteten, derweil bereits etwas ältere Blogger die Treppe zur Sprechanlage hoch schnauften. Einige dieser Schlingel verstiegen sich dann wohl in die Vermutung, der Paketempfänger sei nicht zu Hause und machten sich daraufhin hurtig davon.


Damit es mal wieder so richtig wie bei Mr. Beaker in den Ohren klingelt ;-)

Klar, daß mensch dieser unvorteilhaften Situation nicht tatenlos zusehen konnte. Eine Erweiterung der Fähigkeiten der Überallklingel war vonnöten. Wenn der RaspBerry Pi(*) ein Signal (von der Klingel) empfangen und dies an die Telefone, die an der FritzBox(*) hängen weiter leiten kann, dann kann man davon ausgehen, daß er ein solches auch von diesen Telefonen aus (an den Türöffner) senden kann.

Dabei müssen zwei Probleme gelöst werden:

  • Wie kann man den Bengel dazu überreden, die 12Volt Spannnung zu vertragen?
  • Wie muss die vohandene Asterisk Installation erweitert werden, um ein Telefonsignal in eine Aktion des Türöffners zu verwandeln?

Die Suche bei einer beliebigen Internetsuchmaschine ergibt zum ersten Problem hunderte Vorschläge, die darauf hinauslaufen, selbiges mittels Relais zu lösen. Ich habe hier dann die Schaltung von xgadget sowie die Anleitung von 4hf übernommen. Die Relais gibt es über die dortigen Quellen zu erwerben oder eben auf Amazon oder in der Bucht. Ja nachdem, was man schalten will, kauft man eben bis zu 16-fach Relais, die dann jedoch ein eigenes Netzteil benötigen.

Der Relaisanbieter gibt es viele, vermutlich kommen die Bauteile jedoch aus der selben chinesischen Fabrik und werden nur entsprechend Anbieter gebrandet. Wie auch immer: Ich habe für unsere Klingel ein 2 Kanal Relais Modul(*) verwendet. Dieses ist zwar größer als das Einfach Modul, kostet meist jedoch weniger. Komisch? So ist der Kapitalismus nun mal, auch in China. (Stimmt nicht! Hier gibt es die Dinger sogar für 0,88€ plus 1€ Versandkosten!(*))

Doch genug der Ideologie, zurück zur Klingel. Die Signalseite des Relais mit den gewünschten Pins des Raspberry Pi GPIO verdrahten und dann die Lastseite parallel zum Türöffner der Sprechanlage geschaltet. Meistens fangen hier die Probleme an. Sprechanlagen aus der Steinzeit? Kein Problem. Was hatte ich mich aber über die Nachrichten des Postboten und die Anrufe von Familienmitglieder gewundert: Angeblich sei niemand zuhause gewesen. Solche Banditen! Oder sollte etwa...?

Es bleibt kompliziert.

Auch bei Sprechanlagen aus der Steinzeit besteht die Möglichkeit, daß diese nicht nur zur Kommunikation mit der Klingel an der Haustüre, sondern auch zur selbigen mit Etagentelefonen, Klingeln an der Wohnungstüre und anderen Gerätschaften vorgesehen waren. Was bei uns der Fall war und dafür sorgte, daß die Klingel zwar klingelte, wenn diese vor der Wohnungstüre betätigt wurde, jedoch nicht von der Haustüre aus. Getestet hatte ich natürlich nur von der Wohnungstüre aus 8-)

Nachdem auch dieses nicht unerhebliche Problem gelöst war, stand erneuten Versuchen nichts im Wege. Außer Asterisk. Dies ist ja nun nicht gerade ein einfaches Telefonanlagenprogramm, sondern doch schon ein relativ mächtiges Werkzeug, mit dem durchaus auch die Kommunikation von Callcentern oder Konzernzentralen mit dazugehörigen Videoanlagen, Faxgeräten, IP-Telefonie usw. geregelt werden kann. Mit Kanonen auf Spatzen? Wenn's hilft. Zum Glück ist Asterisk skalierbar und es gibt auch eine ausgezeichnete Dokumentation, das Asterisk Buch im Netz.

Leider erfordern umfangreiche Programme etwas Einarbeitung. Deshalb gibt es auch Alternativen wie DoorPi. Im Vergleich zu Asterisk deutlich überschaubarer und auch hinsichtlich Home 4.0 sicherlich sinnvoll. Wenn nicht die Klingel schon auf der Grundlage von Asterisk funktioniert hätte und die DoorPi Lösung ebenso gut dokumentiert wäre. Nach einem kurzen Seitenblick habe ich DoorPi deshalb zur Seite gelegt.

Konzentriert

Die Überallklingel wurde über ein Python Script ausgelöst, das .call Dateien im Outbound von Asterisk anlegt, sobald ein (Klingel)Signal auf ausgewählten GPIO Pins anliegt. Asterisk reagiert auf die .call Datei und setzt deren Inhalt in Aktionen, in dem Fall in einem Anruf bei der Rundrufnummer der FritzBox um. Auf das Projekt ging Andrijan Möcker in seinem c't Artikel ein, diesen kann man auch noch als PDF Datei beziehen.

Beim Türöffner muss ein Signal an einen GPIO Pin gesendet werden, die dann an das Relais weiter geleitet werden, woraufhin der parallel geschaltete Öffner anzieht und die Türe sich öffnen lässt. Da ich des Prorgrammierens in Python nicht mächtig und obendrein zu faul bin, das für eine Klingel zu erlernen, habe ich das in Bash gemacht:

#!/bin/sh
gpio mode 12 out
gpio write 12 0
sleep 2
gpio write 12 1

Mit diesen viereinhalb Zeilen schaltet der Raspberry Pi für 2 Sekunden (so schnell muss der Postbote die Tür öffnen) das Relais über den GPIO Pin 10. Was, Pin 10? Wieso das denn, da steht doch 12? Stimmt. Bei den GPIO Pins gibt es soviele Bezeichnungen für deren Belegungen, wie andere Leute Unterhosen im Schrank haben. Alternative Fakten eben. Tatsächlich ist für die Bezeichnung die jeweilige Bibliothek, die für die Ansteuerung verwendet wird, verantwortlich. Eine gute Übersicht gibt es bei RaspBerry Guide.

Ich verwende hier wiring PI. Dieses Lib ist schnell installiert, ich verweise dazu an der Stelle auf tutorials-raspberry.de. Also. Pin 19 mit dem Signaleingang des Relais verbinden, einen GND Pin des GPIO mit dem selbigen des Relais und Schlußendlich einen 5 Volt Pin des GPIO mit dem VCC Pin des Relais verbinden. Die nebeneinander liegenden VCC und JD-VCC Pins des Relais bleiben bzw. werden im Gegensatz zur Anleitung bei xgadgets mittels eines Pin Steckers gebrückt, damit ersparen wir uns die zusätzliche Versorgung mit 3,3 Volt.

In meinem Fall musste ich die 5 Volt mittels einer Quick & Dirty Lötlösung von dem auf dem Raspberry PI verbauten ZigBee Modul(*) (dem Thema widme ich einen späteren Beitrag) von Dresden Elektronik klauen. Es gehen natürlich auch GPIO Extender(*), falls die Stromverorgungspins alle schon vergeben sind.

Ein erster Funktionstest

"Fliegender" Aufbau. Nach Ablauf diverser Tests werden alle Kabel schön sauber in ein Gehäuse gestopft.
Ein Test, ob man die richtigen Pins belegt hat, ist in jedem Fall sinnvoll. Da 5 Volt im Spiel sind - was für den Raspberry oder auch den auf dem Relais verbauten Optokoppler tödlich sein kann - rate ich in jedem Fall zur sorgfältigen Kontrolle der Schaltung. Für einen ersten Test kann man notfalls auf die Widerstände vom GPIO zum Relais verzichten, aber das ist was für faule Kerle. (Im Falle eines gegrillten RaspBerry Pi bitte ich die entsprechenden Werbelinks in diesem Beitrag zu nutzen, dann hat wenigstens einer etwas davon).

Das Relais selber muss mensch an der Stelle noch nicht an die Sprechanlage anschließen.

Ein entschlossener Aufruf des Scriptes mit dem obigen Inhalt, das vorher unter einem beliebigen Namen zum Beispiel als /usr/local/bin/oeffner.sh gespeichert und anschließend mittels:

sudo chmod a+x /usr/local/bin/oeffner.sh

ausführbar gemacht worden ist, sollte einen deutlich hörbaren Schaltvorgang des Relais zur Folge haben. Zudem sollten die auf dem Relais verbauten LEDs lustig im Schalttakt blinken.

Die halbe Miete

Nun biegen wir beinahe auf der Zielgeraden ein. Zuvor gilt es jedoch die Haarnadelkurve Asterisk zu bewältigen. Wie oben ausgeführt mit durchaus steilem Anstieg der Lernkurve, aber dafür gibt es ja diesen Beitrag hier.

Das Relais schaltet also im Ergebnis der Ausführung des Scripts oeffner.sh. Da der ganze Zweck der Übung der ist, mittels Anwahl einer bestimmten Nummernfolge auf einem der an die FritzBox angeschlossenen Telefone dieses Script auszuführen um so die Türe zu öffnen verwenden wir einen Befehl in Asterisk. Ich setze jetzt voraus, daß Asterisk läuft, sich erfolgreich bei der Fritzbox als IP Telefon angemeldet hat und Klingelsignale empfängt. Dazu habe ich in der FritzBox unter "Telefonie" das IP Telefon "622" mit dem Passwort "Sowasvongeheim" angelegt und in dem Python Script zur Generierung der .call Datei diese Daten ein eingegeben. Nicht verschlampern, die brauchen wir noch, nämlich hier, in dem etwas von mir angepassten (fett markiert) Python Script, das von c't Autor Andrijan Möcker geschrieben wurde:

 import time
 import shutil
 import RPi.GPIO as gpio
 import os
 import sys
 #Einstellungen
 klingel_gpio = 24 #GPIO, der mit der Schaltung verbunden ist
 callfilepfad = "/home/pi/klingel.call" #Dateipfad in dem das Script die .call-Datei ablegt
 sipkanal = "622" #Name des SIP-Kanals (in eckigen Klammern in der SIP.conf)
 sipziel = "**702" #Ziel des Anrufes (Beispiel: **702 als Anrufergruppe der Fritz!Box)
 sipwartezeit = "4" #Wartezeit bevor wieder aufgelegt wird
 #Hier wird die .call-Datei zusammengebaut und abgespeichert
 callfile = "Channel: SIP/" + sipkanal + "/" + sipziel + "\nApplication: Playback\nWaitTime:" + sipwartezeit + "\nData: /var/lib/asterisk/sounds/de/play"
 cf = open(callfilepfad, "w")
 cf.write(callfile)
 cf.close()
 #
 gpio.setmode(gpio.BCM)
 gpio.setup(klingel_gpio, gpio.IN, pull_up_down=gpio.PUD_UP)
 def voip():
 try:
 shutil.copyfile(callfilepfad,'/var/spool/asterisk/outgoing/anruf.call')
 print(text)
 except Exception:
 pass
 while True:
 time.sleep(0.01)
 if not gpio.input(klingel_gpio):
 time.sleep(0.1)
 if not gpio.input(klingel_gpio):
 voip()
 time.sleep(5)

Zu den von mir vorgenommenen Änderungen schreibe ich weiter unten noch ein paar Worte, das sind im wesentlichen auch die Stellen, die auf die Gegebenheiten vor Ort verändert werden müssen. An der Stelle ein Einschub, nämlich die durch dieses Script im Outbound Verzeichnis von Asterisk /var/lib/asterisk/outgoing/ erzeugte .call Datei:

 Channel: SIP/622/**702
 Application: Playback
 WaitTime 4
 Data: /var/lib/asterisk/sounds/custom/play

Asterisk fragt dieses Verzeichnis ständig ab (pollt) und führt darin enthaltenen Dateien aus. In unserem Fall: Anruf bei der FritzBox mit dem SIP Protokoll unter der Userkennung 622 an die Nummer **702, die ich in dem darüber gezeigten klingelscript.py bereits angelegt habe. Bei erfolgreichem Anruf wird für die Dauer von 4 Sekunden der Inhalt der Datei /var/lib/asterisk/sounds/custom/play ausgeführt. Diese braucht nicht zu existieren, es reicht der Impuls durch den Aufruf, um ein Klingelsignal bei der FritzBox auszulösen.

Nach eingehender Lektüre des bereits erwähnten Asterisk Buches bei dem vor allem auf die Zusammenhänge bei den Benutzerrechten geachtet werden sollte, schreiten wir zur Tat. (Das Semikolon leitet Kommentare ein, diese werden nicht ausgeführt):

 ;Allgemeine Einstellungen in der Asterisk Konfigurationsdatei für SIP Telefonie
 ; /etc/asterisk/sip.conf
 ; Ein paar notwendige Grundeinstellungen
 ;
 [general]
 port=5060
 bindaddr=0.0.0.0
 videosupport=no
 dtmfmode=rfc2833
 srvlookup=yes
 directmedia=no
 nat=no
 localnet=192.168.178.0/255.255.255.0 ; Das lokale Netz sowie die Broadcast Adresse
 transport=udp
 callerid=KlingelPi <622> ; Diese Anruferkennung erscheint auf kompatiblen Telefonen
 ;
 ; Der Sip Provider, in unserem Fall die FritzBox
 ; User:Passwort:Ziel/User
 register => 622:Sowasvongeheim@192.168.178.1/624
 ;
 ; Wir legen mal ein Ziel für den Türöffner an:
 [624]
 type=friend
 secret=Sowasvongeheim
 host=192.168.178.1
 insecure=invite,port
 ;
 ; Virtuelles Telefon für das Python Script, das via .call Datei die Überallklingel auslöst.
 [622]
 type=friend
 username=622
 fromuser=622
 secret=Sowasvongeheim
 host=192.168.178.1
 insecure=invite,port

Nun nützt eineM die beste sip.conf nichts, wenn es keine passenden Contexte in der /etc/asterisk/extensions.conf gibt. Wobei, das stimmt nicht ganz, das Script der c't lässt die extensions unberührt. Im Rahmen der Lektüre des Asterisk Handbuches auf der Suche nach alle, was Shell Befehle betrifft, springen einem dann 2 Möglichkeiten zur Befehlsausführung ins Gesicht: System() und TrySytem(). Dazu mal ein Vollzitat:

Führt durch die C-Funktion system() einen Befehl auf der Shell sh aus.
Diese Anwendung ist der TrySystem()-Anwendung sehr ähnlich, abgesehen davon, dass sie -1 zurückliefert, falls sie den Systembefehl nicht ausführen kann, wohingegen die TrySystem()-Anwendung stets 0 zurückliefert.

So. Ob Bash oder sh ist Wurst, wir haben damit die Möglichkeit, daß Asterisk das oeffner.sh Script ausführt. Sofern ein Context zutrifft. Da wir in der FritzBox ja ein Telefon angelegt haben, kommt über dieses mit der Kurzwahl **622 Kennung nicht nur das Signal vom Postboten an der Klingel, sondern mensch kann die **622 auch anrufen. It's Magic!

 ; Entweder an die bestehende /etc/asterisk/extensions.conf anhängen oder überschreiben, sofern keine anderen 
 ; Contexte / Extensions ausgeführt werden müssen.
 ;
 [default]
 ; Das Klingelscript verweist auf die Extension 622:
 exten => 622,1,Answer() ; Asterisk nimmt ab
 exten => 622,2,WaitExten(1) ; wartet 1 Sekunde
 exten => 622,2,Hangup() ; und legt dann auf
 ; Mehr braucht es nicht zum Klingeln
 ;
 ; Anruf bei **622 verweist hierher:
 exten => 624,1,Answer() ; Asterisk nimmt ab
 exten => 624,2,System(/usr/local/bin/oeffner.sh) ; Asterisk ruft die sh Shell auf und führt darin das oeffner.sh Script aus
 exten => 624,3,Hangup() ; Asterisk legt nach Abarbeitung des Scripts auf

Hier wird nun klar, warum ich bei der extensions.conf einige Zeit vertrödelt hatte und letzlich im Unterschied zur c't keinen Rundruf via **9 bei der FritzBox starte, sondern darin eine Gruppe angelegt habe, in der die anzurufenden Telefone vereint sind: Ein Rundruf bei der *9 führt nämlich dazu, daß auch der Öffner ausgelöst wird, denn die **622 ist ja die Nummer, die für die Türöffnung angerufen wird. Und eine Selbstöffnung wollen wir nun nicht wirklich einbauen, das gehört in Arztpraxen...

Ein Blick in das "sauber" von Profis verlegte Siedle HT401a-01
Die Rechnung ohne den Wirt Elektriker

Der bisherige Aufbau empfängt also Signale der Klingel, löst dadurch Anrufe auf den entsprechenden, bei der FritzBox registrierten Telefonen auf der **702 aus und wenn mensch mittels Kurzwahl **622 auf einem dieser Telefone wählt, klickt das Relais.

Das Relais betätigt den Öffner. Wenn es denn (richtig) angeschlossen ist. In unserm Fall verfluche ich jedes Mal die Elektriker, die Ende der 80er Jahre nicht daran gedacht haben, daß im Jahr 2018 jemand einen RaspBerry an ihre "Installation" anschließen will. Es hilft also kein Rezept wie : "Das blaue Kabel durchschneiden, an beide Enden das Relais anschließen, funktioniert 100%". Bestenfalls geht die Klingel nicht, schlimmstenfalls blickt mensch nicht mehr durch...

Nun denn, es hilft nichts, beim Anschluss der Klingel hat sich bei unserer Installation letztlich die gute alte Zahnstochermethode, mit der Kinder gerne Schellenbergerles² gespielt haben (Mit Zahnstocher den Klingelknopf an der Haustüre festklemmen) um die Leitungen oder Anschlüsse zu finden, die in dem Fall im Unterschied zu vorher Spannung anzeigen.

Im Falle unserer uralten Siedle HT401a-01 Anlage war das aber nicht nötig, die Schraubklemmen „7“ und „c“ im Telefon müssen für die Überallklingel abgegriffen werden, wie Moritz Cichon in seinem Blog im Beitrag "Siedle HT401a-01 Klingel austauschen: Endlich ein angenehmer Gong" ausführte.

Bei dem Anschluss des Relais ist es etwas einfacher, hier hilft es, den Öffnerknopf im Haustelefon anzusehen und welche Kontakte er im Auslösezustand schließt. Im Fall Siedle auf die Klemme "I" und den Pin "c" oben rechts auf der Platine. (Der Anschluss an "Lw" wie "Läutewerk"=Vorgabe von Siedle funktionierte bei unserem Telefon leider nicht. Notfalls Platine heraushebeln und die Schaltung an den Leiterplatten nachverfolgen. Hint: Meßgeräte helfen auch hier weiter ;-)) Daran schließen wir dann das Relais parallel an. Keinesfalls in einer Reihenschaltung, sonst löst weder der Türöffner des Haustelefons noch der Anruf bei der **622 den Türöffner aus.

An der Stelle eine Warnung: Auch wenn in Telefonanlagen in der Regel nur niedrige Ströme fließen können diese durchaus unangenehme Folgen (Kurzschluss der Klingelanlage, Stillstand Herzschrittmacher, Mega Ärger mit dem Vermieter usw.) haben. Daher: Ohne entsprechende Ausbildung bitte Fachleute zur Hilfe heranziehen. Es müssen ja nicht die sein, die bei uns die Klingelanlage verlegt haben.

In dem Sinne: Viel Erfolg beim Nachbauen!

Eigentlich fehlt jetzt noch eine Sprechfunktion. Man will ja nicht jedeN ins Haus lassen...



Blogpost enthält Werbung!

**trueten.de ist Teil des Amazon Partnerprogramm EU. Das bedeutet, wenn ihr ein Produkt über die Links kauft, welche mit einem „*“ gekennzeichnet sind (affiliate Link), erhaltet ihr diese zu den üblichen Preisen und ich bekomme eine kleine Provision. So könnt ihr unser Blog ohne extra Aufwand unterstützen! Vielen Dank!

RiP, Steven Hawking

NASA StarChild Stephen Hawking
Foto: NASA Ausbildungszentrum
„Remember to look up at the stars and not down at your feet. Never give up work. Work gives you meaning and purpose and life is empty without it. If you are lucky enough to find love, remember it is there and don't throw it away.“

Steven Hawking
* 8. Januar 1942 in Oxford, Oxfordshire, England; -  14. März 2018 in Cambridge, Cambridgeshire, England

Zitat

WLAN Verbindungsprobleme unter Android 7.x bzw. LineAgeOS 14.x umgehen

Darauf muss man auch erst mal kommen: Seit einiger Zeit gibt es das Problem, daß im Unternehmensnetzwerk Android Handys, die mit LineageOS 14.x bzw. unter Android 7.1.2 "Nougat" laufen, Verbindungsprobleme auftreten. Betroffen sind Access Points, die das vor allem in Unternehmen verwendete WiFi Protokoll WPA2-Enterprise (PEAP/MSCHAPv2) bzw. 802.1x EAP anbieten. Die "Verbinden" Felder der Handys im Wifi Menü bleiben dabei grau, es ist kein Connect möglich. Reproduziert wurde das Problem von uns mit einem OnePlus 3T, auf dem die aktuellen LineAgeOS Nightlies installiert sind.

Eine Suche bei Google brachte dann in einem der Treffer die Lösung einen brauchbaren Workaround. Der User Hao Lu schreibt in einer Diskussion um den bei einem von Google entwickelten Handy - dem Pixel XL- dazu:

"I found a workaround for my Pixel XL as I experienced the same issue. Go to the play store and search for WiFi manager (I just used the first one). Install and open. Enter the ID and password as usual, the connect button shouldn't be grayed out. It'll remember the settings so you can delete the app if you want. Hope this helps."

Kurz: Der Tipp funktioniert. Auf dem Testgerät den WiFi Manager von Kostya Vasilyev installiert - Gerät verbindet sich sofort:

Bleibt die Frage: Warum hat Google diesen Bug nicht schon längst gefixt? Natürlich muss man erst mal darauf kommen, mit einer Drittanbieter App einen Systemfehler zu umgehen. Auf der anderen Seite zeigt sich hier mal wieder die Android Problematik, daß es eben mindestens 1000 Wege zur Lösung eines Problems gibt. Leider sind nicht selten 995 davon nicht begehbar, z.B. im Unternehmenseinsatz oder unter besonderen Sicherheitsaspekten. Offensichtlich kann bei diesem Bug auch ein Systembestandteil locker umgangen werden.

Und das können im Zweifelsfall eben auch bösartige Programme.

cronjob