PositionSync-Demo

Aus ARTECO Wiki
Version vom 22. Dezember 2009, 15:39 Uhr von Alex (Diskussion | Beiträge) (Hinweis auf Code per Mail eingefügt)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen

Die PositionSync-Demo ist eine Auskopplung des zum OSC3 gehörenden PositionSync als eigenständige Anwendung. Sie ermöglicht es, unabhängig vom OSC3-Client Positionsdaten zu übertragen und ist zudem als Beispiel für die Nutzung der XML-Schnittstelle gedacht.

Wie komme ich zu einer lauffähigen Anwendung?

Quelltext

Erhältlich per Mail an ticket@arteco.de

Voraussetzungen

  • Qt 4 Entwicklerbibliotheken (z.B. die freie und kostenlose LGPL Version, zu beziehen auf http://qt.nokia.com/downloads)
  • Module: QtXml, QtSql, QtNetwork.

Setzen der Fahrzeug-UUIDs

In Datei src/tool/positionsync.cpp, Funktion syncPositions(), Zeilen 90-92:

m_systemsToSync
   << "A87E7EBF-C87B-8795-EC54-F5E64DF6776D"
   << "FE87F6C8-9E6F-56EC-795F-E567D5765D76"
   << "F9E8876D-F07A-08EC-F9A7-0D8A98BAD6D9";

stehen die zu synchronisierenden Fahrzeuge. Als Beispiel drei Fahrzeug-UUIDs eingetragen. Falls keine Leseberechtigung für diese Fahrzeuge existiert, sollten hier UUIDs von Fahrzeugen eingetragen werden, für die Berechtigungen existieren. Die Liste kann beliebig lang sein, es können mehr oder weniger UUIDs eingetragen werden (jeweils mit << "..." wird ein Eintrag angehängt, nicht das Semikolon am Schluß vergessen;).

Übersetzen des Codes

  • entweder: positionsync-demo.pro in die bevorzugte Entwicklungsumgebung laden. Hierfür bietet sich z.B. der von Qt mitgelieferte Qt Creator an. Dort existiert ein Menüpunkt Build/Build All.
  • oder: Eine Shell oder Eingabeaufforderung öffnen und dort folgendes tun:
    1. ins Verzeichnis arteco-positionsync‑demo-1.0 wechseln
    2. qmake
    3. make

Die Anwendung wird nun erstellt als bin/positionsync‑demo oder unter Windows als tmp/positionsync‑demo.exe und kann von dort ausgeführt werden.


Hinweise zur Benutzung

Funktionsweise

Nach dem Einloggen und Anklicken des Buttons "Synchronization" wird eine Verbindung zum OSC3-Webservice aufgebaut. Für die im Code eingetragenen Fahrzeugsysteme werden nun Positionsdaten abgerufen. Die Antwort, ein XML-Dokument, wird geparst und die Datensätze werden in einer lokalen SQLite-Datenbank gespeichert. Sodann wird die nächste Menge an Positionsdaten abgerufen, bis die lokalen Datenbanken für die gegebenen Systeme auf dem aktuellen Stand sind.

HTTP-Anfrage

Die Anfrage, die an den Webservice gestellt wird, baut sich wie folgt auf:

/systems/<uuid>/positions.xml?<parameter>

parameter:

from_created_at: created-at der ersten Position, die geliefert werden soll (format: "yyyy-MM-ddThh:mm:ss")
only:            durch Kommata getrennte Liste der gewünschten Datenbankfelder
sort_field:      ein Feld, nach dem die Antwort sortiert sein soll
sort_order:      Sortierrichtung. asc = aufsteigend, desc = absteigend
limit:           Anzahl der Datensätze, die zurückgeliefert werden sollen
Beispiel: /systems/01234567‑89AB‑CDEF‑FEDC‑BA9876543210/positions.xml?from_created_at=2009‑06‑19T19:37:41&
          only=id,created_at,raw_data&sort_field=created_at&sort_order=asc&limit=500

Datenbankdateien

Die lokalen Datenbanken befinden sich in einem Unterverzeichnis, das in der Datei src/config.h definiert ist:

/** subdirectory for position databases, relative to application directory */
#define DIR_POSITIONS "positions"

Für jedes Fahrzeug wird eine eigene Datenbankdatei angelegt. Sie ist benannt nach dem Namensschema: db_<Fahrzeug‑UUID>.

Jede Datenbank besteht aus einer Tabelle positions mit folgender Struktur:

`id` int(11) PRIMARY KEY NOT NULL,
`world_x` double default NULL,
`world_y` double default NULL,
`timestamp` datetime NULL default NULL,
`created_at` datetime NULL default NULL,
`status` int(11) default NULL,
`raw_data` varchar(255) default NULL,
`user_data` varchar(255) default NULL,
`map_text` varchar(512) default NULL,
`drive_number` int(11) default NULL,
`course` int(11) default NULL,
`speed` int(11) default NULL,
`max_speed` int(11) default NULL,
`distance` double default NULL,
`gsm_quality` int(11) default NULL,
`sat_count` int(11) default NULL,
`private` tinyint(1) default NULL,
`io_01` int(11) default NULL,
`io_02` int(11) default NULL,
`io_03` int(11) default NULL,
`io_04` int(11) default NULL,
`io_05` int(11) default NULL,
`io_06` int(11) default NULL,
`io_07` int(11) default NULL,
`io_08` int(11) default NULL,
`io_09` int(11) default NULL,
`io_10` int(11) default NULL,
`io_11` int(11) default NULL,
`io_12` int(11) default NULL,
`io_13` int(11) default NULL,
`io_14` int(11) default NULL,
`io_15` int(11) default NULL,
`io_16` int(11) default NULL,
`io_17` int(11) default NULL,
`io_18` int(11) default NULL,
`io_19` int(11) default NULL,
`io_20` int(11) default NULL,
`io_21` int(11) default NULL,
`io_22` int(11) default NULL,
`io_23` int(11) default NULL,
`io_24` int(11) default NULL,
`io_25` int(11) default NULL;

Eine Datenbank kann durch einfaches Löschen der jeweiligen Datei gelöscht werden.

PositionSync::getLastTimestamp()

Hier wird bestimmt, ab wann die ersten Positionsdaten abgefragt werden sollen. Falls noch keine Daten in der lokalen Datenbank vorliegen, wird als Default "2000‑01‑01T00:00:00" (yyyyMMddThh:mm:ss) zurückgegeben. Wenn keine Daten aus der Urzeit gebraucht werden, kann der Defaultwert hier geändert werden.

Dieser Wert gilt nur für Fahrzeuge, die zum ersten mal gesynct werden. Sind schon Daten in der Datenbank vorhanden, wird automatisch der letzte Datenbankeintrag als neuer Zeitstempel gewählt.

Muttithreading

Um die Benutzeroberfläche agil zu halten, läuft die Synchronisation in einem eigenen Thread. Wenn der Code angepaßt wird, ist zu beachten, daß Kommunikation zwischen Objekten, die in verschiedenen Threads leben, nur durch (queued) Signals/Slots erfolgen sollte - nicht durch direkte Methodenaufrufe.


Abhängigkeitsbaum

MainWindow  (interagiert mit dem Nutzer)
     `--> SyncThread  (startet neuen Thread und erzeugt PositionSync-Objekt)
                 `--> PositionSync  (steuert Synchronisation and Datenbankeinträge)
                          `.`----> ResourceLoader  (Erstellt Anfragen an den Webservice)
                            `.          `--> HttpXml  (Kommunikation mit Webservice
                              `--> Position  (hält Daten)