1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-14 03:49:52 +03:00
opentx/radio/util/crossfire-parse.py
Bertrand Songis 53b51cac94 Bsongis/crossfire refactoring (#3613)
* Crossfire refactoring

* Crossfire script now displaying fields

* Crossfire script now displaying text selection values
2016-06-18 22:16:50 +02:00

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)