DME-Auswertung per serieller Schnittstelle

Klasse! Also ein Einsatz könnte folgendermaßen aussehen:

let incidentData = {
  "reason": "Straße überschwemmt", // Einsatzgrund bzw. Schlagwort
  "keyword": "THL 2", // Stichwort
  "description": "Wasserrohrbruch im Kreuzungsbereich", // Freitext der Leitstelle
  "location": {
    "rawText": "Musterstadt, Einbahnstraße 5 a" // Adresse als Freitext
  }
}

Keines der Felder oben ist ein Pflichtfeld und kann leer oder weggelassen werden, falls es dazu keine Angabe gibt. Es gäbe auch noch mehr Felder, aber die sind entweder aktuell nicht wichtig, oder sie werden mit Standardwerten gefüllt. So wird z. B. als Alarmzeit (time) die aktuelle Uhrzeit angenommen.

Bekommst du auch den ausgelösten RIC zu sehen?

Leider nein. Der Melder ist auf einen eigenen „Informations-RIC“ programmiert. Dieser wird von der Leitstelle nur bei echtem Alarm mit alarmiert (also nicht bei Problealarm oder ähnlichen).
Ich versuche mich gerade in euer Projekt und Node.js einzuarbeiten. Als C-Entwickler ein riesen Spass! :wink:

Ah okay, aber das passt ja auch. Zur Not müsste man das eben zeitbasiert unterscheiden, eine Funktion die für die analogen Melder eh noch eingebaut werden muss.

Das glaube ich :sweat_smile: Wenn dir irgendwo Doku fehlt, sag gerne Bescheid. Ich werde gleich mal noch die READMEs vom Hub aktualisieren, wie man eine Entwicklungsversion ans Laufen bekommt.

Ja, eine Doku wäre super!
Wie gesagt ich werde die nächste Alarmierung aufzeichnen. Ich hoffe dann einen eindeutigen Delimitter zu finden um das parsen zu vereinfachen. Sonst müsste man tatsächlich mit timeouts arbeiten.

So, ich habe mal die READMEs von Hub und Display etwas aufgemöbelt. Also vor allem die in den Unterordnern für server, console usw.

Und es gibt natürlich auch noch https://docs.alarmdisplay.org/
Die Seite kriegt demnächst auch mal ein Update, das bezieht sich alles noch auf die letzt veröffentlichte Beta-Version. Deshalb möchte ich da jetzt bald eine neue schnüren und auch die Docker-Images veröffentlichen, dann passt das wieder zusammen.

Ich habe jetzt mal einen Service zum Auslesen der seriellen Konsole angelegt. Das klappt auch schon ganz gut.
Ich habe jetzt nur ein Problem mit der Datenbank.
Aktuell hat die Tabelle ‚hub_textanalysis‘ einen Fremdschlüssel auf die watchedFolderID in der Tabelle „hub_watched_folders“.
Jetzt musste ich eine neue Tabelle für die Konfiguration der seriellen Ports anlegen. Diese müsste ich jetzt auch über die ID auf die Textanalysenkonfiguration in der Tabelle ‚hub_textanalysis‘ damit ich weiß welche Textanalysekonfiguration ich für den Pagereingang her nehmen muss.
Hast du eine Idee wie man das umsetzen könnte?

Ah, ja so ein ähnliches Problem hatte ich neulich auch, bzw. habe dann gleich versucht, es zu vermeiden. Da ging es um die Druckaufträge für neue Dateien (Tabelle hub_print_tasks).

Da es später auch andere Quellen für Druckaufträge geben soll, gibt es jetzt keine feste Bindung an die watchedFolderId, sondern stattdessen zwei Spalten: event und sourceId. Das event bezeichnet das Ereignis, das den Druckauftrag auslöst (bisher nur ‚found_file‘) und sourceId die ID der Instanz, die das Event auslöst (für ‚found_file‘ die ID eines überwachten Ordners). Dadurch wird das ganze etwas entkoppelter.

Auf dieses Schema sollte die textanalysis-Tabelle auch noch umgestellt werden, um weitere Quellen zu ermöglichen. Ich hatte da primär Emails im Sinn, aber hierfür passt das natürlich auch schon.

OK, verstanden. Dann versuche ich das so einzubauen…

Das wäre super. Und wenn’s wo hakt, gerne fragen.

Noch ein Tipp: Die Skripte für die DB-Migration wurden bei mir im Entwicklungsmodus (npm run dev) immer ignoriert. Mein Workaround war da, die Anwendung einmal zu bauen (npm run compile) und aus dem lib-Ordner zu starten.

Das funktioniert schon ganz gut. Ich habe alles umgestellt und das Anlegen eines Einsatze aus dem seriellen Monitor funktioniert auch schon.
Jetzt fehlt mir tatsächlich nur doch ein Log unseres Pagers damit ich die Texterkennung einstellen kann. Wir hatten zwar zwischenzeitlich schon Einsätze aber irgendwie kam am Pager nix raus. Da bin ich gerade mit der Leitstelle dran. Ich hoffe bis Freitag ist das Problem gelöst.
Dann müssten wir noch die console überarbeiten damit man den pager auch konfigurieren kann.
Soll ich dir meine Änderungen bzgl. serieller Eingang schon mal als PullRequest schicken? Dann könntest du vorab schonmal checken und Feedback geben…

Coole Sache :tada:
Ich habe jetzt erst mal nur wegen der Datenbank draufgeschaut und kommentiert, über den Rest lese ich später noch drüber.

Ich bin dann schon mal gespannt auf die Pager-Ausgabe. Ich glaube, dass die Textanalyse noch ein Mini-Update braucht, um direkt ab dem ersten Zeichen Angaben extrahieren zu können. Bisher wird immer erst nach dem Beginn der ersten section gesucht, und alles davor weggeworfen. Für das Alarmfax ist das sinnvoll, hier wohl eher nicht. Aber das sollte kein Drama sein, und das kann ich schon mal vorbereiten.

Folgendes Problem:
Obwohl ich alle Referenzen zu watchedFolderID in der textanalysis entfernt habe bekomme ich noch folgende Fehlermeldung:
[2021-04-01T07:39:22.524] [ERROR] default - Unhandled Rejection at: Promise Promise {
GeneralError: Unknown column ‚watchedFolderId‘ in ‚field list‘
at new GeneralError (C:\Users\tobiby\source\repos\hub\server\node_modules@feathersjs\errors\lib\index.js:177:17)
at exports.errorHandler (C:\Users\tobiby\source\repos\hub\server\node_modules\feathers-sequelize\lib\utils.js:29:20)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at Object.onNewSerialAlarm (C:\Users\tobiby\source\repos\hub\server\src\services\textanalysis\textanalysis.class.ts:31:30) {
type: ‚FeathersError‘,

Gibt es noch einen versteckten Index oder ähnliches wo er sich noch die „alten“ Spalten der Tabelle merkt?

Meine spontane Vermutung wäre, dass in der server/src/models/textanalysis.model.ts und server/src/models/watchedfolders.model.ts noch die Fremdschlüsselbeziehung konfiguriert ist (ganz am Ende unter associate).

Die hatte ich schon raus gemacht.
Ich kenne die Ursache nicht aber ich habe einen Workaround gefunden.
const textAnalysisJobs = await this.find({
query: {
event: ‚pager_alarm‘,
sourceID: pagerID,
$limit: 1,
$select: [ ‚id‘, ‚event‘, ‚sourceID‘, ‚config‘ ]
},
paginate: false
}) as TextAnalysisData[];
Wenn man das $select hinzufügt und alle Spalten explizit aufzählt dann kommt der Fehler nicht mehr.

Ein paar mal ist es mir auch schon passiert, dass das Tool hinter npm run dev Codeänderungen geschluckt und eine andere Datei aus dem Cache gezogen hat. Das ließ sich dann durch erneutes Starten des Tools beheben.

Puh, war jetzt doch noch ein Stück mehr Arbeit. Neben der Datenbankmigration habe ich auch die UI umgesetzt und die Funktionalität etwas aufgebohrt. So wird nun mehr als eine serielle Schnittstelle gleichzeitig unterstützt und die Baudrate kann eingestellt werden. Beim Anlegen, Verändern und Löschen eines serial monitors wird die Überwachung entsprechend gestartet, verändert oder gestoppt.

Der aktuelle Stand liegt im Branch feature/serial_input.

Zum Testen habe ich mir hier einen Arduino angeschlossen, der auf Befehl einen Text sendet. Aus den RegExps in der LS_Bodenseekreis.ts habe ich versucht, das Originalformat zu rekonstruieren, war aber nicht ganz erfolgreich. Kannst du es mal mit deinen Daten testen?

Hallo,
danke für die Unterstützung!
Ich habe mir den Code geholt und mal ein paar Alarme eingespielt. Sieht nicht schlecht aus.
Unser Format lautet in etwa so (nicht druckbare Zeichen in <>):

ENR:12345 H1 VU Musterhausen, Musterhausen, Musterstraße, 14, L=9?20’43.8348", B=47?46’45.1912", >> Kreuzung Musterstadt 14-16 MSG: - Fahrradsturz, Anruf abgebrochen, schlechte Verbindung

Wenn ich das einspiele bekomme ich folgende Ausgabe:
[2021-04-16T20:40:37.713] [DEBUG] default - {
time: 2021-04-16T18:40:37.678Z,
id: 16,
sender: ‚‘,
ref: ‚‘,
caller_name: ‚‘,
caller_number: ‚‘,
reason: ‚H1 VU‘,
keyword: ‚‘,
description: ‚- Fahrradsturz, Anruf abgebrochen, schlechte Verbindung‘,
status: ‚Actual‘,
category: ‚Other‘,
updatedAt: 2021-04-16T18:40:37.678Z,
createdAt: 2021-04-16T18:40:37.678Z,
location: {
id: 16,
rawText: ‚, Musterstra , , Musterhausen\n Musterhausen,‘,
latitude: null,
longitude: null,
name: ‚‘,
street: ‚, Musterstra‘,
number: ‚‘,
detail: ‚, Musterhausen‘,
postCode: ‚‘,
locality: ‚Musterhausen,‘,
country: ‚‘,
createdAt: 2021-04-16T18:40:37.000Z,
updatedAt: 2021-04-16T18:40:37.000Z,
incidentId: 16
}
}
Leider habe ich gerade das Problem, dass seit der Umstellung auf Digitalalarmierung unser alter Melder im Feuerwehrhaus keinen Text mehr empfangen kann, da er die Verschlüsselung nicht unterstützt.
Das heißt ich muss jetzt erstmal einen neuen Melder installieren der die Verschlüsselung unterstützt und dann auch wieder einen Text ausgeben kann.

Klasse, vielen Dank für das Beispiel. Das hat es schon viel klarer gemacht.

Über das Fragezeichen in der Koordinate hatte ich mich schon gewundert, aber das ist dann wohl ein Ersatz für das Gradzeichen. Auch sind das WGS-Koordinaten, im Fax stehen sonst immer Gauss-Krüger-Koordinaten. Da muss ich noch eine Anpassung vornehmen, damit die richtig verarbeitet werden.

Ok, dann schauen wir mal, ob das Format mit dem neuen Melder noch das gleiche ist.

Was ich noch vergessen habe, hier zu erwähnen: Die Auswertung der seriellen Schnittstelle ist schon seit ein paar Wochen im develop-Branch. In dem Zuge habe ich auch die Config für die LS Bodensee-Oberschwaben nochmal etwas angepasst. Damit kommt nun folgendes heraus:

{
      "id": 201,
      "time": "2021-06-07T09:51:53.000Z",
      "sender": "",
      "ref": "12345",
      "caller_name": "",
      "caller_number": "",
      "reason": "H1 VU",
      "keyword": "",
      "description": "- Fahrradsturz, Anruf abgebrochen, schlechte Verbindung",
      "status": "Actual",
      "category": "Other",
      "createdAt": "2021-06-07T09:51:53.000Z",
      "updatedAt": "2021-06-07T09:51:53.000Z",
      "location": {
        "id": 156,
        "rawText": "Musterstraße 14\n Musterhausen",
        "latitude": 47.779219777777776,
        "longitude": 9.345509666666668,
        "name": "",
        "street": "Musterstraße",
        "number": "14",
        "detail": "",
        "postCode": "",
        "locality": "Musterhausen",
        "country": "",
        "createdAt": "2021-06-07T09:51:53.000Z",
        "updatedAt": "2021-06-07T09:51:53.000Z",
        "incidentId": 201
      }
    }

Was mir noch aufgefallen ist: Ist eigentlich H1 das Stichwort? Dann würde ich das noch in die Eigenschaft keyword verschieben.

Ein Beitrag wurde in ein neues Thema verschoben: Eigene Layout-Definition