From 7eda55e2b042566020ade34d7b2cdb9296f37f1d Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Mon, 4 Mar 2019 19:50:35 -0500 Subject: [PATCH] buildcommands: Use dictionaries to describe commands, responses, and output Avoid transmitting lists of message ids for commands and responses - gzip doesn't do a good job of compressing them. Signed-off-by: Kevin O'Connor --- klippy/msgproto.py | 21 ++++++++++++--------- scripts/buildcommands.py | 28 ++++++++++++++++------------ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/klippy/msgproto.py b/klippy/msgproto.py index 5feb350d..6bb5c159 100644 --- a/klippy/msgproto.py +++ b/klippy/msgproto.py @@ -6,8 +6,8 @@ import json, zlib, logging DefaultMessages = { - 0: "identify_response offset=%u data=%.*s", - 1: "identify offset=%u count=%c", + "identify_response offset=%u data=%.*s": 0, + "identify offset=%u count=%c": 1, } MESSAGE_MIN = 5 @@ -190,7 +190,7 @@ class MessageParser: self.config = {} self.version = self.build_versions = "" self.raw_identify_data = "" - self._init_messages(DefaultMessages, DefaultMessages.keys()) + self._init_messages(DefaultMessages) def check_packet(self, s): if len(s) < MESSAGE_MIN: return 0 @@ -296,10 +296,10 @@ class MessageParser: #traceback.print_exc() raise error("Unable to encode: %s" % (msgname,)) return cmd - def _init_messages(self, messages, parsers): - for msgid, msgformat in messages.items(): + def _init_messages(self, messages, output_ids=[]): + for msgformat, msgid in messages.items(): msgid = int(msgid) - if msgid not in parsers: + if msgid in output_ids: self.messages_by_id[msgid] = OutputFormat(msgid, msgformat) continue msg = MessageFormat(msgid, msgformat) @@ -311,11 +311,14 @@ class MessageParser: data = zlib.decompress(data) self.raw_identify_data = data data = json.loads(data) - messages = data.get('messages') commands = data.get('commands') - self.command_ids = commands responses = data.get('responses') - self._init_messages(messages, commands+responses) + output = data.get('output', {}) + all_messages = dict(commands) + all_messages.update(responses) + all_messages.update(output) + self.command_ids = sorted(commands.values()) + self._init_messages(all_messages, output.values()) static_strings = data.get('static_strings', {}) self.static_strings = {int(k): v for k, v in static_strings.items()} self.config.update(data.get('config', {})) diff --git a/scripts/buildcommands.py b/scripts/buildcommands.py index 2b892366..1c3448fe 100644 --- a/scripts/buildcommands.py +++ b/scripts/buildcommands.py @@ -131,7 +131,7 @@ class HandleCommandGeneration: def __init__(self): self.commands = {} self.encoders = [] - self.msg_to_id = { m: i for i, m in msgproto.DefaultMessages.items() } + self.msg_to_id = dict(msgproto.DefaultMessages) self.messages_by_name = { m.split()[0]: m for m in self.msg_to_id } self.all_param_types = {} self.ctr_dispatch = { @@ -172,16 +172,20 @@ class HandleCommandGeneration: # The mcu currently assumes all message ids encode to one byte error("Too many message ids") def update_data_dictionary(self, data): - messages = { msgid: msg for msg, msgid in self.msg_to_id.items() } - data['messages'] = messages - commands = [self.msg_to_id[msg] - for msgname, msg in self.messages_by_name.items() - if msgname in self.commands] - data['commands'] = sorted(commands) - responses = [self.msg_to_id[msg] - for msgname, msg in self.messages_by_name.items() - if msgname not in self.commands] - data['responses'] = sorted(responses) + command_ids = [self.msg_to_id[msg] + for msgname, msg in self.messages_by_name.items() + if msgname in self.commands] + response_ids = [self.msg_to_id[msg] + for msgname, msg in self.messages_by_name.items() + if msgname not in self.commands] + data['commands'] = { msg: msgid for msg, msgid in self.msg_to_id.items() + if msgid in command_ids } + data['responses'] = {msg: msgid for msg, msgid in self.msg_to_id.items() + if msgid in response_ids } + output = { msg: msgid for msg, msgid in self.msg_to_id.items() + if msgid not in command_ids and msgid not in response_ids } + if output: + data['output'] = output def build_parser(self, parser, iscmd): if parser.name == "#output": comment = "Output: " + parser.msgformat @@ -412,7 +416,7 @@ class HandleIdentify: data = {} for h in Handlers: h.update_data_dictionary(data) - datadict = json.dumps(data, separators=(',', ':')) + datadict = json.dumps(data, separators=(',', ':'), sort_keys=True) # Write data dictionary if options.write_dictionary: