mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-25 06:15:43 +08:00
[python] refactor messages
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
"""
|
||||
Paparazzi message representation
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
import json
|
||||
import messages_xml_map
|
||||
|
||||
|
||||
class PprzMessageError(Exception):
|
||||
def __init__(self, message, inner_exception=None):
|
||||
self.message = message
|
||||
self.inner_exception = inner_exception
|
||||
self.exception_info = sys.exc_info()
|
||||
def __str__(self):
|
||||
return self.message
|
||||
|
||||
|
||||
class PprzMessage(object):
|
||||
"""base Paparazzi message class"""
|
||||
def __init__(self, class_name, name):
|
||||
self._class_name = class_name
|
||||
self._name = name
|
||||
self._id = messages_xml_map.get_msg_id(class_name, name)
|
||||
self._fieldnames = messages_xml_map.get_msg_fields(class_name, name)
|
||||
self._fieldvalues = []
|
||||
|
||||
def get_fieldnames(self):
|
||||
return self._fieldnames
|
||||
|
||||
def get_fieldvalues(self):
|
||||
return self._fieldvalues
|
||||
|
||||
def get_field(self, idx):
|
||||
return self._fieldvalues[idx]
|
||||
|
||||
def set_values(self, values):
|
||||
if len(values) == len(self._fieldnames):
|
||||
self._fieldvalues = values
|
||||
else:
|
||||
raise PprzMessageError("Error: fields not matching")
|
||||
|
||||
def __str__(self):
|
||||
ret = '%s.%s {' % (self._class_name, self._name)
|
||||
for idx, f in enumerate(self._fieldnames):
|
||||
ret += '%s : %s, ' % (f, self._fieldvalues[idx])
|
||||
ret = ret[0:-2] + '}'
|
||||
return ret
|
||||
|
||||
def to_dict(self, payload_only=False):
|
||||
d = {}
|
||||
if not payload_only:
|
||||
d['msgname'] = self._name
|
||||
d['msgclass'] = self._class_name
|
||||
for idx, f in enumerate(self._fieldnames):
|
||||
d[f] = self._fieldvalues[idx]
|
||||
return d
|
||||
|
||||
def to_json(self, payload_only=False):
|
||||
return json.dumps(self.to_dict(payload_only))
|
||||
Executable
+102
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import absolute_import, print_function
|
||||
|
||||
import os
|
||||
|
||||
# if PAPARAZZI_HOME not set, then assume the tree containing this
|
||||
# file is a reasonable substitute
|
||||
PPRZ_HOME = os.getenv("PAPARAZZI_HOME", os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
'../../../..')))
|
||||
|
||||
default_messages_file = '%s/conf/messages.xml' % PPRZ_HOME
|
||||
|
||||
message_dictionary = {}
|
||||
message_dictionary_types = {}
|
||||
message_dictionary_id_name = {}
|
||||
message_dictionary_name_id = {}
|
||||
|
||||
|
||||
class MessagesNotFound(Exception):
|
||||
def __init__(self, filename):
|
||||
self.filename = filename
|
||||
|
||||
def __str__(self):
|
||||
return "messages file " + repr(self.filename) + " not found"
|
||||
|
||||
|
||||
def parse_messages(messages_file=default_messages_file):
|
||||
if not os.path.isfile(messages_file):
|
||||
raise MessagesNotFound(messages_file)
|
||||
from lxml import etree
|
||||
tree = etree.parse(messages_file)
|
||||
for the_class in tree.xpath("//msg_class[@name]"):
|
||||
class_name = the_class.attrib['name']
|
||||
if class_name not in message_dictionary:
|
||||
message_dictionary_id_name[class_name] = {}
|
||||
message_dictionary_name_id[class_name] = {}
|
||||
message_dictionary[class_name] = {}
|
||||
message_dictionary_types[class_name] = {}
|
||||
for the_message in the_class.xpath("message[@name]"):
|
||||
message_name = the_message.attrib['name']
|
||||
if 'id' in the_message.attrib:
|
||||
message_id = the_message.attrib['id']
|
||||
else:
|
||||
message_id = the_message.attrib['ID']
|
||||
if message_id[0:2] == "0x":
|
||||
message_id = int(message_id, 16)
|
||||
else:
|
||||
message_id = int(message_id)
|
||||
|
||||
message_dictionary_id_name[class_name][message_id] = message_name
|
||||
message_dictionary_name_id[class_name][message_name] = message_id
|
||||
|
||||
# insert this message into our dictionary as a list with room for the fields
|
||||
message_dictionary[class_name][message_name] = []
|
||||
message_dictionary_types[class_name][message_id] = []
|
||||
|
||||
for the_field in the_message.xpath('field[@name]'):
|
||||
# for now, just save the field names -- in the future maybe expand this to save a struct?
|
||||
message_dictionary[class_name][message_name].append(the_field.attrib['name'])
|
||||
message_dictionary_types[class_name][message_id].append(the_field.attrib['type'])
|
||||
|
||||
|
||||
def get_msg_fields(msg_class, msg_name):
|
||||
if not message_dictionary:
|
||||
parse_messages()
|
||||
if msg_class in message_dictionary:
|
||||
if msg_name in message_dictionary[msg_class]:
|
||||
return message_dictionary[msg_class][msg_name]
|
||||
else:
|
||||
print("Error: msg_name %s not found in msg_class %s." % (msg_name, msg_class))
|
||||
else:
|
||||
print("Error: msg_class %s not found." % msg_class)
|
||||
return []
|
||||
|
||||
|
||||
def get_msg_id(msg_class, msg_name):
|
||||
if not message_dictionary:
|
||||
parse_messages()
|
||||
try:
|
||||
return message_dictionary_name_id[msg_class][msg_name]
|
||||
except KeyError:
|
||||
print("Error: msg_name %s not found in msg_class %s." % (msg_name, msg_class))
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
def test():
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-f", "--file", help="path to messages.xml file", default=default_messages_file)
|
||||
parser.add_argument("-l", "--list", help="list parsed messages", action="store_true", dest="list_messages")
|
||||
parser.add_argument("-c", "--class", help="message class", dest="msg_class", default="telemetry")
|
||||
args = parser.parse_args()
|
||||
parse_messages(args.file)
|
||||
if args.list_messages:
|
||||
print("Listing %i messages in '%s' msg_class" % (len(message_dictionary[args.msg_class]), args.msg_class))
|
||||
for msg in message_dictionary[args.msg_class]:
|
||||
print(msg)
|
||||
|
||||
if __name__ == '__main__':
|
||||
test()
|
||||
Reference in New Issue
Block a user