mirror of
https://github.com/opentx/opentx.git
synced 2025-07-14 03:49:52 +03:00
* Crossfire refactoring * Crossfire script now displaying fields * Crossfire script now displaying text selection values
151 lines
4 KiB
Python
151 lines
4 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# This program parses sport.log files
|
|
|
|
from __future__ import division, print_function
|
|
|
|
import sys
|
|
|
|
lineNumber = 0
|
|
crossfireDataBuff = []
|
|
|
|
crossfire_types = [
|
|
"UINT8",
|
|
"INT8",
|
|
"UINT16",
|
|
"INT16",
|
|
"UINT32",
|
|
"INT32",
|
|
"UINT64",
|
|
"INT64",
|
|
"FLOAT",
|
|
"TEXT_SELECTION",
|
|
"STRING",
|
|
"FOLDER"
|
|
]
|
|
|
|
def dump(data, maxLen=None):
|
|
if maxLen and len(data) > maxLen:
|
|
data = data[:maxLen]
|
|
return " ".join("{:02x}".format(c) for c in data)
|
|
|
|
def CheckCrc(packet):
|
|
return True
|
|
|
|
def ParseGPS(payload):
|
|
pass
|
|
|
|
def ParseBattery(payload):
|
|
voltage = float((payload[0] << 8) + payload[1]) / 10
|
|
current = float((payload[2] << 8) + payload[3]) / 10
|
|
consumption = (payload[4] << 16) + (payload[5] << 8) + payload[6]
|
|
return "[Battery] %.1fV %.1fA %dmAh" % (voltage, current, consumption)
|
|
|
|
def ParseLinkStatistics(payload):
|
|
return "[Link Statistics] "
|
|
|
|
def ParseAttitude(payload):
|
|
pitch = float((payload[0] << 8) + payload[1]) / 1000
|
|
roll = float((payload[2] << 8) + payload[3]) / 1000
|
|
yaw = float((payload[4] << 8) + payload[5]) / 1000
|
|
return "[Attitude] pitch=%.3f roll=%.3f yaw=%.3f" % (pitch, roll, yaw)
|
|
|
|
def ParseFlightMode(payload):
|
|
return '[Flight Mode] "%s"' % "".join([chr(c) for c in payload[:-1]])
|
|
|
|
def ParsePingDevices(_):
|
|
return '[Ping Devices]'
|
|
|
|
def ParseDevice(payload):
|
|
return '[Device] 0x%02x "%s" %d parameters' % (payload[1], "".join([chr(c) for c in payload[2:-14]]), payload[-1])
|
|
|
|
def ParseFieldsRequest(payload):
|
|
return '[Fields request]'
|
|
|
|
def ParseFieldRequest(payload):
|
|
return '[Field request] device=0x%02x field=%d' % (payload[1], payload[2])
|
|
|
|
def ParseField(payload):
|
|
name = ""
|
|
i = 5
|
|
while payload[i] != 0:
|
|
name += chr(payload[i])
|
|
i += 1
|
|
i += 1
|
|
return '[Field] %s device=0x%02x field=%d parent=%d type=%s' % (name, payload[1], payload[2], payload[3], crossfire_types[payload[4]])
|
|
|
|
parsers = (
|
|
(0x02, ParseGPS),
|
|
(0x08, ParseBattery),
|
|
(0x14, ParseLinkStatistics),
|
|
(0x1E, ParseAttitude),
|
|
(0x21, ParseFlightMode),
|
|
(0x28, ParsePingDevices),
|
|
(0x29, ParseDevice),
|
|
(0x2a, ParseFieldsRequest),
|
|
(0x2b, ParseField),
|
|
(0x2c, ParseFieldRequest),
|
|
)
|
|
|
|
def ParsePacket(packet):
|
|
len = packet[1]
|
|
command = packet[2]
|
|
payload = packet[3:-1]
|
|
crc = packet[-1]
|
|
for id, parser in parsers:
|
|
if id == command:
|
|
print("(%d)" % lineNumber, dump(packet), parser(payload))
|
|
return
|
|
print("(%d)" % lineNumber, dump(packet))
|
|
|
|
def ParseData(data):
|
|
global crossfireDataBuff
|
|
# convert from hex
|
|
parts = data.split(' ')
|
|
binData = [int(hex, 16) for hex in parts]
|
|
# print binData
|
|
crossfireDataBuff += binData
|
|
# process whole packets
|
|
while len(crossfireDataBuff) > 4:
|
|
if crossfireDataBuff[0] != 0x00 and crossfireDataBuff[0] != 0xee and crossfireDataBuff[0] != 0xea:
|
|
print("Skipped 1 byte", dump(crossfireDataBuff[:1]))
|
|
crossfireDataBuff = crossfireDataBuff[1:]
|
|
continue
|
|
length = crossfireDataBuff[1]
|
|
if length < 2 or length > 0x32:
|
|
print("Skipped 2 bytes", dump(crossfireDataBuff[:2]))
|
|
crossfireDataBuff = crossfireDataBuff[2:]
|
|
continue
|
|
if len(crossfireDataBuff) < length+2:
|
|
break
|
|
ParsePacket(crossfireDataBuff[:length+2])
|
|
crossfireDataBuff = crossfireDataBuff[length+2:]
|
|
|
|
inputFile = None
|
|
|
|
if len(sys.argv) > 1:
|
|
inputFile = sys.argv[1]
|
|
|
|
# open input
|
|
if inputFile:
|
|
inp = open(inputFile, 'r')
|
|
else:
|
|
inp = sys.stdin
|
|
|
|
while True:
|
|
line = inp.readline()
|
|
lineNumber += 1
|
|
if len(line) == 0:
|
|
break
|
|
line = line.strip('\r\n')
|
|
if len(line) == 0:
|
|
continue
|
|
# print line
|
|
parts = line.split(': ')
|
|
if len(parts) < 2:
|
|
print("weird data: \"%s\" at line %d" % (line, lineNumber))
|
|
continue
|
|
crossfireData = parts[1].strip()
|
|
# print "sd: %s" % sportData
|
|
ParseData(crossfireData)
|