Commit e9848601 authored by Swann Perarnau's avatar Swann Perarnau
Browse files

Merge branch 'power-cli' into 'master'

Basic implementation of the command line interface, power API improvements

See merge request !2
parents 15437f00 63db906e
#!/usr/bin/env python2
from __future__ import print_function
import argparse
import logging
import uuid
import signal
import zmq
class CommandLineInterface(object):
"""Implements a command line interface to the NRM."""
def __init__(self):
self.logger = logging.getLogger(__name__)
def do_signal(self):
def setup(self):
# SUB port to the upstream API (connected to its PUB port)
upstream_sub_port = 2345
# PUB port to the upstream API (connected to its SUB port)
upstream_pub_port = 3456
self.context = zmq.Context()
self.upstream_pub_socket = self.context.socket(zmq.PUB)
self.upstream_sub_socket = self.context.socket(zmq.SUB)
upstream_pub_param = "tcp://*:%d" % (upstream_pub_port)
upstream_sub_param = "tcp://localhost:%d" % (upstream_sub_port)
# we want to receive everything for now
upstream_sub_filter = ""
self.upstream_sub_socket.setsockopt(zmq.SUBSCRIBE, upstream_sub_filter)"upstream pub socket bound to: %s",
upstream_pub_param)"upstream sub socket connected to: %s",
# take care of signals
signal.signal(signal.SIGINT, self.do_signal)
# create a uuid for this client instance
self.uuid = str(uuid.uuid4())"client uuid: %r", self.uuid)
def do_run(self, argv):
def do_setpower(self, argv):
""" Connect to the NRM and ask to change the power limit.
The NRM should answer on the pub socket with an acknowledgment."""
# 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,
msg = self.upstream_sub_socket.recv_json()"new message: %r", msg)
# ignore other messages
if isinstance(msg, dict) and msg.get('type') == 'power':
if msg['limit'] == argv.limit:"command received by the daemon")
def main(self):
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbose",
help="verbose logging information",
subparsers = parser.add_subparsers()
# run container
parser_run = subparsers.add_parser("run")
# setpowerlimit
parser_setpower = subparsers.add_parser("setpower")
parser_setpower.add_argument("-f", "--follow",
help="listen for power changes",
help="set new power limit",
args = parser.parse_args()
if args.verbose:
if __name__ == "__main__":
cli = CommandLineInterface()
from __future__ import print_function from __future__ import print_function
import json
import logging import logging
import re import re
import signal import signal
...@@ -95,18 +96,26 @@ class Daemon(object): ...@@ -95,18 +96,26 @@ class Daemon(object):"application now in state: %s","application now in state: %s",
application.state) application.state)
def do_upstream_receive(self, msg): def do_upstream_receive(self, parts):"receiving upstream message: %r", msg)"receiving upstream message: %r", parts) = int(msg.split()[1]) if len(parts) != 1:"target measure: %g", self.logger.error("unexpected msg length, droping it: %r", parts)
msg = json.loads(parts[0])
if isinstance(msg, dict) and msg.get('command') == 'setpower': = float(msg['limit'])"new target measure: %g",
def do_sensor(self): def do_sensor(self):
self.machine_info = self.sensor.do_update() self.machine_info = self.sensor.do_update()"current state: %r", self.machine_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,"Sending power values: %r", msg) 'limit':
self.upstream_pub.send_json(msg)"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)"downstream socket bound to: %s","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