Python Server für ZusiDisplay
Moderator: Jens Haupert
Python Server für ZusiDisplay
Liebe Community,
erstmal vielen Dank für die Aufnahme!
Zu meinem Anliegen:
Ich würde gern ZusiDisplay mit einem Python-Skript ansteuern, d.h. ich möchte Daten wie z.B. die aktuelle Uhrzeit und Geschwindigkeit per TCP an ZusiDisplay senden. Allerdings habe ich nicht so ganz verstanden wie die Daten aufgebaut sein müssen, damit ZusiDisplay sie versteht.
Kann mir da jemand konkret helfen?
Grüße
Sven
erstmal vielen Dank für die Aufnahme!
Zu meinem Anliegen:
Ich würde gern ZusiDisplay mit einem Python-Skript ansteuern, d.h. ich möchte Daten wie z.B. die aktuelle Uhrzeit und Geschwindigkeit per TCP an ZusiDisplay senden. Allerdings habe ich nicht so ganz verstanden wie die Daten aufgebaut sein müssen, damit ZusiDisplay sie versteht.
Kann mir da jemand konkret helfen?
Grüße
Sven
- Jens Haupert
- Beiträge: 4920
- Registriert: 23.03.2004 14:44:34
- Aktuelle Projekte: http://www.zusidisplay.de
- Wohnort: Berlin
- Kontaktdaten:
Re: Python Server für ZusiDisplay
Hallo Sven,
im Zusi3-Handbuch im Kapitel 11.3 (ab Seite 652) wird das genutzte Protokoll beschrieben.
Viele Grüße
Jens
im Zusi3-Handbuch im Kapitel 11.3 (ab Seite 652) wird das genutzte Protokoll beschrieben.
Viele Grüße
Jens
-
- Beiträge: 287
- Registriert: 01.06.2015 14:11:25
- Aktuelle Projekte: http://www.zusidatenbank.de/
- Wohnort: BW Schöneweide
Re: Python Server für ZusiDisplay
Das Datenformat ist kein Geheimnis. Die Zusi 3 Dokumentation beschreibt das TCP-Protokoll und hat detaillierte Beispiele. Darüber hinaus können Sie mit dem Programm "TCPDemoOutput" genau die Daten sehen, die Zusi überträgt.
Allerdings, ist das Datum und die Zeit ein bisschen komisch. Ich berechne es auf C++ so:
Leider ist die Arbeit mit binären Protokollen nicht so einfach in Python wie in C/C++.
Allerdings, ist das Datum und die Zeit ein bisschen komisch. Ich berechne es auf C++ so:
Code: Alles auswählen
//Digital Time
time_t epoch = time(NULL);
struct tm buf;
localtime_s(&buf, &epoch);
data = new zusi::FloatFsDataItem(zusi::Fs_UhrzeitDigital(0x23), (buf.tm_hour * 3600 + buf.tm_min * 60 + buf.tm_sec) * (1.0f / 86400));
//Date
int daysSinceEpoch = static_cast<int>((epoch / (60 * 60 * 24)) + 25569);
data = new zusi::FloatFsDataItem(zusi::Fs_Datum(0x4B), static_cast<float>(daysSinceEpoch));
Zuletzt geändert von jonathanp am 14.05.2017 20:27:28, insgesamt 1-mal geändert.
Autor - Zusi 3 C++ Client, zusidatenbank.de - Das Zusi3 Addon-Datenbank
Re: Python Server für ZusiDisplay
Hallo Jens,
ich habe leider nur Zusidisplay und den TCP-Server zur Hand, da ich das ganze mit dem Trainsimulator verarbeiten möchte.
Viele Grüße
Sven
ich habe leider nur Zusidisplay und den TCP-Server zur Hand, da ich das ganze mit dem Trainsimulator verarbeiten möchte.
Viele Grüße
Sven
Re: Python Server für ZusiDisplay
Hi Jens,
ich hab mich mal durch die TCP Doku von Zusi2 durchgewühlt und habe den Aufbau der Daten gefunden.
Vielen Dank für den Hinweis!
ich hab mich mal durch die TCP Doku von Zusi2 durchgewühlt und habe den Aufbau der Daten gefunden.
Vielen Dank für den Hinweis!
Re: Python Server für ZusiDisplay
Im Grundsatz findest du in den verschiedenen Zweigen von https://github.com/FSchn/ZusiTCP.NET/tr ... asterTest1" target="_blank auch Zusi-TCP-Master (für .Net), die du vielleicht auf deine Programmiersprache übertragen könntest. (Oder gibt es vielleicht sogar etwas, mit dem man .Net aus Python nutzen kann?)
Einen ähnlichen Fall gab es auch schon mal hier: https://forum.zusi.de/viewtopic.php?f=53&t=12087" target="_blank Der dürfte aber keine so ideale Vorgehensweise sein, wenn es auch anderst geht.
Einen ähnlichen Fall gab es auch schon mal hier: https://forum.zusi.de/viewtopic.php?f=53&t=12087" target="_blank Der dürfte aber keine so ideale Vorgehensweise sein, wenn es auch anderst geht.
Zuletzt geändert von F. Schn. am 17.05.2017 17:49:16, insgesamt 1-mal geändert.
Diese Signatur möchte folgendes bekannter machen: ZusiWiki · ZusiSK: Streckenprojekte · YouTube: Objektbau für Zusi · euirc: Zusi-Chat
Re: Python Server für ZusiDisplay
Für Zusi 2 habe ich vor vielen Jahren Server und Client in Python entwickelt, deren Architektur in groben Zügen hier nachzulesen ist. Leider hat man für das Datenformat von Zusi 3 statt auf eine etablierte Serialisierungsmethode auf eine Eigenentwicklung gesetzt, die noch dazu aufgrund des Verzichts auf ein herkömmliches Längenpräfix etwas mühsam zu parsen ist. Insbesondere für Zusi 3 kann ich daher die Bibliothek construct empfehlen, die einen deklarativen Parser für Binärdaten implementiert. Streng der Nomenklatur in Kapitel 11.3.1 des Handbuchs folgend, lässt sich das Grundgerüst des Protokolls etwa folgendermaßen beschreiben:
Eine praktische Anwendung auf den exemplarischen HELLO-Befehl aus Kapitel 11.3.4:
Die Ausgabe:
Container und ListContainer sind Unterklassen von dict beziehungsweise list und können daher nach allen Regeln der Kunst auseinandergenommen werden.
Ausgehend von diesem sehr einfachen Beispiel sind einige Erweiterungen denkbar:
Code: Alles auswählen
attribute = Struct(
'PACKET_LENGTH' / Int32ul,
'ID' / Int16ul,
'DATA' / Bytes(this.PACKET_LENGTH - 2),
)
node = Struct(
'PACKET_LENGTH' / Int32ul, Check(this.PACKET_LENGTH == 0),
'ID' / Int16ul,
'ATTRIBUTES' / GreedyRange(attribute),
'NODES' / GreedyRange(LazyBound(lambda ctx: node)),
'END' / Const(b'\xFF\xFF\xFF\xFF'),
)
Code: Alles auswählen
HELLO = """
00 00 00 00
01 00
00 00 00 00
01 00
04 00 00 00
01 00
02 00
04 00 00 00
02 00
02 00
0A 00 00 00
03 00
46 61 68 72 70 75 6C 74
05 00 00 00
04 00
32 2E 30
FF FF FF FF
FF FF FF FF
"""
def a2b(hexstr):
return binascii.a2b_hex(''.join(hexstr.split()))
print(node.parse(a2b(HELLO))))
Code: Alles auswählen
Container:
PACKET_LENGTH = 0
ID = 1
ATTRIBUTES = ListContainer:
NODES = ListContainer:
Container:
PACKET_LENGTH = 0
ID = 1
ATTRIBUTES = ListContainer:
Container:
PACKET_LENGTH = 4
ID = 1
DATA = \x02\x00 (total 2)
Container:
PACKET_LENGTH = 4
ID = 2
DATA = \x02\x00 (total 2)
Container:
PACKET_LENGTH = 10
ID = 3
DATA = Fahrpult (total 8)
Container:
PACKET_LENGTH = 5
ID = 4
DATA = 2.0 (total 3)
NODES = ListContainer:
END = \xff\xff\xff\xff (total 4)
END = \xff\xff\xff\xff (total 4)
Ausgehend von diesem sehr einfachen Beispiel sind einige Erweiterungen denkbar:
- Natürlich gibt es bei der Definition des Datenformats noch Verbesserungspotential. Das beginnt bei der überflüssigen Namensvergabe für den konstanten String '\xFF\xFF\xFF\xFF' und geht bis zur Abbildung der strukturell nicht unähnlichen Attribute und Knoten in einem einzigen Konstrukt mittels IfThenElse.
- Mit Hilfe eines Adapters kann das Ergebnis von node.parse in eine noch pythoneskere Datenstruktur oder sogar eine völlig eigene Objekthierarchie konvertiert werden.
- GreedyRange(node).parse_stream liest so viele komplette Knoten wie möglich aus dem übergebenen Datenstrom ein und kann so perfekt mit Datenblöcken unbekannter Länge umgehen, wie sie typischerweise beim Lesen von Sockets vorkommen.
- Das deklarativ definierte Datenformat eignet sich nicht nur zum Deserialisieren sondern auch zum Serialisieren von Befehlen. Aus einer abstrakten Datenstruktur kann durch Aufruf von node.build ohne zusätzlichen Code die entsprechende Binärrepräsentation generiert und danach auf die Reise geschickt werden.
- Noch völlig außer Acht gelassen wurde die korrekte Interpretation der Attribut-Nutzdaten, die bis dato nur als scheinbar bedeutungslose Folgen von Bytes verarbeitet werden. Eine Nachrichten-Typhierarchie, deren Klassen die detaillierten Informationen der Kapitel 11.3.2 und 11.3.3 kapseln, ist die übliche Herangehensweise, aber eine sinnvolle Lösung dieses Problems sollte vom konkreten Anwendungsfall abhängen.
- Michael Skupin
- Beiträge: 196
- Registriert: 01.09.2015 23:35:28
- Aktuelle Projekte: Team Süd Strecke Augsburg - Donauwörth
- Wohnort: Schmiechen
Re: Python Server für ZusiDisplay
Hallo Bernhard,
genau danach habe ich auch gesucht, danke für den Tip.
Michael
genau danach habe ich auch gesucht, danke für den Tip.
Michael
Alles Wissenwertes und Info´s gibt es auf unserm Blog:
http://www.zusi-team-sued.de
Unsere original Strecken( Bau )Objekte:
https://gallerie.zusi-team-sued.de/index.php
Das Team freut sich auf euren Besuch
http://www.zusi-team-sued.de
Unsere original Strecken( Bau )Objekte:
https://gallerie.zusi-team-sued.de/index.php
Das Team freut sich auf euren Besuch