Aus den Quellen bauen

Hi,

ich habe mich ein bisschen mit den Quellen auf github vertraut machen wollen. Dabei ist mir aufgefallen, dass das Repo hub-console archiviert ist. Es sieht für mich so aus, dass alles Sourcen jetzt in GitHub - alarmdisplay/hub: Component for collecting, processing and forwarding alerts enthalten sind.

Daher habe ich wie im Readme versucht, das Programm mit npm start zu starten. Dabei kommen die folgenden Fehler:

root@8ff5cef3e50a:/usr/local/hub/server# npm start

> hub-backend@1.0.0-beta.1 start /usr/local/hub/server
> npm run compile && node lib/


> hub-backend@1.0.0-beta.1 compile /usr/local/hub/server
> shx rm -rf lib/ && tsc

src/services/index.ts:4:21 - error TS2307: Cannot find module './uploads/uploads.service' or its corresponding type declarations.

4 import uploads from './uploads/uploads.service';
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/services/ocr/ocr.class.ts:23:19 - error TS2339: Property 'on' does not exist on type 'never'.

23     uploadService.on('created', (blobResult: BlobResult) => this.onUpload(blobResult))
                     ~~

src/services/watchedfolders/watchedfolders.class.ts:112:32 - error TS2339: Property 'create' does not exist on type 'never'.

112           await uploadsService.create({ buffer: buffer, contentType: 'application/pdf' })
                                   ~~~~~~

src/services/watchedfolders/watchedfolders.class.ts:208:39 - error TS2339: Property 'create' does not exist on type 'never'.

208                 return uploadsService.create({ buffer: buffer, contentType: 'application/pdf' })
                                          ~~~~~~


Found 4 errors.

Es sieht für mich so aus, als ob der Ordner src/services/uploads im neuen repo fehlen würde. Kann das sein?

Anschließend habe ich dann probiert das Programm (mit dem kopierten Ordner aus hub-console) zu starten und bekomme anschließend folgenden Fehler:

2020-09-27T15:07:52.455] [WARN] default - The static files for the console UI could not be found, the path /console will not work

Ich habe leider von Nodejs keine Ahnung. Was muss man machen, um das Programm aus den Quellen zu bauen?

Viele Grüße
Andi

Hallo,

tut mir leid für die späte Antwort.

Deine Beobachtung ist richtig, die zuvor einzeln geführten Repos für hub und display wurden archiviert und in jeweils ein Repo zusammengeführt.

Tatsächlich, da ist mir bei der Zusammenführung der upload-Service durchgerutscht, der fehlt im Repo. Im Beta-Release ist er aber enthalten. Der Unterschied zu den Quellen ist hier, dass die console gebaut und der Ordner an die richtige Stelle verschoben wurde. (Das löst dann auch den zweiten Fehler).

Wenn du diese Anleitung befolgst, sollte es eigentlich klappen. Aber melde dich gerne, wenn es doch nochmal haken sollte.

Der Prozess zum Bauen aus den Quellen ist noch nicht richtig dokumentiert bzw. automatisiert. Ich hatte mal was gebaut, aber das ist durch die Zusammenführung der Repos wieder hinfällig geworden und noch nicht wieder repariert.

Viele Grüße,
Andreas

1 „Gefällt mir“

Hi Andreas,

kein Problem.

Ich habe dir gerade zwei Pull-Requests geschickt. Ich wollte die Anwendung aus einem Container heraus starten. Ich fand es eleganter, dazu die benötigten Dateien aus den Quellen zu bauen, anstatt es herunterzuladen.

Die benötigten Dateien sind in dem Pull-Request enthalten. Vielleicht erleichtert es Anderen auch den Einstieg und ich kann hierdurch indirekt zur Dokumentation beitragen.

Folgendes ist mir hierbei aufgefallen:

  1. Beim ersten starten der Container mit docker-compose wird die Datenbank erst eingerichtet, jedoch startet die Applikation schon und schlägt daher mit einem Fehler fehl. Wäre es machbar, dass man in einer Schleife auf die Datenbank eine gewisse Zeit wartet?

  2. Wenn die Datenbank frisch nach deiner Anleitung aufgesetzt wurde, stürzt die Anwendung reproduzierbar mit dem Fehler [ERROR] default - Could not query folders to watch { GeneralError: Table 'ad_hub.hub_watched_folders' doesn't exist ab. Daher sollte entweder die Datenbank richtig initialisiert werden oder das Programm selbst übernimmt die Initialisierung. Beim zweiten Start (eigentlich der Dritte, siehe 1.) klappt es fehlerfrei.

Weiterhin würde ich anregen, dass man die Applikationen komplett per Code initialisieren kann. Das heißt per API alle benötigten Keys usw. anlegen und entsprechend weiterverwenden und auch die Displays anlegen und konfigurieren kann. Ich vermute, das ist bisher wenn dann über einen Dump der Datenbank möglich.

Viele Grüße
Andi

1 „Gefällt mir“

Hi Andi,

vielen Dank! Ich bin leider erst jetzt dazugekommen, mir die PRs mal genauer anzusehen. Klasse Arbeit, das passt schon mal zu sehr großen Teilen zu dem, wie ich mir es vorgestellt hatte. Anmerkungen mache ich dann direkt im PR.

Das depends_on von docker-compose legt ja leider nur die Startreihenfolge fest und wartet nicht bis ein Container wirklich bereit ist. Ja, das wäre sinnvoll, dass der Datenbank zu Beginn eine gewisse Zeit eingeräumt wird. Sollte es in dieser Zeit nicht klappen, kann man den Prozess immer noch mit einem Fehler beenden.

Ja, das habe ich noch so im Kopf, dass FeathersJS an dieser Stelle kein Promise anbietet, auf das man Warten könnte. Da gab es mal einen Issue dazu, ich mache mich mal schlau, ob es da Fortschritt gab. Ansonsten gibt’s erst mal einen schmutzigen Check, ob alle Tabellen da sind, bevor es weitergeht.

In der Theorie müsste das jetzt schon gehen, da der erste Benutzer sich selbst registrieren darf. Ab da kannst du über die API alles machen. Allerdings bräuchte es dann noch einen Weg, die API-Keys für die Displays in den localStorage der Browser zu bekommen. Die Datenbank hätte ich erst mal als gegeben und dauerhaft angenommen, auch über Updates hinweg. Falls die wirklich mal neu gemacht werden sollte, ist ja bestimmt ein Backup vorhanden :grin:

Hi,

ich bin gespannt auf eine Kommentare :slight_smile:. Ich habe mittlerweile ein paar kleine Änderungen/Verbesserungen lokal, die ich eventuell noch pushen müsste/sollte, da mein ursprünglicher Vorschlag nicht funktionierte.

Ansonsten läuft es schon ganz gut. Ich habe auch drei Testfaxe von der ILS bekommen, die richtig erkannt werden. Die Faxe hatte ich mit der Fritzbox abgefangen. Leider erkennt tesseract bei allen Dateien manche Buchstaben nicht richtig, wie zum Beispiel 0 (Null) anstannt O. Ich vermute das müsste man noch per regexp abfangen. Ich melde mich dazu aber nochmal später.

Aktuell versuche ich, die Applikation mit VS Code und einem Debugger zum Laufen zu bekommen, damit ich hoffentlich beim Testen ein bisschen schneller bin. Zieht sich aktuell, da ich keine Ahnung von Typescript/Java Script habe :smiley:

Hier noch ein Kommentar zu deiner Anmerkung.

Ich habe meine Änderungen nochmal auf deinen Commit 2b372c724d1dd gerebased. Und ich bilde mir ein, dass dadurch das Problem behoben ist.

Vielen Dank und viele Grüße

Ah, sehr schön! Probierst du das mit tesseract direkt aus oder lässt du es schon durch die Erkennung laufen? Das Faxformat der ILS Augsburg dürfte ja nicht komplett passen?

Ja, da gibt es leider ein paar Schwankungen. Allerdings kann man tesseract auch eine Liste von Worten mitgeben, die dann bevorzugt erkannt werden. Das dürfte vor allem für Abkürzungen wie OG (statt 0G oder 06) hilfreich sein. Auch Straßennamen oder Stichwörter müssten so ausgebessert werden können. Ich probiere mal, die Liste von Worten als Einstellung einzubauen.

Das dürfte Zufall gewesen sein, es ist ein bisschen Glücksspiel, ob die Datenbank schnell genug überprüft wurde oder nicht. Bzw. war ein Glücksspiel, denn ich habe das jetzt im develop-Branch gefixt. Zum einen wird die Datenbank jetzt über Migrationscripts aufgebaut und andererseits gibt es nun ein Promise, auf das Services warten können.

Sowohl als auch. Ich habe deine Konfiguration kopiert und an die ILS Bamberg angepasst. Wie stellst du dir vor, dass man zwischen den verschiedenen ILSen umschaltet? Kann man das parametrierbar machen? Ich kann es die nächsten Tage auch einchecken. Derzeit finde ich noch unschön, dass einige Begriffen wegen der Texterkennung angepasst werden müssen.

Danke für den Tipp, ich muss mich mal intensiver mit tesseract beschäftigen, um das zu testen.
Macht es Sinn für die Abschnitte reguläre Ausdrücke zu verwenden? Kann natürlich sein, dass es sich mit jedem Fax ändert und man dauerhaft am erweitern der RegEx ist.

Danke dafür. Ich habe aber die Befürchtung, dass etwas noch nicht ganz passt. Ich muss den Container immer noch zweimal starten. Beim ersten Start gibt der Hub-Container folgendes aus:

hub_1      | [2020-12-10T22:22:23.380] [INFO] default - Feathers application started on http://localhost:3030
hub_1      | [2020-12-10T22:22:23.440] [ERROR] default - Database migration failed: connect ECONNREFUSED 172.18.0.3:3306

Ich kann mich zwar auf der Oberfläche anmelden, wenn ich jedoch einen neuen Benutzer anlegen will, bekomme ich folgende Fehlermeldung: Table 'ad_hub.hub_users' doesn't exist
Gleiches passiert auch beim display.

Deine Anmerkungen im PR habe ich eingearbeitet. Danke hierfür.

Für’s Erste wollte ich das in der Console unter Eingang → Texterkennung / Analyse als Einstellung einbauen. Mittelfristig soll aber dann die flowcontrol.ts durch eine dynamischere Konfiguration ersetzt werden. So könnte es sein, dass für einen Alarmeingang per Fax die eine Textanalyse benötigt wird und gleichzeitig für einen Alarmeingang per Email eine andere (bei uns z. B. Fax von der ILS, Email von einer Abschnittsführungsstelle).

Bezieht sich das auf die falsch erkannten Wörter oder meinst du etwas anderes?

Hier bin ich mir ehrlich gesagt unsicher, ob du vorschlägst, die Abschnitte per RegEx zu erkennen, oder ob du kritisierst, dass es schon so ist. Kann man so oder so lesen :smiley:. Also die Anfangsmarkierungen für die Abschnitte sind bereits als RegEx implementiert, obwohl bisher ein einfacher String gereicht hätte. Allerdings dürfte es flexibler sein, hier gleich eine RegEx zu verlangen.

Aaah, stimmt. Ich habe ein Problem gelöst und das zweite vergessen ^^ Gewartet wird aktuell nur auf die Datenbankmigration, jedoch nicht auf die Verbindung. Hole ich nach.

Und danke für die Anpassungen im PR, schaue ich mir auch gleich an.

Ich mein damit, dass in meiner lokalen Datei textanalysis/config/ILS_Bamberg.ts beispielsweise EINSATAGRUND steht, damit das Programm läuft. Hatte noch nicht mehr Zeit mich intensiver mit möglichen Lösungen zu beschäftigen. Daher ist die Datei noch nciht im Repo. Falls du es für weitere Entwicklungen vorteilhaft siehst, kann ich es aber auch schon einchecken.

Ah sorry! :smiley: Ich bin mit der Syntax leider nicht vertraut, aber die beginningMarks sehen/sahen für mich nicht wie RegExs aus… Mein Vorschlag wäre z.B. Objektinfo durch so etwas wie [O|0]BJEKTINFO zu erkennen. (Ich hatte das mal kurz so probiert, was aber auf die Schnelle nicht geklappt hatte)
Da tesseract bei mir aber beispielsweise bei Einsatzgrund das „Z“ als „A“ erkannt wird, habe ich die Befürchtung, dass man immer wieder die Expressions anpassen muss.
Korrigiere mich, falls ich falsch liege, bei mir war es zumindest so, dass das die Erkennung nicht funktioniert hatte, sobald eine beginningMark nicht mit dem erkannten Text übereingestimmt hat.

Danke für die Anmerkungen. Hab deine Vorschläge übernommen.

Ja, die sind in der Kurzschreibweise notiert (eingefasst zwischen zwei Schrägstrichen). Die beiden hier sind gleichbedeutend:

let regex = /asd+f/
let regex = new RegExp('asd+f')

Für die Objektinfo kannst du es mal mit /[O0]BJEKTINFO/ versuchen. Der senkrechte Strich ist hier nicht notwendig, das hatte ich bei der ILS Augsburg fälschlicherweise so gemacht. Habe gestern ein paar Dinge korrigiert: Make the RegExps more general to accept other characters instead of c… · alarmdisplay/hub@edafb9a · GitHub

Entsprechend würde das natürlich mit /EINSAT[AZ]GRUND/ funktionieren, aber das ist keine dauerhafte Lösung. Da wäre mir auch die Gefahr zu hoch, dass sich plötzlich irgendwo anders ein weiterer Buchstabe ändert und nix mehr geht. Ich habe mir das mit der Wortliste für tesseract nochmal angesehen und das dürfte klappen. Du legst eine Textdatei ins gleiche Verzeichnis wie das TIF, und trägst darin die Worte (eines pro Zeile) ein. Dann hängst du an den Befehl --user-words datei.txt an.

Der Plan wäre, in der Config für die Textanalyse eine Liste mit wichtigen Wörtern mitzugeben, die sicher erkannt werden müssen. Die Liste wird dann in das Arbeitsverzeichnis als Textdatei abgelegt, bevor tesseract aktiv wird. Dazu muss ich unter Umständen ein bisschen mehr umbauen. Bis dahin kannst du mit dem Einchecken noch warten.

Es lässt sich aktuell leider nicht elegant lösen, dass alles erst hochfährt (und insbesondere auf eingehende Verbindungen hört), sobald die Datenbank bereit ist. Das wird wohl erst mit der nächsten Major-Version des Frameworks gehen. Deshalb wird jetzt der Prozess einfach beendet, wenn die Datenbankverbindung nicht zustande kommt. Sowas fällt dann auch im Monitoring auf, bzw. Docker startet den Container bei entsprechender Konfiguration wieder neu bis es klappt.

Ich habe mir das Thema Texterkennung auch nochmal angesehen. Leider hat die Option --user-words bei meinen Versuchen keinen Effekt auf die Texterkennung. Die Ergebnisse sind exakt gleich…

Ich habe noch probiert, ob das deutsche Modell von GitHub - tesseract-ocr/tessdata_best: Best (most accurate) trained LSTM models. bessere Ergebnisse liefert und tatsächlich wird der Text bei mir besser erkannt.
Nachteilig ist jedoch, dass die Texterkennung merklich länger dauert. Mit dem Modell über die Ubuntu-Paketquellen braucht es ca. 3,6 s und mit dem besseren Modell rund 19 s. Prinzipiell fände ich die längeren Zeiten akzeptabel… Ich werde es nochmal auf einem Raspberry 4 testen und die Zeiten vergleichen.

So, jetzt habe ich den Ablauf für die Faxerkennung so abgeändert, dass zum Zeitpunkt der Texterkennung schon bekannt ist, nach welchem Layout der Text danach zerlegt wird. Dadurch kann jetzt eine Liste an Wörtern mitgegeben werden, die bevorzugt erkannt werden sollen (vgl. aktualisierte Config für ILS Augsburg).

Ich bin noch dabei, die UI an den neuen Flow anzupassen, aber du kannst gerne schon mal deine Config per PR einreichen. Dann wird auch die Auswahlliste für die Layouts gleich doppelt so lange :wink:

Edit 2021-02-28: Die UI ist jetzt auch soweit.

Ich hab die Datei entsprechend angepasst und einen PR gestellt. Allerdings bin ich noch nicht zum Testen gekommen…

Wie vorher geschrieben, hatte die --user-words leider nicht den erhofften Erfolg gebracht. Ich muss mir mal anschauen wie du die Datei zusammenbaust, vielleicht hatte ich dabei noch einen Fehler gemacht.

Edit 05.03.2021: Ich habe versucht mein Layout zusätzlich einzubinden, bin aber auf die Schnelle gescheitert. Wäre cool wenn du ein Beispiel liefern könntest :slight_smile:

Ich habe die Doku unter Alarmfax - Projekt Alarmdisplay um die Beschreibung zum Hinzufügen einer neuen Layout-Definition erweitert. Das sollte die zwei fehlenden (und nicht offensichtlichen) Schritte abdecken :wink:

Ich bin auch gespannt, wie das mit den --user-words klappt. Ich hatte tatsächlich auch einen Fall, bei dem es nicht so gut geklappt hat. Dabei handelte es sich aber um ein älteres Fax, bei dem noch eine leicht andere Schriftart verwendet wurde. Falls es bei dir immer noch Fehlerkennungen gibt, vergleiche mal dein Fax mit dem Textfax, ob das kleine F und die 4 anders aussehen.

Mittlerweile habe ich nun auch einen Fall, bei dem EINSATAGRUND erkannt wurde, bei drei anderen Faxen passiert es nicht. Vereinzelt macht auch das Doppel-T in MITTEILER und EINSATZMITTEL Probleme, indem sich noch ein I einschleicht.

Das Problem mit dem Doppel-T ließ sich in der Regel mit den User Words lösen. Ich habe jetzt aber auch nochmal die Parameter für die Umwandlung des PDFs angepasst, was weniger Probleme macht. Das einzige, das ich nicht zuverlässig wegbekomme, ist EINSATAGRUND. Deshalb habe ich das jetzt tatsächlich als /EINSAT[AZ]GRUND/ in die Config übernommen.

Hast du es auch mal mit tessdata_best probiert?

Ich habe leider nur 3 Testfaxe zum Testen. Die ILS lässt leider keine weitere Faxnummern parallel zu und aktuell hängt noch das bestehende Fax an der aktuellen Nummer dran.

Ich bin die letzten Wochen leider nicht mehr zum weiteren Testen gekommen, daher konnte ich meinen PR auch noch nicht probieren bzw. anpassen. Ich hoffe, dass ich über Ostern wieder dazu komme.

Nein, noch nicht. Wäre aber mal einen Versuch wert.

Kein Problem. Ich kann den theoretisch auch mergen und die fehlende Kleinigkeit selbst nachtragen. Das wichtigste ist die Config und die hat ja gepasst.

Mit tessdata_best klappt es deutlich besser. MITTEILER, EINSATZGRUND und EINSATZMITTEL werden fehlerfrei erkannt, auch ohne --user-words. Allerdings wurde einmal aus einer Ölspur eine "Ö1lspur", was mit tessdata_fast nicht passiert ist. Das ß inmitten von Großbuchstaben erkennt tessdata_best auch zuverlässiger, tessdata_fast macht oft ein B daraus.

Der Zeitaufwand ist wie du schon sagtest, deutlich spürbar. Auf dem Raspberry Pi 4 ist ziemlich krass, hier erhöht sich die Zeit im Schnitt von 10 auf 58 Sekunden. Bei stärkerer Hardware ist das Verhältnis ähnlich, aber auf einem ganz anderen Niveau. Auf meinem Laptop geht es von 2,5 auf 11,5 Sekunden. Ich denke, die beste Lösung wäre eine Option, mit der man einen alternativen Ort für tessdata angeben kann. Wer die Leistung hat bzw. die längere Zeit in Kauf nimmt, kann so tessdata_best oder sogar ein selbst trainiertes Modell einbinden.