ACS Containerisierung

Wir sind aktuell dabei unsere Fenster im Haus zu tauschen, was dazu führte, dass wir die Wand am eingangsbereich neu machen mussten (Holz weg, richtig dämmen, verputzen, streichen).
Da wir von Anfang an den RFID Leser im Eingangsbereich nur „provisorisch“ installiert haben, habe ich mir nun ein schickes Edelstahlgehäuse anfertigen lassen.

Lesereinbau vorher/nachher

Der Leser war wärend der Zeit der Renovierung leider offline.

Reboot mit Problemen

Der Server für das Zugangskontrollsystem ist das Letzte Artefakt, das ich noch nicht Containerisiert habe. Ich habe zwar dran gearbeitete, aber es gab hier noch diverse Probleme und die Integrationstests haben letztlich auch gefehlt. Ich wollte dies in aller Ruhe im sommerurlaub mal angehen. einen alten gebrauchten Testrechner habe ich dafür auch schon installiert gehabt, aber zu diesem Zeitpunkt war das System nicht einsatzbereit.

Auf dem alten Rechner den Docker zum Laufen bringen klappt nicht, da das darunterliegende OS (Ubuntu 16.04 LTS) zu alt war für die Java Requirements. D.b. ich muss den Server komplett neu aufsetzen und ein „Schwenk“ zu einem Container wäre nicht so schnell machbar gewesen. Wäre aber wünschenswert, dann hätte man den Container einfach hin und her schieben können um den Server in Ruhe auf den neuesten Stand updaten zu können.

Aber da der Rechner ja eh schon unten war (aufgrund der Renovierungsarbeiten) wollte ich zumindest mal ein OS Update fahren um die ganzen aktuell anstehenden Patches in Ubuntu 16.04 LTS nachzuziehen. Dabei kam dann der Rechner nach dem Reboot nicht wieder hoch. Scheinbar hat nach der langen Uptime der Rechner (den LESv2 der Thomas Krenn AG) den Reboot nicht verkraftet. Fakt ist, es kommt kein Bild, keine Ausgabe, nichts.

Tja, da half dann nur noch Flucht nach vorne. Ich habe den kleinen alten Testrechner ein Intel NUC) in den Serverschrank gepackt und frisch das OS draufgepackt. Erst ein Ubuntu Server 24.04 LTS, und, aufgrund von Betriebsproblemen (siehe unten), einen Tag später ein Ubuntu Server 22.04 LTS.
Danach binnen 2 Tagen den ACS-Server als Container so fertig bekommen, dass er läuft und alle Funktionalitäten wieder abdeckt (Mail, Pushover, MQTT, Relais ansteuern).
Zwischenzeitlich läuft der Server sogar nicht priviligiert als NonRoot im readonly Modus, das war schon seit Anfang an ein Problem, dass ich aber im Laufe der letzten Tage lösen konnte.

Ubuntu Server 24.04 LTS und HID Devices mit MCP2200 Chipsatz

Ubuntu Server 24.04 LTS ist das aktuelle Ubuntu Betriebssystem. Daher war es naheliegend dieses auch zu verwenden. Ich verwende für das Öffnen der Türe aktuell ein per USB angeschlossenes Relaisboard (USB Relay Module 4 Channels, for Home Automation – v2) der Firma Denkovi Assembly Electronics LTD. Das Board verwendet einen MCP2200 Chip und gibt sich als HiD Device aus. In der Regel wird im Linux unter den Devices dann ein /dev/hidraw0 und ein /dev/usb/hiddev0 angelegt. Leider funktionierte das nur bis Ubuntu Server 22.04 LTS. In Ubuntu Server 24.04 LTS hat sich das System strikt geweigert das Relais so anzulegen wie ich es erwartet hätte. Leider habe ich nach 1 Tag udev Regeln anlegen dann aufgegeben und bin auf Ubuntu Server 22.04 LTS gegangen.

Das Verhalten muss ich bei Zeiten mal genauer untersuchen bzw. wenn es mir hier nicht gelingt eine Lösung zu finden eine Relais Alternative zu suchen. Denkovi hat hier ja diverse alternative Möglichkeiten. Ggf. switche ich ja zu einer IP basierten Lösung.

ACS Komponenten im Container

Es laufen alle Komponenten des Zugangskontrollsystems nun auf einem Container. Damit werden Migrationsszenarien deutlich einfacher werden. Die Java Komponenten laufen in einem Debian Basiscontainer mit JRE21. Alle anderen Komponenten basieren auf schlanken Alpine Basiscontainern.

Alle Container sind mit Trivy sicherheitsüberprüft. Alle erkannten Vulnerabilities werden im Buildprozess dann entsprechend behandelt.

KomponenteBasisStand
ACS ServerDebian + JRE21Containerisiert
ACS ManagerAlpine + Nginx + PHP 8.1Containerisiert
ACS Tag ManagerDebian + JRE21Containerisiert
ACS Pushover ServiceAlpine + Python 3.11Containerisiert
REDISAlpineContainerisiert
LDAPAlpineContainerisiert
MQTTAlpineContainerisiert
ACS, Stand der Containerisierung

Offene Punkte

  1. Hausinterne DNS Probleme in den Griff bekommen: Entweder die Namensauflösung im ACS Server anpassen (herkömmlich statt den Ubunt Standard mit resolverd) oder, da es ein generelles Problem ist, hier mal eine echte Lösung finden.
  2. Erhöhung der RFID Leser Sensitivität, durch Durchbrechen des Faradayschen Käfigs. Leider schirmt der Edelstahlkasten die elektromagnetische Strahlung sehr ab. Ich versuche heute mla mit der Flex den Käfig mit einem Schnitt zu unterbrechen.
  3. RFID Leser mit Ubuntu Server 24.04 LTS ans Laufen bringen (siehe oben).

    Kinderschutz Apps – Medienzeiten

    Nun mal etwas ganz Anderes. Heute möchte ich mal meinen Frust hier loswerden zum Thema Medienzeiten einschränken auf den Elektronischen Endgeräten von Kindern.

    Früher war es einfach, da gab es einen Computer im Haus, da hatte man noch Kontrolle drüber. Heute gibt es neben den PCs und jede menge tragbarer Geräte wie Tablets, Smartphones, Watches, Laptops, Spielekonsolen, VR Brillen und alle können auf irgend eine Weise mit dem Internet verbunden werden.

    Mein Sohn (13) hat für das Homeschooling während des Corona Lockdowns mit 10, einen eigenen PC bekommen. Ich fand schon damals, dass man mit 10 noch keinen eigenen PC haben muss, aber was solls. Die neuen Medien und das Internet ist eben nicht wegzudiskutieren und eine gewisse Medienkompetenz sollen die Kinder ja schließlich auch aufbauen.

    Wir haben zusammen mit unserem Sohn das Thema angegangen. Zwischenzeitlich hat er noch ein Smartphone und ein uraltes Tablet mit Windows drauf. Das ist so alt, dass man da gar keine Updates mehr fahren kann. Aber um MP3s zu hören reicht es.

    Um die Mediennutzung mit den Endgeräten ein wenig unter Kontrolle zu haben gibt es ja diese tollen Helferlein – die Kinderschutz Apps. Diese bieten jede menge Möglichkeiten und sind auch echt toll. Jede Software, sei es nun kostenpflichtige als auch kostenfreie Tools sind eigentlich gut. Aber sie haben im detail alle Ihre Schwachstellen. Und die muss man im laufe der Kindesentwicklung alle leidvoll erfahren.

    Einschränkungen in der Konfiguration oder Limitierungen

    Jedes dieser Tools möchte möglichst viele Einsatzzwecke abdecken. Inhaltskontrolle, Zeitbeschränkung, Bonuszeiten, Ruhezeiten, …
    Da gibt es schon die ein oder andere Überschneidung bei den Ansprüchen die wirklich schwer technisch umzusetzen sind. Oder das Tool ist eben am ende nicht mehr bedienbar durch „normale“ Eltern.

    Beispiele für schwierige Konstellationen die mir AdHoc einfallen:

    • Bildschirmarbeitszeit einschränken, manche Apps sollen aber immer gehen, Ruhezeiten ja, aber telefonieren soll immer gehen
    • Unterstützung aller Endgeräte Linux, Windows, Android, …
    • Inhalte einschränken, aber bitte über alle Apps

    Unser Setup zu Hause / Medienvereinbarung

    Wir wollen grundsätzlich die Mediennutzung beschränken aber trotzdem unserem Sohn erlauben mit Hilfe des Smartphones schulische Dinge zu bearbeiten bzw. Lern-Apps zu nutzen. Auch erlauben wir unserem Sohn das telefonieren sowie Chatprogramme die für das Alter freigegeben sind (z.B. ist WhatsApp erst ab 16). Nicht altersgerechte Inhalte haben wir auch blockiert – soweit möglich.

    Nachdem wir für ein Jahr die Salfeld Kindersicherung genutzt haben sind wir erst zu Microsoft Family Safety geswitcht und jetzt verwenden wir Google Family Link.
    Die Salfeld Kindersicherung war uns auf dauer zu teuer. Microsoft und Google bieten kostenfreie Alternativen die zwar im funktionsumfang nicht so ausgeklügelt aber auch nutzbar sind. Der Teufel liegt aber im Detail. Microsoft kann (konnte zumindest damals) die Bildschirmzeit zwar bestimmen, hat dann aber nicht begrenzt, also konnte nicht sperren. Google Family Link dagegen zählt die Bildschirmzeit nicht immer richtig und hat keine möglichkeit den Google Playstore zu regulieren. Der ist also immer frei.

    Das große Problem bei allen Apps sind die Ausnahmeregelungen. Also per Gieskanne die Bildschirmzeit zu begrenzen ist ok, aber sobald man sagt, die App darf für 20 Minuten genutzt werden oder die App kann immer genutzt werden geht es los. Je nach App sind die Zeitlimits teil der gesamt Mediennutzung oder auch nicht. Das Mischen der Regeln macht aus meiner Erfahrung die meißten Probleme.

    Was nun aber tun, wenn man das lernen mit Lern-Apps fördern möchte. Das Kind im Notfall immer anrufen können soll. Da kommt man um diese Mischung nicht drum rum. Aber genau hier gibt es eine ganz üble Backdoor, die pfiffige Kinder ausnutzen. Denn was machen die Kinder wenn die Bildschirmzeit für die Games und Videostreamingdienste aufgebraucht ist. Man klickt in den Apps rum die dann noch frei sind.

    Die lieben Zusatzfeatures – die geliebten Backdoors der lieben Kleinen

    Viele Apps haben neben der eigentlichen Kernfunktionalität aber auch Zusatzfeatures. Oft kommt hier ein eingebauter Browser zum Einsatz. Und hier geht der Spaß so richtig los.

    Beispiele:

    • Skype: Es gibt eine Seite „Heute“ mit News aus aller Welt
    • Phase6: Schon mal auf Hilfe geklickt?
    • Hilfe, Impressum, Datenschutz Menüs in diversen Apps

    Oft ist das noch in der App, aber sobald man auf weiterführende Infos klickt wird oft die Homepage des Produktherstellers genutzt. Da muss man die Inhalte schließlich nur an einer Stelle pflegen und lässt die App einfach drauf zugreifen. Man baut einfach einen Browser ein.

    OK, man denkt sich – das ist jetzt nicht so wild. Aber die Kids sind ja nicht blöd. Wenn man mal einen Browser hat (auch wenn es keine Eingabezeile für URLs gibt) muss man eben so lange Links anklicken, bis man auf einer Seite landet die dann den passenden Link zu Youtube und Co enthält. Viele Medienseiten haben ja oft auch mal Facebook, LinkedIn, X (Twitter) oder Youtube Auftritte, die in der Fußzeile der Seite auftauchen. Alternativ kann man auch über links versuchen auf die Google Seite zu kommen und hat dort über die suche alle Möglichkeiten.

    Wenn die Kinder dann mal am Ziel angekommen ist, dann freut man sich als Eltern, dass das Kind fleißig 10h lang Vokabeln gelernt hat und das Kind freut sich, dass die Eltern so dämlich sind.

    Wifi hacks mit dem Smartphone

    Ich hatte ja schon erwähnt, dass mein Sohn ein uraltes Tablet hat auf dem Windows drauf ist. Das ist so alt, da bekommt man keine Kindersicherungsapps drauf. Jedenfalls nicht mal eben so.

    Also hatten wir das einfach nicht im WLAN eingebucht und haben den WLAN Adapter im Tablet auch komplett deaktiviert. Ja, es war bis zu einem gewissen Alter ein Schutz aber die Kinder werden ja älter, also war das Tablet irgendwann dann doch im Netz. Darüber ungefiltert stundenlang im Internet unterwegs. Als wir es gemerkt haben – wurde die MAC des Tablet einfach gesperrt.

    Letzten Dienstag war mein Sohn ganz pfiffig. Er hat nun mit sein Smartphone ein eigenes WLAN aufgespannt, das Tablet da dran gehängt. Das Smartphone war weiterhin im lokalen WLAN eingehängt, es hat in dem Fall als Router fungiert – eben „mobile tethering“.
    Also egal ob die Bildschirmzeit rum ist, mit dem Tablet kann man ja weiter konsumieren. Das taucht dann auch nirgends im Netz auf (außer man hat entsprechendes Equipment).
    Die Eltern freuen sich – der liest sicher was oder er lernt für die Schule. Das Kind freut sich, dass die Eltern so dämlich sind.

    Das Tablet habe ich nun erst mal eingezogen, denn mit allen mir bekannten Kinderschutz Apps kann man das mobile tethering nicht kontrollieren.

    Was hilft denn nun?

    Die Kinder meinen es ja nicht böse – die finden diese Hacker Challange ja vermutlich ganz amüsant. Ich gratuliere meinem sohn immer wenn er eine neue Lücke entdeckt und ausgenutzt hab. Erkläre ihm aber auch, dass ich die Lücke zu seinem Wohl schließen muss. Er nimmt das zwischenzeitlich sehr locker. Also reden, transparenz schaffen und ein gutes Verhältnis aufrecht erhalten sind die besten Tipps. Aber vertrauen ist gut – eine gewisse Kontrolle ist besser.

    Technische Möglichkeiten? Tja, was fällt mir so ein was man da technisch machen kann:

    1. Netzwerkseitiges reglementieren über WLAN AP oder Firewall. Z.b. Internetzugriffe von den Kindergeräten dort zeitlich eingrenzen, oder Grppen von Internetinhalten blocken oder zeitlich eingrenzen (Streaming Dienste, Online Spiele, …) – dazu braucht es aber eine entsprechende Firewall / Internet Router der das gut kann und entsprechend Kenntnis die Features richtig zu konfigurieren.
    2. Einen Proxy installieren und allen Traffic über den Proxy leiten – braucht man halt entsprechend Kenntnisse, Zeit und einen Rechner für der immer mitläuft und Strom frisst. Das Netzwerk Setup wird komplizierter und Fehleranfälliger. Man muss sich halt mit auskennen.
    3. Alles über die Bildschirmzeit regeln und die Verantwortung dem Kind übertragen was in der Zeit passiert und damit leben, dass schulische Inhalte dadurch eben hinten anstehen oder wegfallen.
    4. Das Handy grundsätzlich sperren und ach Absprache dedizierte Apps freigeben (Aufwändig)

    Code Refresh beim Zugangskontrollsystem und Containerisierung

    Was in letzter Zeit passiert ist

    Die letzten Wochen habe ich nun dazu genutzt das Zugangskontrollsystem etwas zu überarbeiten. Nicht die interne Codebasis, aber das drum herum.
    Zum einen werden die Einzelteile immer mehr in Container Images (Docker) gepackt. Dies wird zukünftig dabei helfen, die Skalierbarkeit zu verbessern und auch die Ausfallsicherheit weiter zu erhöhen. Der Schritt ist noch nicht entgültig abgeschlossen aber ich bin auf einem guten Weg.

    Dieser Schritt hat nun vorausgesetzt, die aktuelle FEIG SDK (Generation 2) (OBIDISC4J v5.6.3) zu verwenden. Leider haben wir ja gelernt, dass die aktuellste Generation 3 der SDK nicht mehr (oder auch noch nicht) verschlüsselt mit dem RFID Leser kommuniziert. Das folglich ein Ausschlußkriterium darstellt für den Betrieb als Zugangskontrollsystem.
    Also bleiben wir vorerst auf der Generation 2 des SDKs.

    Weiterhin setze ich nun Java 17 ein, da es im Docker Container doch deutlich besser performt und weniger Speicherprobleme hat als die älteren Java Versionen. Das hatte aber zur Folge, alle bislang vewendeten Java Extensions (javax Klassen) zu den Neuen (jakarta Klassen) zu migrieren (Danke Oracle).
    Das war zum Glück nicht so aufwändig und konnte ohne größere Schwierigkeiten erledigt werden. Hier hing dann aber auch der gesamte Build-Prozess dran und da musste ich auch noch einiges gerade rücken. So ist das eben mit dem „Rattenschwanz“.
    Vorteil ist, ich bin wieder up-to-date mit den Maven Repos und der Build-Prozess ist nun ausgelagert in eine Azure DevOps Pipeline.

    Docker

    Allgemein

    Nicht alle Probleme kann man mit Docker lösen, aber es gibt uns durchaus Möglichkeiten einige der Probleme in den Griff zu bekommen.
    Zum einen wird das „Shipping“ einfacher, da alles im besagen Container liegt was für die Laufzeit benötigt wird. Die FEIG Bibliotheken sind ja „closed source“ und die Java Libraries sind nur Wrapper rund um diese Linux Bibliotheken die im System zu installieren sind. Das macht es schwer die Software „mal eben schnell“ wo anders einzusetzen.
    Zum anderen, wenn nun aber alles in handliche Päckchen (Container Images) gepackt wurde, kann man eben mal die Version tauschen und ratzfatz zurückrollen. Was Upgrades deutlich einfacher macht und auch wenn man mal die Hardware darunter tauschen möchte.

    ACS Tag-Manager

    Hier plane ich auch bereits seit längerem den ACS TAG Manager umzubauen. Diese Anwendung ist dafür verantwortlich, die RFID Tags zu beschreiben. Die Kernfunktionalität soll hier zukünftig als REST API in einem Docker Container laufen. Das Ganze mit API first Ansatz mt der aktuellen OpenAPI Spezifikation.
    Das wird es deutlich einfacher machen, die Kommunikation zwischen Anwendung und RFID TAG zu abstrahieren.
    Am Ende steht dann die Integration in den ACS-Manager. Diese Anwendung ist in PHP geschrieben und würde die REST API verwenden, um die Tags direkt aus der Management Anwendung heraus zu beschreiben.

    Aber bis dahin ist es noch ein langer Weg. Kurzfristig muss nun die zentrale ACS-Server Komponente erfolgreich in den Docker Container gepackt werden, damit ist dann schon viel gewonnen.

    Docker Basiscontainer

    2021 hatte ich versucht mit Alpine Linux als Basiscontainer zu arbeiten. Damals noch mit OpenJRE 11. Dort scheiterte es dann erst an der FEIG Bibliothek v4 (Gen 2) und danach an einer nicht kompatiblen libc Bibliothek. Daher musste ich auf Debian als Basis ausweichen mit dem Upgrade auf die FEIG Bibliothek v6 (Gen 3).
    Dann kam allerdings die Gen 3/Gen 2 Thematik und das Fehlen der Verschlüsselung was mich so frustrierte, dass ich dann zunächst nicht weiter daran gearbeitet habe.

    Nun, 2 Jahre später, versuche ich mal einen Neuanfang. Zunächst auf Basis Debian. Problem ist hier aber, dass der Debian Container schon so viele ungepatchte Sicherheitslücken enthält, dass ich da ein ungutes Gefühl habe, dass so zu betreiben.
    Allerdings darf man sich da nichts vor machen, denn wenn man Debian auch so als OS laufen hat, hat man ja auch die selben Lücken. Aber beim Containerbau hat man ja so schicke Tools, die einem das gleich zeigen. Bei einer Bare-Metal Installation fällt das ja erst mal nicht auf.

    Wichtig ist aber erstmal, dass es überhaupt funktioniert, dann kann man sich um die Optimierung kümmern. Da fallen mir schon noch Dinge dazu ein. Man könnte z.B. die Teile löschen die eine Sicherheitslücke haben (soweit diese nicht benötigt werden) oder rman nähert sich doch von Alpine Linux und versucht die fehlenden Dinge zu integrieren.

    Stand der Containerisierung

    Die einzelnen Bestandteile des Zugangskontrollsystems haben folgenden Stand was die Containerisierung angeht:

    KomponenteStand
    ACS ServerContainerisiert (aber ungetestet)
    ACS ManagerContainerisiert
    ACS Tag Manageroffen
    ACS Pushover ServiceContainerisiert
    REDISContainerisiert
    LDAPContainerisiert
    MQTTContainerisiert
    ACS, Stand der Containerisierung

    Die Homepage WG

    Seit 2 Wochen komme ich etwas zur Ruhe und habe mir endlich die Zeit genommen meine Homepages zu konsolidieren. Besser gesagt habe ich die Inhalte der Homepages:

    • Cybcon Industries
    • Oberdorf IT-Consulting
    • Cybcon’s Blog

    nun in einer Homepage vereinigt. Nach langem hin und her habe ich mich dazu durchgerungen den WordPress Blog „Cybcon’s Blog“ als neue Heimat für die bestehenden Inhalte zu verwenden. Der Blog ist nun im Menü unter „Cybcon’s Blog“ zu finden, die anderen Inhalte sind größten Teils die Inhalte meiner Oberdorf IT-Consulting Seite. Diese wird auch das Erscheinungsbild hier verändern bzw. hat das bereits getan, da es sich ja um den gewerblichen Teil handelt der gewisse Anforderungen erfüllen muss.

    Aber der Blog wird weiter bestehen mit allen alten (und hoffentlich auch neuen) Inhalten.

    FEIG Java SDK v3 noch immer ohne Cryptofunktion

    Nachdem ich letztes Jahr angefangen habe mit dem Java SDK v3 preview (Version 6.0.0-rc3) meine Software zu migrieren stockte es ja an der fehlenden Authentisierung zum Leser. Leider musste ich nun 1 1/2 Jahre später feststellen, dass Version 6.2.0 noch immer keine Authentisierung zum Leser unterstützt.

    Ticket bei FEIG ist offen – mal sehen wie die Antwort aussieht.

    Nachtrag

    Zwischenzeitlich gab es Feedback von FEIG. Aktuell gibt es keinen Zeitplan für die Re-Implementation des Features. Es wird auf die Verwendung von SDKv2 verwiesen.

    Da dieses SDK nicht im Container läuft (so war jedenfalls das Ergebnis meiner Tests), geht die Entwicklung hier wieder schlafen.

    ACS Manager endlich verfügbar

    Allgemein

    Nach sehr stockender Entwicklungszeit ist nun endlich das Webfrontend zur Verwaltung der Transponder, Benutzer, Rollen und Regeln fertig gestellt. Ein paar Funktionen fehlen noch aber für die tägliche Arbeit sollte es zunächst mal ausreichen.

    Screenshot der Transponderverwaltung

    Funktionsumfang

    • Benutzer: Hinzufügen, Löschen und Bearbeiten von Benutzern.
      Wichtig sind die Pflege der zentralen Informationen eines Benutzers. Auch werden die dem Benutzer zugeordneten Transponder aufgelistet, die durch Klick auf das Symbol einfach deaktiviert werden können. Jeder Benutzer können eine oder mehrere Rollen zugeordnet werden.
    • Transponder: Aktivieren und Deaktivieren von Transpondern. Pflege der Benutzerzurdnung.
    • Rollen: Definition von Rollen mit einem beschreibenden Text.
    • Regeln: Regeln können den Zugang einschränken. Folgende Regeln werden unterstützt:
      • Zugang innerhalb von Datumsgrenzen
      • Zugang innerhalb von Uhrzeitgrenzen
      • Zugang nur an geraden/ungeraden Kalenderwochen (Pflege eines Teilers und eines Offset)
    • Zugangspunkte: Verknüpfung von Rollen und Regeln.
    • Monitor: Anzeige der Zugangsversuche und ob dieser erfolgreich war oder abgelehnt wurde.

    Gesamtarchitektur

    Mit dem ACS Manager (und dem darin eingebetteten Access Monitor) schließt sich nun die Lücke in der Gesamtarchitektur.
    Hinzugekommen sind außerdem ein Pushover Gateway, welches sich auf die Statusmeldungen im MQTT subscribed und die Nachrichten versendet. Sowohl ACS Manager als auch Pushover Gateway laufen als Docker Container.

    Gesamtarchitektur

    Offene Punkte im ACS Manager

    Bislang wird das Codieren der Transponder über die Weboberfläche nicht unterstützt. Daher ist das Management der Transponder noch in einem frühen Stadium.

    Next Steps

    Die Containerisierung soll weiter vorangebracht werden, da ich hierdurch eine hohe Flexibilität als auch eine saubere Verwaltung der Infrastruktur mit Container Boardmitteln hinbekomme.
    Das ist die Fortführung aus dem letztes Jahr begonnen Code Refresh, der leider Mitte letzten Jahres eingeschlafen ist. Allerdings fehlt hier nicht mehr so viel, um den Server komplett mit der neuen Feig Java Bibliothek am Laufen zu haben. Letztes Jahr fehlte ja noch Unterstützung für die SSL Verschlüsselung zwischen Leser und Server. Ich hoffe, dass dies zwischenzeitlich implementiert ist. Nach dem Code Refresh ist der nächste Schritt die Containerisierung des Servers und der komplette Umzug auf Docker.

    Danach werde ich mich an die Neuentwicklung des Tag Managers machen. An Stelle des lokal laufenden Java Programms, soll ein Webbasierter REST Microservice als Herzstück eingesetzt werden um mit dem Leser zu kommunizieren. Die Programm und Ablauf Logik wird dann in den ACS Manager integriert werden (jedenfalls so der Plan).

    Blog kaputt – Blog wieder da

    Nach einem ungeplanten Ausfall meines Blogs bin ich seit heute wieder online. OK, mir war klar, dass PHP 5 outdated war und dass es früher oder später keine Updates mehr gibt. Aber dass die Updates der Plugins funktionieren mir dann diese den Dienst verweigern, daran hatte ich nicht gedacht.

    Zum Glück war ich eh dabei die Seite umzuziehen, nun war es etwas ruppig aber immerhin, der Blog läuft wieder und die Daten konnte ich auch alle retten. Alles schick auf WordPress 6 und PHP8.

    Coderefresh

    Seit dem letzten Firmwareupdate hat sich nicht viel getan. Seit dem sind 2,5 Jahre vergangen und das System leistet anstandslos seinen Dienst ohne jegliche Ausfälle.

    Vor 3 Wochen habe ich begonnen den Quellcode nach Azure DevOps umzuziehen. Via Azure Pipelines werden nun die einzelenen Java Bibliotheken voll automatisiert gebaut.

    Vor 2 Wochen habe ich angefangen mich nun endlich um das Management System zu kümmern. Dieses wird als PHP WebAnwendung umgesetzt und als Docker Container bereitgestellt. Mit start dieses Projekts kam nun auch die Idee, die Java Anwendungen als Docker Container zur Verfügung zu stellen. Die ersten Tests mit der FEIG Bibliothek OBIDISC4J 4.8.0 waren allerdings nicht erfolgreich. Bei start des Tagmanagers (zur Initialisierung der RFID Medien) beendet dieses sich nach dem Start direkt mit einem Coredump. Ein Ad-Hoc upgrade auf die Version 5.5.2 (die aktuelle Version) endet mit einer Fehlermeldung, dass die Feig Crypto Componente sich nicht initialisieren lässt. Daraufhin habe ich mich mal an den Support der Firma FEIG ELECTRONIC GmbH gewendet.

    Die Firma arbeitet allerdings aktuell an einer neuen Generation der Java Bibliotheken und mir wurde empfohlen gleich auf die dritte Generation upzugraten, allerdings wird hier einiges an Codingaufwand auf mich zukommen. Der 18. Januar 2021 ist offizielles Releasedatum des ersten Release Candidate der neuen Java Bibliothek. Allerdings noch ohne Crypto Componente.

    Ich habe mich dazu entschlossen das Angebot anzunehmen und die Anwendung(en) entsprechend umzuschreiben. Ich werde diese Gelegenheit nutzen um folgende Optimierungen durchzuführen:

    • Überführung der Konfiguration aus der Konfigurationsdatei in den LDAP
    • Dynamische Ermittlung der Zugangspunkte (aus dem LDAP) und erstellen der Listener, damit soll es möglich sein mehrere Leser mit einer Serveranwendung zu versorgen.

    Vorbereitungen für den Coderefresh, wie ein Upgrade auf Java 11, das aktualisieren der anderen eingebundenen Bibliotheken und die eEinbindung der neuesten Maven Plugins, habe ich heute abgeschlossen.

    Da ich jetzt wieder Betatester spiele, wird es wohl auch wieder mehr Updates hier im Blog geben.

    IoT mit ESP8266 und DHT22

    Ziel des Projekts sollte es sein günstige IoT Sensoren zu erstellen und in FHEM einzubinden. Hierzu habe ich folgendes Szenario erstellt:

    1. Entwicklerboard (ESP8266)
    2. angeschlossener Temperatur und Luftfeuchte Sensor (DHT22)
    3. Connect via WLAN
    4. Ermittlung der Ablesezeit von einem NTP Server
    5. Erstellen eines JSON Strings
    6. Publish auf MQTT Server (Mosquitto)
    7. Verwenden des DeepSleep Modus beim ESP8266 um Strom zu sparen (für Batteriebetrieb)
    8. FHEM liest die Daten vom MQTT Server und visualisiert diese.

    Mosquitto einrichten

    Zunächst habe ich den MQTT Server eingerichtet. Ich habe mich hier für Mosquitto entschieden. Das Ganze läuft als Docker Container.

    Da die IoT Devices in einem eigenen WLAN Netz befinden, musste die Firewall auf den MQTT Server freigegeben werden.

    Zusätzlich wurde eine Benutzerauthentisierung eingerichtet.

    das Mosquitto aclfile.conf sieht wie folgt aus:

    # this only affects clients with username admin
    user admin
    topic read $SYS/#
    topic readwrite #
    
    # This only affects clients with username esp8266
    user esp8266
    topic write /environmental_sensors/#
    
    # this affects all clients
    pattern write $SYS/broker/connection/%c/stat

    Mit mosquitto_passwd kann man dann die Passwörter in die Passwortdatei speichern. Nach einem Reload des Mosquitto (kill -hup) akzeptiert der MQTT Broker die Schreibrequests der IoT Devices auf allen Topics die mit „/environmental_sensors/“ anfangen.

    FHEM

    Um FHEM an den MQTT anzubinden benötigt man folgende Konfigurationen:

    #MQTT - https://haus-automatisierung.com/hardware/fhem/2017/02/13/fhem-tutorial-reihe-part-26-esp8266-arduino-mqtt-temperatur-an-fhem.html
    define Mosquitto MQTT mqttServer:1883
    
    # wandelt JSON Strings aus dem reading "data" im Device "mqtt01".
    define Jason2Readings01 expandJSON mqtt01:data.*
    
    # Erstellen Device "mqtt01" zum lesen aus dem MQTT Server
    define mqtt01 MQTT_DEVICE
    attr mqtt01 IODev Mosquitto
    attr mqtt01 icon temp_temperature
    attr mqtt01 room IoT
    attr mqtt01 stateFormat Temperatur: temperature°C<br>Luftfeuchtigkeit: humidity%
    attr mqtt01 subscribeReading_data /environmental_sensors/iotLocation
    
    # Logging der Daten aus den readings "temperature" und "humidity"
    define FileLog_mqtt01 FileLog /var/log/fhem/mqtt01-%Y-%m.log mqtt01:(temperature|humidity).*
    attr FileLog_mqtt01 logtype esp8266-dht22:Plot,text
    
    # Define GPlot zur Visualisierung
    define wl_mqtt01 SVG FileLog_diningRoomServerRack:esp8266-dht22:CURRENT
    attr wl_mqtt01 label "Klima IoT Device 01"
    attr wl_mqtt01 room IoT
    attr wl_mqtt01 title "Klima IoT Device 01

    Die passende gplot Datei esp8266-dht22.gplot sieht dann so aus:

    set terminal png transparent size <SIZE> crop
    set output '<OUT>.png'
    set xdata time
    set timefmt "%Y-%m-%d_%H:%M:%S"
    set xlabel " "
    set ytics nomirror
    set y2tics
    set yrange [0:99]
    set y2range [10:50]
    set title '<L1>'
    set grid xtics y2tics
    
    set y2label "Temperatur in C"
    set ylabel "Luftfeuchtigkeit in %"
    
    #FileLog 4:temperature:0:
    #FileLog 4:humidity:0:
    
    plot \
      "< awk '/temperature/{print $1, $4}' <IN>"\
         using 1:2 axes x1y2 title 'Temperatur' with lines lw 2,\
      "< awk '/humidity/ {print $1, $4+0}' <IN>"\
         using 1:2 axes x1y1 title 'Luftfeuchtigkeit' with lines\ 

    ESP8266

    Nun zur eigentlichen Entwicklung des ESP8266. Ich verwende aktuell die Arduino IDE für das Flashen. Hier sind ein paar zusätzliche Bibliotheken zu installieren:

    Da ich mit dem DeepSleep Modus des ESP8266 arbeite, ist der Quellcode nur in der standard Funktion „void setup()“ enthalten. Die Funktion „void loop()“ bleibt in dem Fall leer.

    Der Kopfbereich des Programms sieht dann so aus:

    /* ESP8266 + WiFi connection, DHT22 Humidity and Temperature Node reading
     * and send to MQTT Broker
     */
    
    #include <PubSubClient.h> // @see: "https://pubsubclient.knolleary.net/api.html"
    #include <ESP8266WiFi.h>  // @see: "https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/readme.html"
    #include <DHT.h>
    #include <ArduinoJson.h>  // @see: "https://arduinojson.org/"
    #include <NTPClient.h>    // @see: "https://diyprojects.io/esp8266-web-server-part-3-recover-time-time-server-ntp/#.W876FvZCSUk"
    #include <WiFiUdp.h>
    #include <ctime>          // to parse epoch into ISO 8601 Zulu Time String
    
    // initialize the clients
    WiFiClient espClient;
    PubSubClient client(espClient);
    #define DHTTYPE DHT22 // DHT11 or DHT22
    #define DHTPIN  2
    DHT dht(DHTPIN, DHTTYPE, 11);
    WiFiUDP ntpUDP;
    NTPClient timeClient(ntpUDP, "ntpServerName", 0, 60000); // 
    
    // The MQTT server connection parameters
    const char* mqtt_server = "mqttServerName";
    const int mqtt_port = 1883;
    const char mqttUser[] = "esp8266"; // MQTT broker user
    const char mqttPass[] = "myIoTPasswordForMQTT"; // MQTT broker password
    String clientName = ""; // MQTT client name
    // The MQTT topics to publish messages to
    String topicPrefix = "/environmental_sensors/";
    String topicLocation = "iotLocation";
    String topic = topicPrefix + topicLocation;
    
    // DeepSleep time in us
    long deepSleepTime = 6e8; // 60e6 is 60 Seconds 9e8 is 15 Minutes

    Danach folgen ein paar Helfer Funktionen.

    /**
     * macToStr - converts a MAC address to a String
     * @param mac: uint8_t* MAC address
     * @return: String the MAC address as String
     */
    String macToStr(const uint8_t* mac)
      {
      String result;
      for (int i = 0; i < 6; ++i)
        {
        result += String(mac[i], 16);
        if (i < 5)
          result += ':';
        }
      return result;
      }
    
    /**
     * floatToStr - converts a float to a String
     * @param f: float, the float to convert
     * @param p: int, the precission (number of decimals)
     * @return: String, a string representation of the float
     */
    char *floatToStr(float f, int p)
      {
      char * pBuff;                         // use to remember which part of the buffer to use for dtostrf
      const int iSize = 10;                 // number of buffers, one for each float before wrapping around
      static char sBuff[iSize][20];         // space for 20 characters including NULL terminator for each float
      static int iCount = 0;                // keep a tab of next place in sBuff to use
      pBuff = sBuff[iCount];                // use this buffer
      if (iCount >= iSize - 1)              // check for wrap
        {
        iCount = 0;                         // if wrapping start again and reset
        }
      else
        {
        iCount++;                           // advance the counter
        }
      return dtostrf(f, 0, p, pBuff);       // call the library function
      }

    Danach kommen die Funktionen für den Verbindungsaufbau und die Datenverarbeitung.

    WLAN Verbindungsaufbau:

    /**
     * setup_wifi - connects to a WiFi network
     * and log the IP address and MAC of the Device
     */
    void setup_wifi()
      {
      const char* ssid = "iot-wlan";
      const char* password = "iotWLANpassword";
      const String clientNamePrefix = "esp8266-";
    
      delay(10);
      // We start by connecting to a WiFi network
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);
    
      // WiFi only as client
      WiFi.mode(WIFI_STA);
      // Authenticate to WiFi network
      WiFi.begin(ssid, password);
    
      while (WiFi.status() != WL_CONNECTED)
        {
        delay(500);
        Serial.print(".");
        }
    
      Serial.println("");
      Serial.println("WiFi connected");
    
      // get the MAC address of the device
      uint8_t mac[6];
      WiFi.macAddress(mac);
    
      // log MAC address and IP address
      Serial.print("MAC address: ");
      Serial.println(macToStr(mac));
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());
    
      // append MAC Address to clientName to connect to MQTT
      clientName = clientNamePrefix;
      clientName += macToStr(mac);
      }

    MQTT Verbindungsaufbau

    /**
     * setup_mqtt - connects to MQTT broker and subscribe to the topic
     */
    void setup_mqtt(String clientName)
      {
      client.setServer(mqtt_server, mqtt_port);
      Serial.print("Connect to MQTT Broker ");
      Serial.println(mqtt_server);
      if (!client.connect((char*) clientName.c_str(), mqttUser, mqttPass))
        {
        Serial.print("failed, RC=");
        Serial.println(client.state());
        }
    
      // Loop until we're reconnected
      Serial.print(".");
      while (!client.connected())
        {
        delay(500);
        Serial.print(".");
        }
    
      Serial.println("");
      Serial.println("MQTT connected");
    
      // process incoming MQTT messages and maintain MQTT server connection
      client.loop();
      }

    Ermitteln des Aktuellen Datums und Uhrzeit per NTP

    /**
     * read_ntp - connects to ntp server, make an update and return epoch
     * @return: unsigned long, time in seconds since Jan. 1, 1970 (unix time) 
     */
    unsigned long read_ntp()
      {
      // Start NTP client
      Serial.println("Start NTP Client.");
      timeClient.begin();
    
      // get time
      Serial.println("Get NTP datetime");
      timeClient.update();
      unsigned long epoch = timeClient.getEpochTime();
    
      // Stop NTP client
      Serial.println("Stop NTP Client.");
      timeClient.end();
    
      return(epoch);
      }

    Auslesen des DHT22 Sensors

    /**
     * read_dht - read the DHT22 sensor values and return results
     * @return: String, the mqtt payload of the readings
     */
    String read_dht()
      {
      String payload;
      float t, h;
    
      Serial.println("Try to read from DHT sensor!");
      h = dht.readHumidity();
      t = dht.readTemperature();
      // Check if any reads failed and exit early (to try again).
      while (isnan(h) || isnan(t))
        {
        Serial.println("Failed to read from DHT sensor!");
        Serial.println("Try again in 5 seconds");
        // Wait 5 seconds before retrying
        delay(5000);
        h = dht.readHumidity();
        t = dht.readTemperature();
        }
    
      Serial.println("DHT Sensor readings:");
      Serial.print(t);
      Serial.println("°C");
      Serial.print(h);
      Serial.println("%");
    
      // adjust readings
      //h = h * 1.23;
      //t = t * 1.1;
    
      // convert float to String with precission of 1
      String tPayload = floatToStr(t, 1);
      String hPayload = floatToStr(h, 1);
    
      // get NTP Time
      unsigned long epoch = read_ntp();
      Serial.print("Zeit von NTP: ");
      Serial.println(epoch);
      // convert to datetime String
      char timestamp[64] = {0};
      const time_t epochTime = epoch;
      strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%SZ", localtime(&epochTime));
      Serial.println(timestamp);
    
      // create a JSON object
      StaticJsonBuffer<200> jsonBuffer; // Buffer calculation see "https://arduinojson.org/v5/assistant/"
      JsonObject& root = jsonBuffer.createObject();
      root["datetime"] = timestamp;
      root["location"] = topicLocation;
      root["temperature"] = tPayload;
      root["humidity"] = hPayload;
      // generate json string for MQTT publishing
      root.printTo(payload);
      Serial.println(payload);
    
      return(payload);
      }

    Die Funktion void setup()

    /**
     * setup - the main function after booting the microcontroller
     */
    void setup()
      {
      // initialize serial console with 115200 bauts
      Serial.begin(115200);
      Serial.setTimeout(2000);
      // Wait for serial to initialize.
      while(!Serial) { }
    
      // connect to WiFi network
      setup_wifi();
    
      // connect to MQTT Broker
      setup_mqtt(clientName);
    
      // read DHT22 temperature and humidity
      String payload = read_dht();
      Serial.println("MQTT message payload to send to topic.");
      Serial.print("Payload: ");
      Serial.println(payload);
    
      // send payload to topic
      bool topicRetained = true;
      if (client.publish((char*) topic.c_str(), (char*) payload.c_str(), topicRetained))
        {
        Serial.print("published environmental data to topic ");
        Serial.println(topic);
        }
      else
        {
        Serial.print("FAILED to publish environmental data to topic ");
        Serial.println(topic);
        Serial.print("MQTT state: RC=");
        Serial.println(client.state());
        }
    
      // Wait 20 seconds before proceeding
      Serial.println("Waiting for 5 seconds");
      for (int i = 0; i < 5; ++i)
        {
        Serial.print(".");
        client.loop(); // process incoming MQTT messages and maintain MQTT server connection
        delay(1000); // 1 Second
        }
      Serial.println();
    
      // disconnecting from MQTT broker
      Serial.println("Disconnecting from MQTT Broker.");
      client.disconnect();
    
      // Wait 20 seconds before proceeding
      Serial.println("Waiting for 5 seconds");
      for (int i = 0; i < 5; ++i)
        {
        Serial.print(".");
        client.loop(); // process incoming MQTT messages and maintain MQTT server connection
        delay(1000); // 1 Second
        }
      Serial.println();
    
      // close WiFi connection
      Serial.println("Closing WiFi connection");
      espClient.stop();
    
      // going into deep sleep
      Serial.println("Going into deep sleep.");
      ESP.deepSleep(deepSleepTime);
      }
    
    
    /**
     * loop - the ESP loop while the microcontroller is running
     */
    void loop()
      {
      }

    Ergebnis

    Nachdem alles sauber aufgesetzt ist purzeln dann munter im MQTT Topic die Nachrichten rein:

    MQTT.fx

    Und werden im FHEM dargestellt:

    FHEM

    Die Ausgabe an der seriellen Console der Arduino IDE sieht so aus:

    Arduino IDE

    Und so sieht das Board aus (noch nicht zugeschnitten und das passende Gehäuse fehlt auch noch):

     

    MQTT mit Eclipse Mosquitto

    Zwischenzeitlich läuft das Zugangssystem stabil. In der Zwischenzeit sind einige Umstellungen erfolgt:

    • Umstellung auf Maven für die Java Builds
    • Veröffentlichung einiger OpenSource Artefakte auf Maven Central
    • Installation eines neuen Docker Hosts
    • Installation eines Eclipse Mosquitto MQTT Servers (als Docker Container)

    Den MQTT Server hatte ich ursprünglich für die geplante IoT Infrastruktur (mit ESP8266 und ESP32 basierten Sensoren – hier werde ich auch berichten sobald die ersten Sensoren in Betrieb gehen) installiert. Ich habe diesen auf einem alten Raspberry Pi 1 Model A aufgesetzt als Docker Container.

    Für das User Management System hatte ich bereits länger geplant einen Access Monitor geplant. Dieser sollte die letzten Zutritte visuell darstellen. Also wer hat wann zuletzt einen Zugang angefragt und wie war der Status dazu. Hier soll unter anderem auch ein Bild des Benutzers kommen angezeigt werden das aus dem LDAP Server geladen wird.

    Ich hatte lange überlegt wie man einen solchen Monitor implementieren könnte. Vorallem wie dieser die Daten übermittelt bekommt.

    Mit MQTT ist die Sache nun relativ einfach. Das Zugangskontrollsystem muss nur den Status eines Zutritts in einen Topic des MQTT Servers Publishen. Der Zutrittsmonitor subscribed auf diesen Topic und erhält so alle notwendigen Informationen zur Visualisierung.

    Für den Publish der Nachricht aus dem Zugangskontrollsystem verwende ich nun den Eclipse Paho Java Client. Die Bibliothek war unkompliziert zu integrieren.
    Der Zutritts Monitor ist eine Webanwendung. Für den subscripe verwende ich aktuell Eclipse Paho JavaScript Client. Dieser war etwas Tricky, denn das Beispiel auf der Seite hat bei mir nicht funktioniert.

    Folgender JavaScript Sourcecode führte dann zum Erfolg:

    <head>
    <script> // configuration var mqtt; var reconnectTimeout=2000; var host="myMQTTServer"; var port=9001; var clientId="oitc-acs-monitor"; var topic="/oitc-acs" // called when the client connects function onConnect() { // Once a connection has been made, make a subscription and send a message. console.log("Successfully connected to " + host + ":" + port); console.log("Subscribing to topic " + topic); mqtt.subscribe(topic); } // called when a message arrives function onMessageArrived(message) { // console.log(message.payloadString); obj = JSON.parse(message.payloadString); console.log(obj); } function MQTTconnect() { console.log("Try to open connection to " + host + ":" + port); mqtt = new Paho.MQTT.Client(host,port,clientId); mqtt.onMessageArrived = onMessageArrived; // Valid properties are: timeout userName password willMessage // keepAliveInterval cleanSession useSSL // invocationContext onSuccess onFailure // hosts ports mqttVersion mqttVersionExplicit // uris var options = { timeout: 3, userName: "acsMonitorUser", password: "myUsersPass", keepAliveInterval: 60, useSSL: true, onSuccess: onConnect, mqttVersion: 3, }; mqtt.connect(options); } </script> </head> <body>
    <script>
    MQTTconnect(); </script>
    </body>

    Wenn die Seite lädt, verbindet sich die Webanwendung mit dem MQTT websocket und subscribed den topic. Da die Nachrichten „retained“ vom Zugangskontrollsystem gesendet werden, wird auf jeden Fall der letzte Zugriff im JavaScript consolen Log angezeigt. Bei weiteren Zugängen erscheinen diese ebenfalls im Log.

    Die nächsten Schritte sind nun die Anzeige auf der HTML Seite. Ich werde hier mit jQuery arbeiten um mir das Leben etwas einfacher zu machen. Einen ersten Prototypen habe ich bereits am Laufen. Die nächste Herausforderung ist nun, das Bild der Person noch aus dem LDAP Server zu laden. Ich werde berichten, sobald ich hier wieder ein Stück weiter gekommen bin.

    Abschließend noch das aktuelle Architektur Schaubild:

    FEIG Firmware v2.9.0

    Seit dem letzten Firmware Update lief nun der Leser eine lange Zeit ohne Abbrüche. Das Prolem scheint wohl gelöst zu sein. Leider hatte mit der Firmware allerdings die Signalisierung der LEDs und des Buzzers am Leser nicht mehr funktioniert.

    Nachdem nun einiges an Zeit vergangen ist hatte ich nochmals bei der FEIG nachgefragt ob der Fehler zwischenzeitlich erkannt und behoben wurde.

    Prompt erhielt ich schon eine neue Firmware v2.9.0. Nach einspielen der Firmware scheint nun die Ansteuerung der LEDs und Buzzer wieder zu funktionieren. Ob diese Firmware auch stabil läuft wird die Zeit zeigen. Bisher gab es allerdings keine Ausfälle zu verzeichnen.

    FEIG OBID Firmware Version 2.8.131

    Nachdem nach dem letzten Firmware Update die KeepAlive Abbrüche nicht weggegangen sind habe ich dies der FEIG gemeldet. Da wohl ein anderer Kunde ein ähnliches Problem hat, hat die FEIG für diesen kunden den Netzwerk Stack in der Firmware optimiert. Die FEIG hat mir den Release Candidate für den Leser zum Test zur Verfügung gestellt.

    Das Flashen des Lesers mit dem RC ging, wie beim letzten mal, ohne Probleme und das Zugangskontrollsystem hat automatisch die Verbindung zum Leser wieder hergestellt.

    Mal sehen ob sich das Problem damit löst, ansonsten muss ich wohl Netzwerk Traces mitlaufen lassen um das Problem genauer zu Untersuchen.

    FEIG OBID Firmware Version 2.8.0

    Seit Nutzung des Lesers OBID ID CPR.50.10 der Firma FEIG ELECTRONIC GmbH habe ich mit Verbindungsabbrüchen in der Kommunikation des Lesers mit dem Server zu kämpfen. Das Ganze zeigt sich wie folgt:

    Im „Notifymode“ kann der Leser KeepAlive Requests an den Server senden. Dies habe ich auf eine recht knappe Zeit (5 Sekunden) eingestellt. In unregelmäßgien Abständen hat der Leser jedoch, ohne erfindlichen Grund, diese KeepAlive Requests eingestellt. Nach einigem Experimentieren habe ich hierfür einen Workaround gefunden.  Im Falle eines ausbleibens der Requests sende ich einen CPU Reset an den Leser. Dies hat meist geholfen.

    Leider hat sich das Ganze nach Einschalten der Verschlüsselten Verbindung verschärft. Zum einen kommen die Verbindungsabbrüche nun häufiger und das Senden des CPU Reset hat auch nicht mehr geholfen. Als Alternative könnte ich nun einen System Reset schicken der den gesamten Leser bootet. Habe ich aber nicht weiter implementiert.

    Ich tippe hier auf einen Memory Leak im Leser und habe den Bug der Firma FEIG gemeldet. Scheinbar hat noch ein weiterer Kunde diesen Fehler im System und konnte diesen mit dem Firmware Update auf Version 2.8.0 beheben. Der Leser an der Türe hat beim mir die Firmware Version 2.6.0.

    Ich erhielt also die aktuelle Firmware und das OBID Firmware Update Tool. In der Beschreibung fand ich allerdings den Hinweis dass die Konfiguration des Lesers beim Flashen zurückgesetzt werden kann. das wollte ich aber auf jeden Fall verhindern. Der Leser ist nämlich fest in der Außenwand verbaut und die Netzwerkkonfiguration mit der Firewall dazwischen ist recht aufwändig umzubauen. Daher bat ich um Klärung in welchen Fällen der Leser die Konfiguration beim Flashen verliert.

    Vor einer woche habe ich dann die Antwort vom technischen Support erhalten dass bei einem Update von 2.6.0 nach 2.8.0 die Konfiguration nicht zurückgesetzt wird. Daher habe ich mich heute an den Update gewagt.

    Zunächst mit dem Leser an meinem Schreibtisch (bisher Firmware Version 2.7.0).

    Das OBID Firmware Update Tool lies sich einfach installieren (Archiv entpacken) und starten. Nach eingabe von IP Adresse und Port findet ws auch sofort den Leser und fragt nach dem Passwort zur Authentisierung. Nachdem man dieses eingegeben hat, kann man die XML Datei mit der neuen Firmware wählen und das Flashen kann beginnen.

    Zunächst wird der Bootloader auf Version 1.0.0 gebracht (512 Blöcke) und danach autmatisch die Leser Firmware (2048 Blöcke). Beides ging reibungslos. Nach jedem Flash Vorgang wird der Leser automatisch gebootet (also insgesamt 2 mal).
    Am Ende kommt ein Beep und eine Ready Meldung.

    Der Start des Zugangskontrollsystems ging danach ohne weitere Modifikationen.

    TOP!

    Nun muss sich zeigen ob die Verbindungsabbrüche mit der neuen Firmware Version auch wirklich behoben sind. Ansonsten muss ich wohl wieder einen Call aufmachen.

    Neues Feig Java SDK 4.8.0

    Kuze Info am Rande.

    Es gibt ein neues Java SDK von der Firma FEIG Electronic GmbH. Heruntergeladen ist es. Leider ist das SDK nicht kompatibel mit v4.7. Daher musste ich ein paar Anpassungen am Listener vornehmen. Ob das SDK tut wie es soll und ob der SSL Bug damit behoben wurde werde ich die kommenden Tage mal testen.

    Ich werde berichten 🙂

    Aktuell sieht die Architektur so aus. Mal sehen ob die 2 gelben Verbindungen bald grün werden.