Commit 63db906e authored by Swann Perarnau's avatar Swann Perarnau

[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.
parent bc1b7fd2
...@@ -57,17 +57,24 @@ class CommandLineInterface(object): ...@@ -57,17 +57,24 @@ class CommandLineInterface(object):
The NRM should answer on the pub socket with an acknowledgment.""" The NRM should answer on the pub socket with an acknowledgment."""
command = "34.56 %g" % argv.level # build the command as a JSON dict giving enough info. This is an
self.upstream_pub_socket.send_string(command) # 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): 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) self.logger.info("new message: %r", msg)
fields = msg.split() # ignore other messages
if fields[0] == "23.45": if isinstance(msg, dict) and msg.get('type') == 'power':
self.logger.info("new power: %g", float(fields[1])) if msg['limit'] == argv.limit:
break self.logger.info("command received by the daemon")
break
def main(self): def main(self):
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
...@@ -86,7 +93,7 @@ class CommandLineInterface(object): ...@@ -86,7 +93,7 @@ class CommandLineInterface(object):
parser_setpower.add_argument("-f", "--follow", parser_setpower.add_argument("-f", "--follow",
help="listen for power changes", help="listen for power changes",
action='store_true') action='store_true')
parser_setpower.add_argument("level", parser_setpower.add_argument("limit",
help="set new power limit", help="set new power limit",
type=float) type=float)
parser_setpower.set_defaults(func=self.do_setpower) parser_setpower.set_defaults(func=self.do_setpower)
......
from __future__ import print_function from __future__ import print_function
import json
import logging import logging
import re import re
import signal import signal
...@@ -97,16 +98,24 @@ class Daemon(object): ...@@ -97,16 +98,24 @@ class Daemon(object):
def do_upstream_receive(self, parts): def do_upstream_receive(self, parts):
self.logger.info("receiving upstream message: %r", parts) self.logger.info("receiving upstream message: %r", parts)
self.target = int(parts[0].split()[1]) if len(parts) != 1:
self.logger.info("target measure: %g", self.target) 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): def do_sensor(self):
self.machine_info = self.sensor.do_update() self.machine_info = self.sensor.do_update()
self.logger.info("current state: %r", self.machine_info) self.logger.info("current state: %r", self.machine_info)
total_power = self.machine_info['energy']['power']['total'] total_power = self.machine_info['energy']['power']['total']
msg = "23.45 %g" % (total_power) msg = {'type': 'power',
self.upstream_pub.send_string(msg) 'total': total_power,
self.logger.info("Sending power values: %r", msg) 'limit': self.target
}
self.upstream_pub.send_json(msg)
self.logger.info("sending sensor message: %r", msg)
def do_control(self): def do_control(self):
total_power = self.machine_info['energy']['power']['total'] total_power = self.machine_info['energy']['power']['total']
...@@ -154,7 +163,7 @@ class Daemon(object): ...@@ -154,7 +163,7 @@ class Daemon(object):
downstream_socket.bind(downstream_bind_param) downstream_socket.bind(downstream_bind_param)
upstream_pub_socket.bind(upstream_pub_param) upstream_pub_socket.bind(upstream_pub_param)
upstream_sub_socket.connect(upstream_sub_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) upstream_sub_socket.setsockopt(zmq.SUBSCRIBE, upstream_sub_filter)
self.logger.info("downstream socket bound to: %s", self.logger.info("downstream socket bound to: %s",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment