Nach dem automatischen Update des Kernel auf die Version 6.14.0.24 bricht VirtualBox die Ausführung einer virtuellen Umgebung mit der folgenden Fehlermeldung ab:
VirtualBox can't enable the AMD-V extension. Please disable the KVM kernel extension, recompile your kernel and reboot (VERR_SVM_IN_USE).
Grund dafür ist – diesem Posting zufolge – eine Änderung in der Initialisierung von KVM während des Bootvorgangs.
KVM wird im neuen Kernel während des Bootens initialisiert und verhindert so den Start von VirtualBox-Containern.
Das Posting schlägt den folgenden Fix vor:
Die Verwendung des folgenden Kernel-Parameters unterbindet diese Initialisierung:
kvm.enable_virt_at_load=0
Am einfachsten lässt sich das durch Ändern der Konfigurationsdatei /etc/default/grub erreichen, indem dort der Parameter GRUB_CMDLINE_LINUX_DEFAULT um diesen Eintrag ergänzt wird, z. B. so
GRUB_CMDLINE_LINUX_DEFAULT="kvm.enable_virt_at_load=0"
Mit
sudo update-grub
wird /boot/grub/grub.cfg neu erstellt.
Beim nächsten Booten ist der Parameter dann aktiv und VirtualBox kann wieder gestartet werden.
Montag, 28. Juli 2025
Ubuntu 24.04: Kernel-Update verhindert Start von VirtualBox
Samstag, 12. April 2025
Double-sided printing on Brother MFC-L2710DW now working again on Ubuntu
I'm using a Brother MFC L2710DW with my Ubuntu machines.
I've chosen this printer (which supports duplex printing) years ago because it was supported by Ubuntu out of the box.
However, after updating to Ubuntu 24.04 (Noble Numbat) the duplex printing capability was gone... The "front" page was printed OK, but the "back" page looked like a
memory dump: parts of the intended output were visible but interleaved
with random and geometric pixel patterns.
It turned out that the printer driver für the MFC-L2710DW had changed to "brlaser" between Ubuntu versions. This driver is now responsible for various brother laser printers.
I opened a bug report on the brlaser Github repo. It turned out that this was a know problem that had meanwhile been fixed.
However - the fix hadn't made it into the branch that Ubuntu is using.
I created a bug report in Launchpad with a link to the GitHub-Thread.
The maintainer promptly created a new version which has now (mid-April 2025) "pre-release" status.
If you can't wait: the binaries are available if you follow the links on Launchpad.
After downloading and installing it (sudo dpkg -i printer-driver-brlaser_6.2.7-0ubuntu1_amd64.deb) double-sided printing is again working.
Sonntag, 23. März 2025
openpyxl - data_only beware
openpyxl is a popular library to access Excel data via python.
However, there is an unexpected side effect if you have formulas in your Excel workbook.
I'm not the first to find that out the hard way - so here is another warning.
If you have a formula in your xlsx-spreadsheet like "=B1-A1" the spreadsheet app (Excel, LibreOffice etc.) stores the formula as well as the calculated result which you can see in the cell.
If the formula is stored e.g. in "C1", and you open the file in your python script like this:
import openpyxl
wb = openpyxl.load_workbook(filename="testwb.xlsx")
print(sheet["C1"].value)
# prints the formula
The result will be the formula, not the calculated value.
In order to access the calculated value, you have to open it with data_only set to True.
import openpyxl
wb = openpyxl.load_workbook(filename="testwb.xlsx", data_only=True)
print(sheet["C1"].value)
# prints the calculated value
The catch is that if you try to save the workbook later with for example
wb.save("testwb2.xlsx")
all formulas in the entire workbook are gone (if the workbook was loaded with data_only=True).
If you must have access to the results of the formulas that Excel has calculated, the work-around is to open two instances of the workbook: one with and one without data_only.
Make the one using data only also read_only, just in case
wb = openpyxl.load_workbook(filename="testwb.xlsx", data_only=False)
wb_dataonly = openpyxl.load_workbook(filename="testwb.xlsx", data_only=True, read_only=True)
This way you have access to the calculated values via wb_dataonly and you can add data and save the result using wb... and yes, you have to keep in mind that the two instances go out of sync as soon as you modify wb.
Donnerstag, 13. März 2025
Bitwarden's ssh-agent
The most secure way of accessing external ssh servers is the use of ssh-keys and I'm deploying them regularly. The private key is stored on my hard drive, and I'm protecting it with a passphrase. Remembering the passphrase especially for a site you rarely use has always been a PITA.
Since the beginning of this year (2025) the password manager Bitwarden allows you to manage your ssh-keys as well. So I gave it a try.
Under Ubuntu you have to install the Bitwarden desktop app from the snap repo and connect it to your vault. After setting SSH_AUTH_SOCK in your .bashrc the desktop app acts as your ssh-agent:
export SSH_AUTH_SOCK=/home/your_user_name/snap/bitwarden/current/.bitwarden-ssh-agent.sock
While importing keys I've noticed that Bitwarden only likes the "new ones" (that use Ed25519 elliptic curve crypto). It was a good opportunity to re-key.
Bitwarden itself always generates Ed25519 keys. The reason might be that this special kind of key allows you to calculate the public key from the private one.
When importing keys into Bitwarden I had to provide the passphrase to my keys, which made me hesitate - perhaps a Gibson-ian reaction :) - because it meant that the key is stored "naked" in the Bitwarden vault.
I would have liked it more if Bitwarden would have provided the passphrase on request - but this would have made integration as ssh-agent impossible.
How is the risk mitigated?
- You are prompted each time a ssh-key is requested from the vault, which is an improvement over the regular ssh-agent.
- There is no indication where a key can be used, if you don't put it into the comment.
- Up until now Bitwarden has a spotless record of securing your vault.
Integration with .ssh/config
The .ssh/config file allows you to configure additional items like hostname, user name, port, the ssh-key AKA the identity file, and port forwarding rules for a given host. This way you don't have to specify them every time in a ssh command. If and only if an identity file is configured for a given host a ssh-agent will be queried.
If you generate the ssh-key within Bitwarden the private key is stored in your vault. But what do you put into the IdentityFile field to make the system query the Bitwarden app?
As Kiko Piris pointed out here, it needn’t be the private key that is stored on the hard drive. It might also be the public key. This will not help you if the Bitwarden app is not running, but at least it will make ssh try to contact the ssh-agent.
You might have noticed during the regular use of the Bitwarden app that the IdentityFile field has to be present in the .ssh/config file but the key file itself is not used.
I still have my passphrase-protected private keys on my hard drive with the IdentityFile field pointing to them. But when I log in with ssh I’m not queried for the passphrase, instead the Bitwarden Desktop app pops up requesting confirmation to use the key it has stored in its vault.
The Bitwarden app has a button that copies the public key into the clipboard which can be used to create the public key file which then can be specified in the IdentityFile field.
It is - as usual - a compromise between security and convenience. If it fits your risk profile it's a nice tool.
Montag, 3. März 2025
matplotlib - The secret of the vanishing x-ticks
The versions:
* Ubuntu 24.04
* python 3.12.3
* matplotlib 3.10.0
I've searched for this solution for days. So I describe it here for anyone who might need ist.
The goal is rather simple:
I want to create a figure with three subplots, each with an independent x-axis because I want to display data with different time periods.
I expected to get something like this:
And that is exactly what you get if execute this simple program.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
from datetime import datetime
import matplotlib as mp
print(mp.__version__)
# 3.10.0
FORMAT_MAJOR = False
FORMAT_MINOR = False
# Format definitions
# not all are used
years = mdates.YearLocator() # every year
months = mdates.MonthLocator() # every month
days = mdates.DayLocator() # every day
hours = mdates.HourLocator() # every hour
years_fmt = mdates.DateFormatter('%Y')
month_fmt = mdates.DateFormatter('%m')
day_fmt = mdates.DateFormatter('%d')
hour_fmt = mdates.DateFormatter('%H')
fig, axs = plt.subplots(nrows=3, ncols=1, figsize=(187, 12), sharex="none")
datx0 = [ datetime(2025, 1, 31), datetime(2025, 2, 2), datetime(2025, 2, 3) ]
daty0 = [100, 200, 150]
datx1 = [ datetime(2025, 2, 4), datetime(2025, 2, 5), datetime(2025, 2, 7) ]
daty1 = [150, 100, 150]
datx2 = [ datetime(2025, 2, 1), datetime(2025, 2, 4), datetime(2025, 2, 5) ]
daty2 = [200, 200, 150]
axs[0].plot(datx0, daty0)
axs[1].plot(datx1, daty1)
axs[2].plot(datx2, daty2)
for pos in range(3): # 0..2
curraxs = axs[pos]
curraxs.grid(True)
if FORMAT_MAJOR:
curraxs.xaxis.set_major_locator(days)
curraxs.xaxis.set_major_formatter(day_fmt)
curraxs.tick_params(axis="x", which="major", rotation=45)
if FORMAT_MINOR:
curraxs.xaxis.set_minor_locator(hours)
curraxs.xaxis.set_minor_formatter(hour_fmt)
curraxs.tick_params(axis="x", which="minor", rotation=90)
# only 1% "slack" at each end
curraxs.set_xmargin(0.01)
print(axs[0].xaxis.get_majorticklabels())
print(axs[1].xaxis.get_majorticklabels())
print(axs[2].xaxis.get_majorticklabels())
plt.show()
As you can see, there are three data series.
- The first from 2025-1-31 to 2025-2-3.
- The second from 2025-2-4 to 2025-2-7.
- The third from 2025-2-1 to 2025-2-5.
The date ranges have been chosen to overlap slightly. The y-data has no special meaning other than to show different graphs in the subplots.
The vanishing act occurs if you try to format the x-axis labels.
This is usually done with:
import matplotlib.dates as mdates
days = mdates.DayLocator()
day_fmt = mdates.DateFormatter('%d')
axs.xaxis.set_major_locator(days)
axs.xaxis.set_major_formatter(day_fmt)
This works fine for a single axis. If you have more than one, strange things happen:
The missing x-ticks become more apparent if you set FORMAT_MINOR to True as well.
- In the first subplot the ticks for 2025-01-31 are missing.
- In the second subplot the ticks from 2025-02-05 and above are missing.
- Only the third subplot has all x-ticks.
The output of the get_majorticklabels() of the three axis at the end of the program...
print(axs[0].xaxis.get_majorticklabels())
print(axs[1].xaxis.get_majorticklabels())
print(axs[2].xaxis.get_majorticklabels())
...gives an indication of what happened:
They are all identical – using the values from the last call 2025-01-01 to 2025-02-05.
Which explains the missing parts at the beginning of the first subplot and the missing days at the end of the second.
So, how to fix this?
It seems that – contrary to what one might believe – the xxxxLocator() calls are not simply generators that produce ticks as requested. They seem to keep some kind of internal state – in this case of the last subplot – influencing all the other uses.
You have to move them into the for-loop so that for each axis a “new” xxxxLocator() is created.
...
for pos in range(3): # 0..2
curraxs = axs[pos]
curraxs.grid(True)
days = mdates.DayLocator()
hours = mdates.HourLocator()
if FORMAT_MAJOR:
curraxs.xaxis.set_major_locator(days)
curraxs.xaxis.set_major_formatter(day_fmt)
curraxs.tick_params(axis="x", which="major", rotation=45)
...
This gives the expected result:
Sonntag, 12. Januar 2025
Einfache Monats-e-Rechnung
Vor einigen Wochen habe ich über meinen GitHub-Account eine Java-Anwendung zur Erstellung einer einfachen Monats-e-Rechnung verfügbar gemacht.
Ich weise jedoch darauf hin, dass ich weder ein Steuerberater noch ein Anwalt bin, und die von mir getroffenen Entscheidungen – so nachvollziehbar sie auch sein mögen – sich als falsch herausstellen könnten. Für Hinweise bin ich – schon im Eigeninteresse – dankbar.
Was also ist eine e-Rechnung?
Aus Sicht eines Programmierers ist eine e-Rechnung nichts anderes als eine XML-Datei in einem gesetzlich vorgeschriebenen Format, die also solche oder in eine PDF-Datei eingebettet verschickt werden kann, und nach dem Wachstumschancengesetz ab 2025 bzw. spätestens 2028 im B2B-Geschäftsverkehr verwendet werden muss. Kurz gesagt: die Papierrechnung ist tot – so gut wie...
Der Grund ist eigentlich nachvollziehbar.
Stellen Sie sich ein Unternehmen vor, das von seinen Lieferanten Hunderte von Rechnungen im Monat erhält. Dieses Unternehmen hat mit Sicherheit eine Software, die diese Rechnungen verwaltet und rechtzeitig anweist.
Außerdem hat das Unternehmen jemanden, der diese Rechnungen – egal, ob sie auf Papier oder als PDF vorliegen – sichtet, die wichtigen Daten heraussucht und in diese Software eingibt. Einfacher wäre es, wenn die Daten bereits in einer computerlesbaren Form vorliegen würden – und genau das ist eines der Ziele der e-Rechnung.
Bei großen Firmen wird man das mit einem Update in der sowieso vorhandenen Software lösen – bei Einzelkämpfern und kleinen Unternehmen ohne eine solche Software wird es jedoch schwierig, diese gesetzliche Anforderung umzusetzen.
Man könnte auf die Idee kommen, diese XML-Datei (die im Grunde auch nur eine Textdatei ist) von Hand zu erstellen. Das ist jedoch umständlich und fehleranfällig, und irgendwie muss man das XML noch in die PDF-Datei bekommen…
Das heißt, man wird um irgendeine Software nicht herumkommen.
Für die „nackte“ XML-Datei gilt die XRechnung-Spezifikation, für die kombinierte PDF+XML-Variante ist es ZUGFeRD.
Eine ZUGFeRD-Rechnung hat den Vorteil, dass man den PDF-Teil mit einem beliebigen PDF-Viewer anzeigen kann, für die XRechnung ist ein spezieller Viewer notwendig.
Da eine ZUGFeRD-Rechnung aus einem PDF-Teil und einen XML-Teil besteht, existiert natürlich die Gefahr, dass die Daten, die ein Mensch im PDF sehen kann, nicht denen entsprechen, die im XML kodiert sind. Beim Erstellen ist man daher gesetzlich verpflichtet, dass die Informationen in beiden identisch sind. Im Zweifelsfall gilt aber das XML.
Im Netz gibt es einige kostenlose Angebote zum Erzeugen dieser PDF-Rechnungen – auch von namhaften Anbietern – bei denen man die benötigten Daten in eine Maske einträgt und ein konformes PDF erhält… natürlich direkt neben den kostenpflichtigen Angeboten, mit denen das alles viel einfacher geht.
Auch gibt es Open-Source-Fakturierungssoftware, die e-Rechnungen erstellen kann, oder Makros für LibreOffice. Bei den meisten würde ich 90% der Funktionalität nie brauchen und die Funktion, die ich brauche – die Monatsrechnung – fehlt häufig.
Was ist so besonderes an einer Monatsrechnung?
Bei den meisten „einfachen“ Rechnungen bezieht sich die Rechnung nur auf genau EINE Bestellung. Wenn Sie z.B. in einem Webshop einkaufen, bekommen Sie eine Rechnung für genau diese eine Bestellung. Diese 1:1-Beziehung liegt beim überwiegenden Teil aller Rechnungen vor.
Eine Monatsrechnung fasst mehrere Bestellungen aus einem Monat in einer Rechnung zusammen. Damit bezieht sich EINE Rechnung auf MEHRERE Bestellungen.
Auch dieser Fall ist in der ZUGFeRD-Spezifikation vorgesehen, nur leider wird er meist nicht in der Software implementiert.
Was braucht man für eine ZUGFeRD e-Rechnung?
Für den PDF-Teil reicht die übliche Textverarbeitung wie LibreOffice oder Word. Beide haben die Möglichkeit, den Text als PDF/A zu speichern. Dabei stellt die „/A“-Variante („A“ wie Archiv) sicher, dass das PDF auch später noch in der heutigen Form angezeigt werden kann, u.a. dadurch, dass der benutzte Zeichensatz in das PDF mit integriert wird.
Das so erzeugte PDF allein wird aber künftig nicht mehr als Rechnung ausreichen.
Den fehlenden XML-Teil kann man mit dem o.g. Programm erzeugen. Es setzt dabei auf die Mustang-Bibliothek.
Deren Vorteile:
sie kann das XML erzeugen und in die PDF-Datei integrieren
sie kann eine Validierung der so entstandenen PDF-Datei durchführen
Der Nachteil:
eine Monatsrechnung kann sie (zurzeit) auch nicht erstellen.
Den letzten Punkt habe ich dadurch gelöst, dass ich die fehlende Funktionalität selbst programmiert und die XML-Datei entsprechend der Spezifikation erweitert habe.
Mustang verbindet dann die zuvor erzeugte PDF-Datei mit der neu erstellten XML-Datei und erzeugt daraus eine ZUGFeRD-Datei. Diese Datei wird dann von einem Validator geprüft.
Der Validator prüft die PDF-Datei, den Aufbau der XML-Datei und die Abhängigkeit der Felder im XML untereinander. Er verwendet dabei Hunderte von Regeln. So prüft er beispielsweise, dass Summen stimmen oder dass ein bestimmtes Feld vorhanden ist, wenn ein anderes Feld einen bestimmten Wert hat usw.
Er verringert so die Gefahr, dass eine Rechnung vom Empfänger zurückgewiesen wird, weil Fehler im XML vorhanden sind.
Eine 100%-ige Garantie ist das aber auch nicht. Es gibt mehrere Validatoren und die sind sich nicht immer ganz einig. Außerdem werden die Validatoren selbst auch weiterentwickelt und deren Ergebnisse können dann in der nächsten Version bei der gleichen PDF-Datei unterschiedlich ausfallen.
Simple Monats e-Rechnung (smer)
Mein
Programm steht als sog. „Fat-Jar“ zur Verfügung, das alle
Abhängigkeiten bereits mitbringt – vor allem die megabytegroßen
Validator-Dateien. Es setzt somit nur ein installiertes Java 17
voraus.
Aufgerufen wird die Version 0.1.2 mit
java -jar smer-0.1.2-all.jar name_der_pdf_datei.pdf [name_des_rechungsdatei.yaml]
Wie in der zugehörigen Dokumentation beschrieben, werden die Daten wie Firmen- und Kundenanschriften, Warenliste und Steuerfälle in YAML-Dateien gespeichert. Diese Daten ändern sich nach dem anfänglichen Erstellen meist nicht mehr.
Der „variable Teil“ sind die Daten der eigentlichen Rechnung. Auch er wird in einer YAML-Datei erwartet, deren Name man optional dem Aufruf mitgeben kann.
YAML ist ein Format, das man mit einem normalen Texteditor bearbeiten kann und dessen Aufbau noch „menschenlesbar“ ist. Die Namen der Felder sind so gewählt, dass sie selbsterklärend sind.
Wie bei ähnlichen Angeboten im Internet werden auch hier die Daten dem Programm auf einem Silbertablett präsentiert. Es macht daraus eine XML-Datei, verbindet diese mit dem vorbereiteten PDF und führt ein Validierung durch.
Wie oben erwähnt müssen Sie sicherstellen, dass die Daten im PDF- und im XML-Teil identisch sind. Das Programm gibt hierzu eine kurze Zusammenfassung der im XML-Teil gespeicherten Zahlen aus.
Das Programm reicht in seiner jetzigen Form aus, um gelegentlich ein PDF zu einer Monatsrechnung „aufzuwerten“.
Spätestens dann, wenn man viele Rechnungen schreibt, wird jedoch der Wunsch nach weiteren Funktionen kommen, wie beispielsweise
die Anbindung an eine „richtige“ Datenbank
das Erzeugen der PDF-Datei
Solche Erweiterungen sind aber für jeden Betrieb sehr spezifisch und daher hier nicht implementiert. Das Programm ist aber so ausgelegt, dass es sich leicht erweitern lässt.
Samstag, 28. September 2024
Frameo - es ist Zeit
Digitale Bilderrahmen verbreiten sich immer mehr und viele kommen auf die Idee, ihn den Großeltern zu schenken, um Bilder von der eigenen Familie über das Internet auf den Bilderrahmen zu senden, und die älteren Herrschaften so am eigenen Familienleben teilhaben zu lassen.
Das folgende Posting beschreibt ein nicht offensichtliches Problem in Gast-Netzwerken, wie sie z. B. in Altenheimen vorkommen.
Wenn man einen digitalen Bilderrahmen haben möchte, der sich über das Internet befüllen lässt, hört man sehr schnell den Namen „Frameo“. Das System besteht aus einer Mobil-App zum Senden der Bilder (iOS oder Android), der Software auf dem Bilderrahmen (der unter Android läuft) und augenscheinlich einem Frameo-Server in der Cloud, der zumindest die Verbindung zwischen App und Rahmen herstellt.
Das Einsatzgebiet bringt es mit sich, dass der Bilderrahmen nach seiner Einrichtung in den allermeisten Fällen ohne weitere Bedienung laufen muss. Das heißt, der Rahmen muss sich zu den programmierten Uhrzeiten automatisch aus- und wieder einschalten und neue Bilder erscheinen wie von Geisterhand.
Bei Frameo können mehrere „Freunde“ Bilder an den Rahmen senden - löschen kann man Bilder leider nur vor Ort.
Beim Anlegen eines „Freunds“ wird eine 10-stellige PIN generiert, die 12 Stunden lang gültig ist. Während dieser Zeit kann man diese PIN per Telefon, Messenger oder SMS weitergeben. Mit dieser PIN wird in den Mobil-Apps die Verbindung zum Rahmen hergestellt.
Auch die Erzeugung der PINs kann an einen „Freund“ delegiert werden.
So weit, so gut.
Die Probleme begannen hier jedoch mit der Beobachtung, dass der Bilderrahmen beim Booten seine Zeit nicht automatisch einstellte. Bei jedem Neustart oder Ein- und Ausschalten ging die manuell eingestellte Zeit verloren.
Dies war um so erstaunlicher, da der Rahmen mit dem Internet verbunden war und über diesen Weg auch Bilder von den Mobil-Apps übertragen werden konnten.
Der Kundendienst von Frameo hat sich sehr bemüht, konnte das Problem letztlich aber auch nicht finden, gab aber den Anstoß zu dessen Lösung.
Ein Bilderrahmen ist ein klassisches IoT-Gerät und gehört daher aus Sicherheitsgründen in ein Gast-Netzwerk.
Ein Gast-Netzwerk erlaubt den Zugriff auf das Internet, aber nicht auf die Computer des internen Netzwerks.
Auch das WLAN in einem Altenheim sollte als Gast-Netzwerk konfiguriert sein.
Eine wenig bekannte aber standardmäßig aktivierte Sicherheitsfunktion in Fritz-Boxen beschränkt den Internetverkehr auf WWW und E-Mail und ist damit für 99% aller Fälle ausreichend.
Sie blockiert jedoch den Zugriff auf Zeitserver und damit das automatische Stellen von Uhren (z. B. die im Bilderrahmen).
Ohne diese Zeitinformation setzte sich die Uhr im Bilderrahmen immer auf 5:00 Uhr morgens. Die programmierten Ein- und Ausschaltzeiten des Rahmens beziehen sich auf diese Zeit, sodass er sich mitten in der Nacht ein- bzw. ausschaltete.
Die Beschränkung auf WWW und E-Mail in Gast-Netzwerken kann man in der Fritz-Box ausschalten. Seitdem funktioniert auch das automatische Einstellen der Uhrzeit. Es bleibt zu sehen, wie das WLAN im Altenheim konfiguriert ist.
Einen entsprechenden Hinweis habe ich an AVM gegeben, aber ich erwarte keine große Reaktion.
Dienstag, 9. Juli 2024
Postbank behebt HBCI-Fehler
Wie im o.g. Forumthread berichtet, hat die Postbank - in bemerkenswerter Schnelle - den vor einigen Tagen gemeldeten Fehler unterdessen behoben.
Wie ebenfalls im o.g. Forumthread beschrieben, muss man nun jameica dazu veranlassen, die fehlenden Kontobewegungen von der Postbank zu holen:
Zunächst sollte - falls das nicht automatisch geschieht - ein Backup erstellt werden.
Dann: Start > Hibiscus > Konten
Dort das entsprechendes Konto auswählen und mit der rechten Maustaste das Kontext-Menü öffnen.
Nun: Erweitert > Saldo und Datum zurücksetzen
Bei der nächsten Synchronisation holt jameica alle verfügbaren Kontobewegungen vom Server und versucht die so entstehenden Dubletten zu erkennen und zu überspringen.
Das funktioniert, wenn zwischendurch in jameica nichts an den Einträgen verändert wurde. Ansonsten wird die Buchung nicht als Dublette erkannt und neu angelegt. Man sollte deshalb danach Ausschau halten.
Donnerstag, 4. Juli 2024
Fehler in der HBCI-Schnittstelle der Postbank führt zu Problemen bei Finanzsoftware
Eine augenscheinlich Anfang August vorgenommene Änderung der Postbank an den Daten, die sie über ihre HBCI-Schnittstelle ausgibt, führt zu Problemen bei der Finanzsoftware jameica und wahrscheinlich auch bei anderen Programmen.
Einer der Datenpunkte, die pro Transaktion übertragen werden, ist die IBAN des Empfängerkontos. Die IBAN ist in Deutschland 22 Zeichen lang und der Programmierer von jameica hat für diesen Datenpunkt eine Länge von 40 Zeichen vorgesehen - also normalerweise mehr als genug.
Seit Anfang August überträgt die Postbank die IBAN des Empfängerkontos jedoch doppelt, mit einem Schrägstrich dazwischen. Die Zeichenkette ist damit 45 Zeichen lang und passt dann nicht mehr in die eigentlich großzügig bemessenen 40 Zeichen der lokalen Datenbank. Dies führt dazu, dass die Buchung nicht richtig eingelesen werden kann und übersprungen wird.
jameica gibt zwar eine Meldung aus, dass einige Daten nicht eingelesen werden konnten - sogar mit rotem Hintergrund; einen etwas deutlicheren Hinweis hätte ich mir dann doch gewünscht.
Soweit im Augenblick bekannt ist, tritt der Fehler "nur" bei Daueraufträgen und den monatlichen Abbuchungen der Kreditkarte auf.
Der Autor von jameica gibt an, dass die Postbank den Fehler mittlerweile zugibt und einen Fix bis zur KW 29 verspricht... mal sehen
Im Augenblick bleibt nur der Besuch der Bank-Website, wenn man überprüfen will, ob ein Dauerauftrag ausgeführt wurde.
Links
Thread im Forum: https://homebanking-hilfe.de/forum/topic.php?t=26582
Samstag, 25. November 2023
„Altes“ von der Postbank
Wie Anfang des Jahres berichtet, hatte die Umstellung der IT-Infrastruktur bei der Postbank einige unschöne Nebenwirkungen. Aber es hat sich was getan.
Seit September dieses Jahres hat die Dateigröße der PDF-Kontoauszüge merklich zugenommen.
Seither kann man den Text wieder mit Auswählen/Kopieren/Einfügen aus dem PDF heraus kopieren und erhält dabei kein Kauderwelsch mehr, sondern tatsächlich den angezeigten Text.
Auch CSV-Dateien mit den Buchungsdaten lassen sich nun wieder erstellen... Ich bleibe jetzt aber bei Jameica.
Freitag, 24. November 2023
Web-Apps auf RaspberryMatic?
Web-Apps sind Programme, die im Webbrowser des Betrachters laufen. Aber
warum sollte man so etwas mit RaspberryMatic einsetzen? Das hat doch
schon eine GUI?
Jeder, der bereits ein RaspberryMatic-System aufgesetzt hat, kennt die RaspberryMatic-Weboberfläche. Mit ihr kann man alles einrichten, einstellen und programmieren, was bei einem Homematic-System notwendig ist.
Eines ist sie jedoch nicht: übersichtlich. Jemand, der das System nur oberflächlich kennt, findet sich darin kaum zurecht.
Es liegt also nahe, für solche Benutzer eine angepasste Oberfläche zu programmieren. Diese auf dem Raspberry selbst zu implementieren ist recht schwierig. Bei einer Webanwendung hingegen läuft die Weboberfläche auf dem Rechner des Betrachters, der wahrscheinlich um ein Vielfaches leistungsstärker ist, als ein Raspberry.
Und RaspberryMatic bringt im Prinzip auch alles mit, was man dazu braucht:
- einen Webserver, über den die App ausgeliefert werden kann
- mehrere APIs, mit denen Sensoren ausgelesen und Aktoren gesteuert werden können.
Allerdings, im Auslieferungszustand funktioniert diese Idee nicht – und RaspberryMatic trifft dabei nur eine geringe Schuld.
Grund ist ein in allen gängigen Webbrowsern eingebauter Schutzmechanismus: „Same Origin“. Dieser besagt, dass Sachen nur dann ungefragt von einem Webserver nachgeladen werden dürfen, wenn die aufrufende Seite (in diesem Fall die Web-App) auch von dort stammt.
„Same Origin“ bezieht sich hierbei leider nicht nur auf die gleiche Maschine, sondern auch auf den gleichen Port – und der Port, über den die APIs angesprochen werden, ist ein anderer als der HTTP(S)-Port, von dem die Web-App geladen wird.
Wenn die Web-App nun versucht, den API-Port anzusprechen, generiert der Webbrowser, in dem die App läuft, eine Nachfrage auf dem entsprechenden Port, ob der Zugriff gestattet ist: die sog. CORS-Anfrage. Diese versteht RaspberryMatic jedoch nicht und antwortet mit einem Fehler, der vom Webbrowser als ein „Nein“ interpretiert wird. Die Webbrowser blockiert dann die eigentliche API-Kommunikation.
Es gibt mehrere Möglichkeiten, dies zu beheben. Dieser Post beschreibt, wie man diesen Zustand „minimal-invasiv“ ändern kann.
Die hier beschriebene Lösung ermöglicht die API-Abfrage über den normalen HTTPS-Port und besteht aus einigen wenigen zusätzlichen Zeilen in einer Konfigurationsdatei. Damit wird die API-Abfrage wirklich „Same Origin“, die CORS-Anfrage entfällt und RaspberryMatic kann über eine Web-App gesteuert werden.
Hinweis: Die APIs sind eigentlich für „normale“ Programme (Skripts oder ausführbare Anwendungen) auf anderen Rechnern gedacht. Diese kennen den „Same Origin“-Schutz nicht und machen deshalb auch keine CORS-Anfrage.
Auswahl der API
RaspberryMatic kennt zwei APIs: die XML-API und die Homematic-Script-API.
Die XML-API verwendet zur Abfrage von Sensoren und Steuern von Aktoren – wie der Name schon vermuten lässt – XML-Snippets. Der Grund weshalb ich sie in diesem Beispiel nicht verwende ist, dass die XML-API keinen Zugriff auf die bei der Homematic-Programmierung häufig verwendeten Systemvariablen bietet.
Die Homematic-Script-API hingegen erlaubt das Ausführen beliebiger kleiner Homematic-Scripts. Diese Skripts können dann Sensoren abfragen, Aktoren steuern aber eben auch Systemvariablen lesen und schreiben.
Firmware ändern
Um die Firmware eines RaspberryMatic zu ändern, muss man sie zunächst entsperren, d.h. editierbar machen. Hierzu muss der SSH-Zugang im RaspberryMatic freigegeben sein (Einstellungen > Systemsteuerung > Sicherheit > SSH).
Dann kann man sich per SSH als Anwender eingeloggen und hat Root-Rechte. Das Entsperren der Firmware erfolgt dann mit dem Befehl:
mount -o rw,remount /
Nach dem Entsperren kann die Konfigurationsdatei lighttpd.conf des Web-Servers mit dem auf dem System installierten Editor vi editieren werden:
vi /etc/lighttpd/lighttpd.conf
Hängen Sie unten den folgenden Text am Ende der Datei an (Hinweis: Aufrufen des Einfügemodus bei vi erfolgt mit der Taste „i“):
$HTTP["url"] == "/regex.exe" {
$HTTP["request-method"] == "POST" {
url.access-allow = ("")
proxy.server = (
"" => (
"localhost" => (
"host" => "127.0.0.1",
"port" => 8183,
),
),
)
}
}
Speichern Sie die Änderungen… (vi verwendet hierzu ESC : w q)
„Sperren“ Sie die Firmware wieder gegen Änderungen:
mount -o ro,remount /
Stoppen und starten Sie den Webserver
/etc/init.d/S50lighttpd stop
/etc/init.d/S50lighttpd start
oder starten Sie im Zweifelsfall das System über die normale WebUI neu (Einstellungen > Systemsteuerung > Zentralenwartung > RaspberryMatic-Neustart).
Der Zugriff auf die Script-API ist nun auch über den normalen Webport mit einem POST-Befehl an die URL
/regex.exe
möglich.
Beschreibung der Änderung
Bei der Untersuchung des Problems hat sich herausgestellt, dass der RaspberryMatic-Webserver lighttpd auch für die Kommunikation der API-Ports zuständig ist und diese Befehle einfach an einen weiteren internen Port (in diesem Fall 8183) weiterleitet. Und genau das ermöglicht diese Änderung auch für den Zugriff über den normalen Webport.
Persistenz
Diese Änderung übersteht einen Neustart des Systems.
Hingegen überschreibt eine Neuinstallation der Firmware oder das gelegentliche RaspberryMatic Firmware-Update auch Konfigurationsdateien und damit diese Änderung. Nach einem solchen recht seltenen Ereignis muss die Änderung in der Konfigurationsdatei, wie oben beschrieben, erneut vorgenommen werden.
Sicherheitsaspekte
Beim Satz „erlaubt die Ausführung beliebiger Scripts“ sollten eigentlich die Alarmglocken klingeln. Um das Risiko zu minimieren, sollte der Zugriff auf die Homematic-Script-API nur verschlüsselt (HTTPS) und nur passwortgeschützt erfolgen.
Benutzer mit einem gültigen Passwort können jedoch beliebige Scripts auch über die normale RaspberryMatic-Weboberfläche ausführen, d.h. das Risiko ändert sich durch die Web-App also nicht.
Über „Systemsteuerung > Einstellungen > Firewall konfigurieren“ kann man, wie oben gezeigt, den Zugriff auf das lokale Netzwerk (192.168.0.*) einschränken.
Wenn solche Systeme hinter einem Internetrouter laufen und nur aus dem lokalen Netzwerk von einem autorisierten Benutzer angesprochen werden können, ist das Risiko also überschaubar.
Diese Konfigurationsänderung wurde mit den folgenden RaspberryMatic-Firmwareversionen getestet: 3.65.11.20221005 und 3.71.12.20230826.
Weitere Links zum Thema
- https://de.wikipedia.org/wiki/Cross-Origin_Resource_Sharing
- https://homematic-forum.de/forum/viewtopic.php?f=65&t=77331
Samstag, 25. Februar 2023
„Neues“ von der Postbank
Ende letzten Jahres hat die Postbank mit viel Aufwand ihre betroffenen Privatkunden über einen anstehenden Umzug ihrer IT-Infrastruktur informiert. Das dies nicht reibungslos über die Bühne gehen würde scheinen sie schon geahnt zu haben.
So wurde etwa die Kreditkartenabwicklung auf eine andere Site ausgelagert und die Übertragung der Sicherheitscodes bei Online-Kreditkartenkäufen erfolgt im Augenblick wieder per SMS.
Zum Jahreswechsel war das System – angekündigter Weise – offline. Nach einigen Anfangsschwierigkeiten in den ersten Tagen ist es jetzt wieder wie gewohnt erreichbar.
Den IT-Umzug hat die Postbank zum Anlass genommen diverse Angebote zu ändern und zu streichen; die hier angegebenen Punkte beziehen sich jedoch nur auf ihr Online-Banking.
Einige sinnvolle Funktionen sind verschwunden. Und bei manchen Sachen fragt man sich, in welchem Jahr wir leben.
Umsatzabfrage
Eine der wichtigsten Funktionen beim Online-Banking ist wohl die Abfrage des Kontostands und der Umsätze. Dies ist auch im neuen System möglich, das war es dann aber auch.
Im „alten System“ bestand die Möglichkeit, diese Umsätze als CSV- oder XML-Datei zur weiteren Verarbeitung herunterzuladen.
Diese Möglichkeit wurde ersatzlos gestrichen.
PDF-Kontoauszüge
Wer versucht, diese oder andere Daten aus den „neuen“ PDF-Kontoauszügen mit Markieren-Kopieren-Einfügen zu holen, erlebt sein blaues Wunder. Wenn man z.B. seine IBAN braucht und diese im Kontoauszug markiert – ja das geht – kopiert und dann woanders einfügt, erhält man einen Buchstabensalat, der nur entfernt mit dem etwas zu tun hat, was das menschliche Auge lesen kann. Hier ein Beispiel einer Überweisung, deren Text sich augenscheinlich markieren lässt. Der kopierte Text in der Zwischenablage sieht aber sehr sonderbar aus. So fehlen z.B. alle Zahlen, was bei Kontoauszügen besonders auffällt:
pbmA Überweisung an
Bundesnetzagentur
fBAk abMUTRMMMMMMMMTRMMNMMT
BfC MAohabcNTRM
serwendungszweckL hundenreferenz
hassenzeicÜen VMN4VMMNU4UR J
Diese „neuen“ PDF-Auszüge erkennt man vor allem daran, dass sie oben rechts nicht mehr das gelbe Postbank-Logo der „alten“ PDF-Auszüge haben, bei denen das Herauskopieren im Übrigen einwandfrei funktioniert.
Der Buchstabensalat aus den neuen PDF-Auszügen erinnert an OCR-Ergebnisse aus der Anfangszeit, wobei man sich natürlich fragt, warum man bei computergenerierten PDF-Dateien überhaupt OCR einsetzen muss.
Daueraufträge
Brokerage
Unter der Rubrik „Investieren“ werden bei der
Umsatzanzeige die Anteile nur mit 2 Nachkommastellen angegeben, und
nicht wie allgemein üblich (und auch im alten System implementiert) mit 3
Nachkommastellen.
Zumindest enthalten die – jetzt nicht mehr computerlesbaren – PDF-Abrechnungen diese 3 Nachkommastellen.
Open-Source-Software, um die Auswirkungen dieser „Verbesserungen“ etwas abzumildern
Der meines Wissens einzige Weg, um im Augenblick Umsätze und Salden ohne Umwege computerlesbar von der Postbank zu bekommen, ist die HBCI-Schnittstelle, wie sie z.B. in Finanzsoftware implementiert ist.
Aber auch das freie Programm Jameica/Hibiscus kann über die HBCI-Schnittstelle kommunizieren.
Über diese Software können – neben anderen Funktionen – Kontoabstände und Umsätze abgefragt, verarbeitet, aber auch exportiert und von anderen Programm weiterverarbeitet werden.
Was die PDFs angeht, die nur so tun, als könnte man ihren Inhalt herauskopieren, so kann man hier eine „richtige“ OCR-Software einsetzen.
Im Linux-Umfeld bietet sich gimagereader an. Der Nachteil hier ist, dass gimagereader ein Programm mit einer GUI ist. Es setzt jedoch die OCR-Engine tesseract ein, die man auch separat, z.B. in Skripts, aufrufen kann.
tesseract verarbeitet jedoch keine PDFs, sodass diese zuerst in eine Bilddatei umgewandelt werden müssen, wie beispielsweise im folgenden Python3-Skript:
from pdf2image import convert_from_path
import pytesseract
pil_image_list = convert_from_path("x.pdf")
# pro Seite ein PPM
# print(pil_image_list)
# erste Seite
img = pil_image_list[0]
text = pytesseract.image_to_string(img, lang="deu")
print(text)
Warum dieser nicht immer 100% fehlerfreie Umweg überhaupt notwendig ist, weiß nur die Postbank.
Reaktionen
Auf diese und andere gemeldete Fehler und Bugs reagiert das Unternehmen allerdings mit Baustein-E-Mails, sodass meine Hoffnung nicht besonders hoch ist, dass diese Meldungen tatsächlich gelesen werden und sich jemand darum kümmern wird.
Sonntag, 9. Januar 2022
Docker: temporary error ... try again later
In case you encounter this error message while creating docker images I want to draw your attention to a more unusual reason (DNS), how to fix it, and the somewhat embarrassing root cause in my case.
Have fun.
When setting up a docker installation on an Ubuntu Server 20.04 LTS system the build process for a docker image that had worked fine on my desktop computer failed with this misleading error message:
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/main/x86_64/APKINDEX.tar.gz
ERROR: http://dl-cdn.alpinelinux.org/alpine/v3.4/main: temporary error (try again later)
Strangely enough I could wget this file from the command line.
If you google this error the standard advice is to update docker. I did (to version 20.10.12) ... but it didn't help though.
With problems like this it's always good advise to try to replicate it with the most simple setup possible.
In this case:
- Get a small Linux system image from the repo (alpine)
- and start a command line inside the container: sh
- try to install a package (curl) within the container
$ docker run -it alpine:3.4 sh
/ # apk --update add curl
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/main/x86_64/APKINDEX.tar.gz
ERROR: http://dl-cdn.alpinelinux.org/alpine/v3.4/main: temporary error (try again later)
WARNING: Ignoring APKINDEX.167438ca.tar.gz: No such file or directory
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/community/x86_64/APKINDEX.tar.gz
ERROR: http://dl-cdn.alpinelinux.org/alpine/v3.4/community: temporary error (try again later)
WARNING: Ignoring APKINDEX.a2e6dac0.tar.gz: No such file or directory
ERROR: unsatisfiable constraints:
curl (missing):
required by: world[curl]
Docker did download the alpine image but inside the container downloading the APKINDEX failed. And yeah - I did wait and tried again later... no luck.
Back inside the container I tried:
/ # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=117 time=14.639 ms
64 bytes from 8.8.8.8: seq=1 ttl=117 time=13.921 ms
64 bytes from 8.8.8.8: seq=2 ttl=117 time=13.956 ms
^C
/ # ping google.com
ping: bad address 'google.com'
Which means: I can reach the internet from inside the container but the DNS resolution obviously isn't working. Let's see who is resolving:
/ # cat /etc/resolv.conf
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients directly to
# all known uplink DNS servers. This file lists all configured search domains.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.
nameserver 129.168.0.1
search local
Who is 129.168.0.1 and how did it became the nameserver? To be honest - it was my fault (more on that later).
Using the only text editor available in a base alpine install I changed it to
/ # vi /etc/resolv.conf
nameserver 8.8.8.8
And yes, when using vi I always have to think very hard how to get the changes written back to disk.
Trying to add the package now works like a charm:
/ # apk --update add curl
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/community/x86_64/APKINDEX.tar.gz
(1/4) Installing ca-certificates (20161130-r0)
(2/4) Installing libssh2 (1.7.0-r0)
(3/4) Installing libcurl (7.60.0-r1)
(4/4) Installing curl (7.60.0-r1)
Executing busybox-1.24.2-r14.trigger
Executing ca-certificates
So the problem is definitely a faulty DNS name server .... How can this be fixed?
If I start the container with the --dns option ...
docker run --dns 8.8.8.8 -it alpine:3.4 sh
apk add runs without a problem. And if I check /etc/resolv.conf it says 8.8.8.8
Slight problem: --dns works with docker run but not with docker build.
You have to tell docker itself to use a different DNS server.
Googles first advise is modifying /etc/default/docker like this
DOCKER_OPTS="--dns=my-private-dns-server-ip --dns=8.8.8.8"
But Ubuntu 20.04 LTS uses systemd and in this case these settings are ignored.
You have to create an override files for this systemd service using
sudo systemctl edit docker.service
with the following content
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --dns 8.8.8.8 -H fd:// --containerd=/run/containerd/containerd.sock
I first located the original docker.service file, copied the ExecStart line, and added the dns option.
The first empty ExecStart is needed to clear its original value before setting the new one... good to know (thanks - herbert.cc).
Everything worked.
So - who is 129.168.0.1? Well, it's a typo. It should read 192.168.0.1 - my cable modem.
I later found it in /etc/netplan/00-installer-config.yaml which sets up the machine's IP address, gateway, DNS resolver, etc.
I must have made this typo while installing the system onto the hard drive using the Ubuntu installer.
But why did the internet connection work at all? I could download files... the docker image for example.
My specific setup made the system use a fixed IP address (as servers usually need one) but it did NOT disable DHCP.
So eventually the DHCP server updated the faulty DNS resolver setting with the correct value and all worked fine.
It seems that docker samples the DNS nameserver during boot-up at a time after the yml-file had set the wrong value and before the DHCP server could replace it with the correct one. It then hands this value to the docker build and docker run processes instead of the nameserver currently in use. As those values are usually identical nobody does notice.
I don't know if I would call this a bug but it is unexpected behaviour.
Now you know.
Useful links
- https://serverfault.com/questions/612075/how-to-configure-custom-dns-server-with-docker
- https://serverfault.com/questions/1020732/docker-settings-in-ubuntu-20-04
- https://docs.docker.com/config/daemon/systemd/
- https://www.herbert.cc/blog/systemctl-docker-settings/
Montag, 7. Juni 2021
Grabbing EPGs from Schedules Direct
TL;DR
You can now find my EPG json grabber client for Schedules Direct on Github.
The utilities download and cache the EPG data in a sqlite database. They can produce an output in xmltv format for systems like EyeTV, MythTV etc.. They can also create short overviews (e.g. by genre) if you want to check what sci-fi episodes are coming up.
The utilities are written in Python3 and should run on any python3 base installation.
The story
A few weeks ago the EPG function in EyeTV on my old Mac Mini stopped working.
Until then I used the Gracenote service integrated in EyeTV to download EPGs. As far as I can tell the Gracenote downloader tries to contact its server but fails. System logs indicate that the OS rejects the connection due to some SSL handshake error. The machine is to old for the installed Mac OS to be updated … so, no hope to get the SSL issue fixed.
This happened – of course – just weeks after I renewed the Gracenote subscription, and unsurprisingly Geniatech – the seller of the subscription – didn’t react on my bug report or plea for help.
What to do?
EyeTV offers two other sources for EPGs: DVB and xmltv
DVB gets the EPG information from the TV signal itself. The problem: In order to receive the signal you must switch to that channel for a few minutes. With over 40 channels this becomes infeasible. And even then you only get 3 days worth of EPG (compared to 14 days with Gracenote).
The xmltv option takes the information from a text file in xmltv format. The format is well documented and EyeTV can read an xmltv file using a special command. But where to get the information from?
Schedules Direct is a provider of EPG information and also offers – unlike many other providers – listings for stations in Europe. However rather than providing the information in xmltv format you have to query their API and get chunks of information back in JSON format.
The utilities
And that’s where the utilities come in.
- sdjsongrab.py is the part that talks to the API and caches the information in a sqlite database.
- You have to run sdconf.py first to configure your name and password and select the lineups (sets of stations) whose schedule you want to download.
- genepg.py will create the xmltv file from the information stored in the database.
- maintenance.py will perform some database related operations.
The most difficult part is to select which lineups to use. A lineup determines the stations whose EPG you can access. There are hundreds of lineups available from which you can choose up to four. They mostly contain stations grouped by geographic location, cable provider, etc. sdconf.py exposes the part of the SD API that helps you select suitable ones.
With the help of filter definition files geneps.py can generate quick overviews of all programs with a given genre and/or name. This can be used for example to get a quick overview of all sci-fi programs or all programs containing “Star Trek” in their title.
maintenance.py can be used to display various information from the database itself. Most notably a list of genres that can be used in the filter definition files.
You can find more information in the README and doc files of this project.
Comimg up...
The software is still in development. Currently I’m observing how the size of the database grows and if and when a pruning is needed. At the moment it's to early to tell.
I only use the generated xmltv file with EyeTV and can’t check it with other software. If you have any suggestions let me know.
Dienstag, 26. Januar 2021
Tagesschau - Coronavirus Live-Feed - RSS-Feed
Es war zugegebenermaßen lästig, jeden Morgen auf tagesschau.de den Corona Live-Feed zu suchen, ihn aufzurufen, ganz nach unten zu rollen und den RSS-Link aus dem entsprechenden Icon zu kopieren, um ihn dann in meinen RSS-Reader einzufügen.
Bei der allgemeinen Umgestaltung der Tagesschau-Seiten scheint dieses RSS-Icon jedoch untergegangen zu sein.
Der Feed als solcher ist jedoch noch da und seine URL folgt dem nachstehenden Muster:
URL der Seite:
https://www.tagesschau.de/newsticker/liveblog-coronavirus-dienstag-175.html
URL des RSS-Feeds:
https://www.tagesschau.de/newsticker/liveblog-coronavirus-dienstag-175~rss2feed.xml
Wochentag und Zahl ändern sich täglich.
Update: 30. Januar 2021
Das Format der URL hat sich leicht geändert. Aus "coronavirus" wurde nur "corona".
https://www.tagesschau.de/newsticker/liveblog-corona-samstag-109.html
Grund dürfte sein, dass die gleiche URL mit "coronavirus" bereits im Mai verwendet wurde.Am Prinzip hat sich aber nichts geändert.
Donnerstag, 13. August 2020
Retro Music Player app and playlists
Until now I've used the Google Play Music app. One reason was that I could store songs I regularly hear locally on my device and didn't need to stream them over and over again via the mobile data connection.
As Google Play Music is being discontinued and I have transferred my collection to its successor - the Youtube Music App - only to find that I have to pay 9,99 € a month for the privilege to have the music I already bought played back locally without streaming.
I've managed - with some difficulty - to download my collection and my playlists from Google Music and I'm now trying to find an app which can play my music (most do) and can import my playlists (here lies the problem).
The Retro Music Player app is an open-source music player for Android which claims to be able to import and export playlists. But this is only partially true.
The export works perfectly as it is implemented in the app. The import is (currently) performed by the operating system and its implementation ranges from "works perfectly" to "doesn't work at all" as many bug reports on GitHub can attest to.
Until RMP decides to implement the playlist import in the app itself the functionality of this feature is left to chance.
Mittwoch, 29. April 2020
Wake Me Up After You Go-Go
The reason that WoL was not working was presumably not the BIOS (which I did update to the current version (E7C02AMS.360)), it was neither the router nor the network cable – as mentioned elsewhere – and my BIOS settings were correct as well.
It turns out that contrary to my other computers it is not enough to simply turn on the settings in the BIOS as shown below. The operating system must inform the motherboard Ethernet subsystem “which kind of WoL” it should use – otherwise that setting, which is not accessible from the BIOS, stays disabled, nothing will happen and it looks as if WoL were not working at all.
The most common WoL option is the so called Magic Packet which can be sent by utilities like etherwake (on Linux) or Wake-on-LAN (on Android), but apparently there are other options as well.
Windows user can specify the option to use in the Control Center, but I’m not running Window, I’m using Ubuntu Linux 20.04 LTS… What to do? The answer is ethtool.
Let’s start with the BIOS settings:
Settings\Advanced\Integrated Peripherals
Onboard LAN Controller: Enabled ... (which is the default)
Settings\Advanced\Power Management Setup
ErP Ready: Disabled ... (which is the default)
Settings\Advanced\Wake Up Event Setup
Resume By PCI-E Device: Enabled
With Linux running, determine the device identifier of your onboard Ethernet “card” using the ifconfig command:
ifconfig
If ifconfig is not installed run:
sudo apt install net-tools
Furthermore you need ethtool:
sudo apt install ethtool
The name of my ethernet device is: enp34s0
Change the following commands accordingly.
Enter:
sudo ethtool enp34s0
Look for the line “Wake-on:”. If the value in this line is “d” then the WoL function is (d)isabled. To make it react to the WoL Magic Packet is has to be set to “g”.
sudo ethtool -s enp34s0 wol g
Check the setting again with:
sudo ethtool enp34s0
Shut-down the computer and try to wake it with a WoL tool as mentioned above.
This command needs to be executed after each boot. The simplest way to achieve this is to append or create the file /etc/rc.local:
#!/bin/bash
ethtool -s enp34s0 wol g
exit 0
Don’t forget to make it executable:
sudo chmod 744 /etc/rc.local
A more elaborate way can be found here. Note: Check the path of ethtool with “which ethtool” and correct the script accordingly.
Wake-up happy….
Links
- https://www.thomas-krenn.com/en/wiki/Wake_On_LAN_under_Linux
P.S.: Here is the German version of the BIOS options:
Settings\Erweitert\Integrierte Peripheriegeräte
Onboard LAN Controller: Aktiviert (default)
Settings\Erweitert\Energieverwaltungs Konfiguration
ErP Ready: Deaktiviert (default)
Settings\Erweitert\Einrichtung der Reaktiverungsereignisse
Fortsetzung durch PCI-E-Gerät: Aktiviert
Donnerstag, 6. Februar 2020
How to set the active camera ... when Blender renders in the background
Background rendering, i.e. rendering without the UI and based on command line parameters alone, is usually the domain of render farms.
But there are situations where this functionality is useful for normal users as well: scripts.
In my case the blend file contains a complex architectural model and various cameras (which you can conveniently set-up and switch between with the “Stored Views” add-on).
Some of those cameras are (virtual) panoramic cameras. Their output will be fed into a generator script to calculate multi-res images for use with the web panorama viewer pannellum (https://pannellum.org) to create a virtual tour.
Wouldn’t it be nice to have a script producing the rendered pictures for all those cameras; it might even call the pannellum generator script afterwards to calculate the multi-res images needed for the virtual tour...
When Blender is started in background mode, various parameters can be set from the command line - among others the frame and scene to be rendered, the render engine and the output path.
Missing however are some settings I would like for my workflow: the active camera and the dimension percentage (Output Properties > Dimensions > Resolution > %). Those values are stored in the blend file and used in the render process.
If you want rendered images from multiple cameras you usually open the blend file, switch the camera, save the blend file and re-render…
As for the other setting: I sometimes forget to switch the resolution from my usual 50% to 100% before starting to render. While rendering without the UI you don’t notice this right away. Something that sets this value to 100% would be nice.
The solution
Blender’s command line option --python-expr lets you enter a short Python snippet which gives you access to all settings in your scene.
To switch the active camera in the current screen use
import bpy
bpy.context.scene.camera = bpy.context.scene.objects.get('XXXXXX')
where XXXXXX is the name of the camera.
The command for setting the resolution percentage value is
bpy.context.scene.render.resolution_percentage = 100
You can test these commands in Blender’s Python console.
Note: It does matter where you put the --python-expr command on the command line. If used at the end of the command it will be ineffective because it changes the parameter after the render process.
My typical Blender background render command looks like this:
blender -b myblend.blend --python-expr "import bpy; bpy.context.scene.camera = bpy.context.scene.objects.get('Camera XXXX'); bpy.context.scene.render.resolution_percentage = 100" -o /tmp/pic_#### -F PNG -x 1 -f 1 -E CYCLES
- -b: background render of myblend.blend.
- --python-expr: use camera ‘Camera XXXX’ and render at 100%
- -o: store under /tmp/pic_####
- -F: store as PNG
- -x: add the PNG extension
- -f: render frame 1
- -E: use cycles render engine
You might use this technique to change other values on the fly without them being saved back to disk.
Montag, 18. November 2019
Berechnung der Vorabpauschale bei Fonds und ETF

In meinem GitHub-Repository ist nun ein kleines Programm zur Berechnung der Vorabpauschale und der Bemessungsgrundlage bei der Kapitalertragssteuer nach dem „neuen“ Investmentsteuergesetz von 2018 verfügbar.
Wichtiger Hinweis
Ich bin kein Steuerberater. Alle Ergebnisse dieser Routine und alle angegebenen Informationen sind unverbindlich und ohne Gewähr. Jegliche Haftung meinerseits ist ausgeschlossen.
Das Programm befasst sich mit einem sehr eng gefassten aber wahrscheinlich recht häufig vorkommenden Aspekt, nämlich der Vorabpauschale und der Bemessungsgrundlage für die Kapitalertragssteuer bei Fonds und ETF, die seit dem Inkrafttreten des Gesetzes am 1.1.2018 erworben wurden. Bei älteren Fonds/ETF gibt es bei der Berechnung des Gewinns weitere Regelungen, die nicht Gegenstand dieses Programms sind.
Worum geht es?
Die Vorabpauschale kann als Steuer auf Buchgewinne beschrieben werden, fällt also auch dann an, wenn kein Geld vom Fonds zum Anleger geflossen ist.
Wenn man Fonds/ETF bei einer inländischen Bank kauft und verkauft, werden alle Berechnungen und Abzüge von der Bank vorgenommen. Die Bank bucht die Steuer automatisch von Ihrem Konto ab und kann ggf. Teile der Wertpapiere verkaufen, wenn sie nicht anders an Ihr Geld kommt. Um Überraschungen zu vermeiden, sollte man die Vorabpauschale im Auge behalten.
Grundsätzlich versteuern muss man das, was der Fonds ausschüttet, und den Kursgewinn, den man zum Schluss (hoffentlich) mit dem Verkauf macht. Dazwischen fällt u.U. die Vorabpauschale dann an, wenn der Kurswert des Fonds steigt. Teile dieser Kursgewinne müssen versteuert werden, können dann aber beim Verkauf abgezogen werden. Man bezahlt also nicht mehr Steuer, sondern nur früher (vorab).
Zweck des Programms
Das Programm berechnet die Vorabpauschale und die Bemessungsgrundlage auf der Grundlage einer geringen Anzahl von Parametern, die dem Anleger bekannt sind (oder sein müssten).
Die eigentliche Routine ist in eine separate Datei ausgelagert und kann auch von anderen Programmen eingebunden werden. Ein Großteil des restlichen Programms dient zum Einlesen der Daten und zur Ausgabe der Ergebnisse.
Die Routine ist das Ergebnis einer längeren Internetrecherche und implementiert die bei der Mehrzahl der Quellen beschriebene Vorgehensweise. Dass sich nicht alle Quellen völlig einig sind und teilweise auch zu anderen Ergebnissen kommen, ist natürlich ernüchternd. Falls Sie also Fehler finden, wäre ich für einen Hinweis dankbar.
Beschreibung der Ergebnisse
Die Vorabpauschale besteuert einen „fiktiven“ Kursgewinn, falls dieser nicht durch die Höhe der Ausschüttungen überschritten wird, und auch nur dann, wenn überhaupt ein Kursgewinn aufgetreten ist.
Um welche Beträge geht es?
Grundlage ist zunächst der Basisertrag. Er berechnet sich aus
Der Basiszins ist eine Prozentzahl, die jährlich vom Bundesfinanzministerium bekanntgegeben wird. Sie beträgt für 2018 0,87%, für 2019 0,52%, für 2020 0,07% und für 2021 0,00%.
Somit errechnet sich der Basisertrag für 2019 für einen Wert von 10.000 € mit:
Dies ist der maximal Wert, der sich ggf. noch um Ausschüttungen reduziert, und die sog. Vorabpauschale bildet*.
Zu dieser Vorabpauschale werden die Ausschüttungen wieder addiert, weil beide Teile versteuert werden müssen. Falls der Fonds nicht ausschüttend (thesaurierend) ist, bleibt es also bei diesem Maximalwert.
Von der Summe wird bei Aktienfonds/-ETF noch die sog. Teilfreistellung von 30% abgezogen. Das ergibt die sog. Bemessungsgrundlage:
Dagegen wird der Sparerfreibetrag von derzeit 801€ (1602 € für gemeinsam veranlagte Verheiratete/Lebenspartner) aufgerechnet - entweder in Form eines Freistellungsauftrags oder später bei der Steuererklärung.
Die Bemessungsgrundlage wird dann noch mit dem Kapitalsteuersatz von zurzeit max. 26,375% (25% + 5,5% Solidaritätszuschlag) multipliziert. Man erhält die tatsächlich zu zahlende Steuer.
* Genauere Informationen zum implementierten Algorithmus finden Sie in der Dokumentation im GitHub-Repository. Er deckt auch Fonds ab, bei denen eine Teilfreistellung von nur 15% bzw. 0% gilt, sowie die Jahre 2018 und 2019 und kann leicht erweitert werden.
Die implementierte Eingabe der Steuerfälle in einer Textdatei ist für Portfolios mit nur wenigen Fonds/ETF ausreichend. Größere Systeme werden wahrscheinlich mit Bildschirmmasken und Datenbanken arbeiten. Die eigentliche Routine bleibt – bis zur nächsten Gesetzesänderung – aber gleich.
Links
Update/Korrektur 25.02.2021:
- Basiszins für 2020 und 2021 nachgetragen
- Korrigiert: Der Sparerfreibetrag wird gegen die Bemessungsgrundlage aufgerechnet, nicht gegen die zu zahlende Steuer.


