From 63db906e7302e65e7afbaadf31b04f36e357526f Mon Sep 17 00:00:00 2001 From: Swann Perarnau Date: Mon, 11 Dec 2017 15:48:08 -0600 Subject: [PATCH] [refactor] Improve power message format This commit changes the message format for the upstream API, to use a json-encoded dictionary. While the format is not set in stone at this point, the goal is to slowly move into a proper protocol, with well-defined fields to the messages, and proper mechanisms to send commands and receive notification of their completion. The only current user of this API is the power management piece, and this change breaks the GRM code maintained outside of this repo. We will need to reconcile the two implementation once the message protocol gets more stable. Related to #1 and #6. --- bin/cmd | 25 ++++++++++++++++--------- nrm/daemon.py | 21 +++++++++++++++------ 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/bin/cmd b/bin/cmd index 6ee3ba7..464e12c 100755 --- a/bin/cmd +++ b/bin/cmd @@ -57,17 +57,24 @@ class CommandLineInterface(object): The NRM should answer on the pub socket with an acknowledgment.""" - command = "34.56 %g" % argv.level - self.upstream_pub_socket.send_string(command) + # build the command as a JSON dict giving enough info. This is an + # idempotent command, so we will repeat the command if we don't get a + # timely answer. + # TODO: check that the level makes a little bit of sense in the first + # place + command = {'command': 'setpower', + 'limit': argv.limit, + } - # now wait for an answer while(True): - msg = self.upstream_sub_socket.recv_string() + self.upstream_pub_socket.send_json(command) + msg = self.upstream_sub_socket.recv_json() self.logger.info("new message: %r", msg) - fields = msg.split() - if fields[0] == "23.45": - self.logger.info("new power: %g", float(fields[1])) - break + # ignore other messages + if isinstance(msg, dict) and msg.get('type') == 'power': + if msg['limit'] == argv.limit: + self.logger.info("command received by the daemon") + break def main(self): parser = argparse.ArgumentParser() @@ -86,7 +93,7 @@ class CommandLineInterface(object): parser_setpower.add_argument("-f", "--follow", help="listen for power changes", action='store_true') - parser_setpower.add_argument("level", + parser_setpower.add_argument("limit", help="set new power limit", type=float) parser_setpower.set_defaults(func=self.do_setpower) diff --git a/nrm/daemon.py b/nrm/daemon.py index f5aa894..402e8de 100644 --- a/nrm/daemon.py +++ b/nrm/daemon.py @@ -1,5 +1,6 @@ from __future__ import print_function +import json import logging import re import signal @@ -97,16 +98,24 @@ class Daemon(object): def do_upstream_receive(self, parts): self.logger.info("receiving upstream message: %r", parts) - self.target = int(parts[0].split()[1]) - self.logger.info("target measure: %g", self.target) + if len(parts) != 1: + self.logger.error("unexpected msg length, droping it: %r", parts) + return + msg = json.loads(parts[0]) + if isinstance(msg, dict) and msg.get('command') == 'setpower': + self.target = float(msg['limit']) + self.logger.info("new target measure: %g", self.target) def do_sensor(self): self.machine_info = self.sensor.do_update() self.logger.info("current state: %r", self.machine_info) total_power = self.machine_info['energy']['power']['total'] - msg = "23.45 %g" % (total_power) - self.upstream_pub.send_string(msg) - self.logger.info("Sending power values: %r", msg) + msg = {'type': 'power', + 'total': total_power, + 'limit': self.target + } + self.upstream_pub.send_json(msg) + self.logger.info("sending sensor message: %r", msg) def do_control(self): total_power = self.machine_info['energy']['power']['total'] @@ -154,7 +163,7 @@ class Daemon(object): downstream_socket.bind(downstream_bind_param) upstream_pub_socket.bind(upstream_pub_param) upstream_sub_socket.connect(upstream_sub_param) - upstream_sub_filter = "34.56 " + upstream_sub_filter = "" upstream_sub_socket.setsockopt(zmq.SUBSCRIBE, upstream_sub_filter) self.logger.info("downstream socket bound to: %s", -- 2.26.2