master/gui: track last parameter changes

This commit is contained in:
Sebastien Bourdeauducq 2015-01-02 15:28:45 +08:00
parent 15b27a1d14
commit 3befafc4e0
5 changed files with 89 additions and 22 deletions

View File

@ -1,9 +1,10 @@
import asyncio
from operator import itemgetter
import time
from gi.repository import Gtk
from artiq.gui.tools import Window
from artiq.gui.tools import Window, ListSyncer
from artiq.management.sync_struct import Subscriber
@ -41,11 +42,25 @@ class _ParameterStoreSyncer:
del self.parameters_store[self._find_index(key)]
class _LastChangesStoreSyncer(ListSyncer):
def convert(self, x):
if len(x) == 3:
timestamp, name, value = x
else:
timestamp, name = x
value = "<deleted>"
return [time.strftime("%m/%d %H:%M:%S", time.localtime(timestamp)),
name, str(value)]
class ParametersWindow(Window):
def __init__(self):
Window.__init__(self, title="Parameters")
self.set_default_size(500, 500)
notebook = Gtk.Notebook()
self.add(notebook)
self.parameters_store = Gtk.ListStore(str, str)
tree = Gtk.TreeView(self.parameters_store)
for i, title in enumerate(["Parameter", "Value"]):
@ -54,17 +69,38 @@ class ParametersWindow(Window):
tree.append_column(column)
scroll = Gtk.ScrolledWindow()
scroll.add(tree)
self.add(scroll)
notebook.insert_page(scroll, Gtk.Label("Current values"), -1)
self.lastchanges_store = Gtk.ListStore(str, str, str)
tree = Gtk.TreeView(self.lastchanges_store)
for i, title in enumerate(["Time", "Parameter", "Value"]):
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(title, renderer, text=i)
tree.append_column(column)
scroll = Gtk.ScrolledWindow()
scroll.add(tree)
notebook.insert_page(scroll, Gtk.Label("Last changes"), -1)
@asyncio.coroutine
def sub_connect(self, host, port):
self.parameters_subscriber = Subscriber("parameters",
self.init_parameters_store)
yield from self.parameters_subscriber.connect(host, port)
try:
self.lastchanges_subscriber = Subscriber(
"parameters_simplehist", self.init_lastchanges_store)
yield from self.lastchanges_subscriber.connect(host, port)
except:
yield from self.parameters_subscriber.close()
raise
@asyncio.coroutine
def sub_close(self):
yield from self.lastchanges_subscriber.close()
yield from self.parameters_subscriber.close()
def init_parameters_store(self, init):
return _ParameterStoreSyncer(self.parameters_store, init)
def init_lastchanges_store(self, init):
return _LastChangesStoreSyncer(self.lastchanges_store, init)

View File

@ -3,33 +3,18 @@ import asyncio
from gi.repository import Gtk
from artiq.gui.tools import Window
from artiq.gui.tools import Window, ListSyncer
from artiq.management.sync_struct import Subscriber
class _QueueStoreSyncer:
def __init__(self, queue_store, init):
self.queue_store = queue_store
self.queue_store.clear()
for x in init:
self.append(x)
def _convert(self, x):
class _QueueStoreSyncer(ListSyncer):
def convert(self, x):
rid, run_params, timeout = x
row = [rid, run_params["file"]]
for e in run_params["unit"], run_params["function"], timeout:
row.append("-" if e is None else str(e))
return row
def append(self, x):
self.queue_store.append(self._convert(x))
def insert(self, i, x):
self.queue_store.insert(i, self._convert(x))
def __delitem__(self, key):
del self.queue_store[key]
class _PeriodicStoreSyncer:
def __init__(self, periodic_store, init):

View File

@ -5,9 +5,27 @@ from gi.repository import Gtk
data_dir = os.path.abspath(os.path.dirname(__file__))
class Window(Gtk.Window):
def __init__(self, *args, **kwargs):
Gtk.Window.__init__(self, *args, **kwargs)
self.set_wmclass("ARTIQ", "ARTIQ")
self.set_icon_from_file(os.path.join(data_dir, "icon.png"))
self.set_border_width(6)
class ListSyncer:
def __init__(self, store, init):
self.store = store
self.store.clear()
for x in init:
self.append(x)
def append(self, x):
self.store.append(self.convert(x))
def insert(self, i, x):
self.store.insert(i, self.convert(x))
def __delitem__(self, key):
del self.store[key]

View File

@ -1,5 +1,6 @@
from collections import OrderedDict
import importlib
from time import time
from artiq.language.context import *
from artiq.management import pyon
@ -68,6 +69,7 @@ class DeviceParamDB:
self.pdb_file = pdb_file
self.ddb = Notifier(pyon.load_file(self.ddb_file))
self.pdb = Notifier(pyon.load_file(self.pdb_file))
self.parameter_hooks = []
def save_ddb(self):
pyon.store_file(self.ddb_file, self.ddb.backing_struct)
@ -92,7 +94,29 @@ class DeviceParamDB:
def set_parameter(self, name, value):
self.pdb[name] = value
self.save_pdb()
timestamp = time()
for hook in self.parameter_hooks:
hook.set_parameter(timestamp, name, value)
def del_parameter(self, name):
del self.pdb[name]
self.save_pdb()
timestamp = time()
for hook in self.parameter_hooks:
hook.del_parameter(timestamp, name)
class SimpleParameterHistory:
def __init__(self, depth):
self.depth = depth
self.history = Notifier([])
def set_parameter(self, timestamp, name, value):
if len(self.history.backing_struct) >= self.depth:
del self.history[0]
self.history.append((timestamp, name, value))
def del_parameter(self, timestamp, name):
if len(self.history.backing_struct) >= self.depth:
del self.history[0]
self.history.append((timestamp, name))

View File

@ -6,7 +6,7 @@ import atexit
from artiq.management.pc_rpc import Server
from artiq.management.sync_struct import Publisher
from artiq.management.dpdb import DeviceParamDB
from artiq.management.dpdb import DeviceParamDB, SimpleParameterHistory
from artiq.management.scheduler import Scheduler
@ -26,7 +26,10 @@ def _get_args():
def main():
args = _get_args()
dpdb = DeviceParamDB("ddb.pyon", "pdb.pyon")
simplephist = SimpleParameterHistory(30)
dpdb.parameter_hooks.append(simplephist)
loop = asyncio.get_event_loop()
atexit.register(lambda: loop.close())
@ -50,7 +53,8 @@ def main():
"queue": scheduler.queue,
"periodic": scheduler.periodic,
"devices": dpdb.ddb,
"parameters": dpdb.pdb
"parameters": dpdb.pdb,
"parameters_simplehist": simplephist.history
})
loop.run_until_complete(server_notify.start(
args.bind, args.port_notify))