PositionSync-Demo: Unterschied zwischen den Versionen
Alex (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „Die PositionSync-Demo ist eine Auskopplung des zum OSC3 gehörenden PositionSync als eigenständige Anwendung. Sie ermöglicht es, Positionsdaten unabhängig vom …“) |
Alex (Diskussion | Beiträge) (Hinweis auf Code per Mail eingefügt) |
||
(2 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
− | Die PositionSync-Demo ist eine Auskopplung des zum OSC3 gehörenden PositionSync als eigenständige Anwendung. Sie ermöglicht es, | + | 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_infos|XML-Schnittstelle]] gedacht. |
== Wie komme ich zu einer lauffähigen Anwendung? == | == Wie komme ich zu einer lauffähigen Anwendung? == | ||
+ | |||
+ | === Quelltext === | ||
+ | Erhältlich per Mail an <tt>ticket@arteco.de</tt> | ||
=== Voraussetzungen === | === Voraussetzungen === | ||
Zeile 13: | Zeile 16: | ||
<code> | <code> | ||
m_systemsToSync | m_systemsToSync | ||
− | << " | + | << "A87E7EBF-C87B-8795-EC54-F5E64DF6776D" |
− | << " | + | << "FE87F6C8-9E6F-56EC-795F-E567D5765D76" |
− | << " | + | << "F9E8876D-F07A-08EC-F9A7-0D8A98BAD6D9"; |
</code> | </code> | ||
− | 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 <code><< "..."</code> wird ein Eintrag angehängt, | + | 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 <code><< "..."</code> wird ein Eintrag angehängt, nicht das Semikolon am Schluß vergessen;). |
=== Übersetzen des Codes === | === Übersetzen des Codes === | ||
− | * entweder: '''positionsync-demo.pro''' in die bevorzugte Entwicklungsumgebung laden. Hierfür bietet sich z.B. der von Qt mitgelieferte | + | * 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: | * oder: Eine Shell oder Eingabeaufforderung öffnen und dort folgendes tun: | ||
*# ''ins Verzeichnis '''arteco-positionsync‑demo-1.0''' wechseln'' | *# ''ins Verzeichnis '''arteco-positionsync‑demo-1.0''' wechseln'' | ||
Zeile 35: | Zeile 38: | ||
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. | 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 === | === Datenbankdateien === | ||
− | Die lokalen Datenbanken | + | Die lokalen Datenbanken befinden sich in einem Unterverzeichnis, das in der Datei <code>src/config.h</code> definiert ist: |
/** subdirectory for position databases, relative to application directory */ | /** subdirectory for position databases, relative to application directory */ | ||
#define DIR_POSITIONS "positions" | #define DIR_POSITIONS "positions" | ||
− | Für jedes Fahrzeug wird eine eigene Datenbankdatei angelegt. Sie | + | Für jedes Fahrzeug wird eine eigene Datenbankdatei angelegt. Sie ist benannt nach dem Namensschema: ''db_<Fahrzeug‑UUID>''. |
+ | |||
+ | Jede Datenbank besteht aus einer Tabelle <code>positions</code> 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. | Eine Datenbank kann durch einfaches Löschen der jeweiligen Datei gelöscht werden. | ||
Zeile 48: | Zeile 109: | ||
=== PositionSync::getLastTimestamp() === | === PositionSync::getLastTimestamp() === | ||
− | Hier wird bestimmt, ab wann die ersten Positionsdaten abgefragt werden sollen | + | Hier wird bestimmt, ab wann die ersten Positionsdaten abgefragt werden sollen. Falls noch keine Daten in der lokalen Datenbank vorliegen, wird als Default <code>"2000‑01‑01T00:00:00"</code> (<code>''yyyy''‑''MM''‑''dd''T''hh'':''mm'':''ss''</code>) 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. | 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. |
Aktuelle Version vom 22. Dezember 2009, 15:39 Uhr
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.
Inhaltsverzeichnis
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:
- ins Verzeichnis arteco-positionsync‑demo-1.0 wechseln
qmake
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"
(yyyy‑MM‑ddThh: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)