diff --git a/artiq/frontend/artiq_gui.py b/artiq/frontend/artiq_gui.py index 40bf6658a..65c1a0fee 100755 --- a/artiq/frontend/artiq_gui.py +++ b/artiq/frontend/artiq_gui.py @@ -11,10 +11,12 @@ from pyqtgraph import dockarea from artiq.protocols.file_db import FlatFileDB from artiq.protocols.pc_rpc import AsyncioClient +from artiq.protocols.sync_struct import Subscriber from artiq.gui.explorer import ExplorerDock +from artiq.gui.moninj import MonInjTTLDock, MonInjDDSDock from artiq.gui.parameters import ParametersDock -from artiq.gui.log import LogDock from artiq.gui.schedule import ScheduleDock +from artiq.gui.log import LogDock def get_argparser(): @@ -59,26 +61,41 @@ def main(): win.setWindowTitle("ARTIQ") d_explorer = ExplorerDock(status_bar, schedule_ctl) - area.addDock(d_explorer, "top") loop.run_until_complete(d_explorer.sub_connect( args.server, args.port_notify)) atexit.register(lambda: loop.run_until_complete(d_explorer.sub_close())) + d_ttl = MonInjTTLDock() + loop.run_until_complete(d_ttl.start()) + atexit.register(lambda: loop.run_until_complete(d_ttl.stop())) + d_dds = MonInjDDSDock() + devices_sub = Subscriber("devices", + [d_ttl.init_devices, d_dds.init_devices]) + loop.run_until_complete( + devices_sub.connect(args.server, args.port_notify)) + atexit.register( + lambda: loop.run_until_complete(devices_sub.close())) + + area.addDock(d_dds, "top") + area.addDock(d_ttl, "above", d_dds) + area.addDock(d_explorer, "above", d_ttl) + d_params = ParametersDock() area.addDock(d_params, "right", d_explorer) loop.run_until_complete(d_params.sub_connect( args.server, args.port_notify)) atexit.register(lambda: loop.run_until_complete(d_params.sub_close())) - d_log = LogDock() - area.addDock(d_log, "bottom") - d_schedule = ScheduleDock(schedule_ctl) - area.addDock(d_schedule, "above", d_log) loop.run_until_complete(d_schedule.sub_connect( args.server, args.port_notify)) atexit.register(lambda: loop.run_until_complete(d_schedule.sub_close())) + d_log = LogDock() + + area.addDock(d_log, "bottom") + area.addDock(d_schedule, "above", d_log) + win.show() loop.run_forever() diff --git a/artiq/gui/explorer.py b/artiq/gui/explorer.py index 3f1e590fd..2e878f507 100644 --- a/artiq/gui/explorer.py +++ b/artiq/gui/explorer.py @@ -23,7 +23,7 @@ class _ExplistModel(DictSyncModel): class ExplorerDock(dockarea.Dock): def __init__(self, status_bar, schedule_ctl): - dockarea.Dock.__init__(self, "Explorer", size=(1100, 400)) + dockarea.Dock.__init__(self, "Explorer", size=(1500, 500)) self.status_bar = status_bar self.schedule_ctl = schedule_ctl diff --git a/artiq/gui/moninj.py b/artiq/gui/moninj.py new file mode 100644 index 000000000..8391b761b --- /dev/null +++ b/artiq/gui/moninj.py @@ -0,0 +1,89 @@ +import asyncio +import logging +import socket +import struct + +from quamash import QtGui +from pyqtgraph import dockarea + +from artiq.tools import TaskObject + + +logger = logging.getLogger(__name__) + + +class _DeviceManager: + def __init__(self, init): + self.comm = None + if "comm" in init: + self.comm = init["comm"] + + def __setitem__(self, k, v): + if k == "comm": + self.comm = v + + def get_core_addr(self): + if self.comm is None: + return None + try: + return self.comm["arguments"]["host"] + except KeyError: + return None + + +class MonInjTTLDock(dockarea.Dock, TaskObject): + def __init__(self): + dockarea.Dock.__init__(self, "TTL", size=(1500, 500)) + self.dm = _DeviceManager(dict()) + self.transport = None + + @asyncio.coroutine + def start(self): + loop = asyncio.get_event_loop() + yield from loop.create_datagram_endpoint(lambda: self, family=socket.AF_INET) + TaskObject.start(self) + + @asyncio.coroutine + def stop(self): + yield from TaskObject.stop(self) + if self.transport is not None: + self.transport.close() + self.transport = None + + def connection_made(self, transport): + self.transport = transport + + def datagram_received(self, data, addr): + levels, oe = struct.unpack(">QQ", data) + print("Received:", hex(levels), hex(oe)) + + def error_received(self, exc): + logger.warning("datagram endpoint error") + + def connection_lost(self, exc): + self.transport = None + + @asyncio.coroutine + def _do(self): + while True: + yield from asyncio.sleep(0.2) + ca = self.dm.get_core_addr() + if ca is None: + logger.warning("could not find core device address") + elif self.transport is None: + logger.warning("datagram endpoint not available") + else: + # MONINJ_REQ_MONITOR + self.transport.sendto(b"\x01", (ca, 3250)) + + def init_devices(self, d): + self.dm = _DeviceManager(d) + return self.dm + + +class MonInjDDSDock(dockarea.Dock): + def __init__(self): + dockarea.Dock.__init__(self, "DDS", size=(1500, 500)) + + def init_devices(self, d): + return d diff --git a/artiq/gui/parameters.py b/artiq/gui/parameters.py index c23bbeb6e..873656eff 100644 --- a/artiq/gui/parameters.py +++ b/artiq/gui/parameters.py @@ -26,7 +26,7 @@ class ParametersModel(DictSyncModel): class ParametersDock(dockarea.Dock): def __init__(self): - dockarea.Dock.__init__(self, "Parameters", size=(500, 300)) + dockarea.Dock.__init__(self, "Parameters", size=(400, 300)) self.table = QtGui.QTableView() self.table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) diff --git a/artiq/master/scheduler.py b/artiq/master/scheduler.py index 85815209b..9d989af73 100644 --- a/artiq/master/scheduler.py +++ b/artiq/master/scheduler.py @@ -4,7 +4,8 @@ from enum import Enum from time import time from artiq.master.worker import Worker -from artiq.tools import asyncio_wait_or_cancel, asyncio_queue_peek, WaitSet +from artiq.tools import (asyncio_wait_or_cancel, asyncio_queue_peek, + TaskObject, WaitSet) from artiq.protocols.sync_struct import Notifier @@ -149,21 +150,6 @@ class RunPool: del self.runs[rid] -class TaskObject: - def start(self): - self.task = asyncio.async(self._do()) - - @asyncio.coroutine - def stop(self): - self.task.cancel() - yield from asyncio.wait([self.task]) - del self.task - - @asyncio.coroutine - def _do(self): - raise NotImplementedError - - class PrepareStage(TaskObject): def __init__(self, flush_tracker, delete_cb, pool, outq): self.flush_tracker = flush_tracker diff --git a/artiq/tools.py b/artiq/tools.py index b7e6e8dc8..c7ddcab48 100644 --- a/artiq/tools.py +++ b/artiq/tools.py @@ -130,6 +130,21 @@ def asyncio_queue_peek(q): raise asyncio.QueueEmpty +class TaskObject: + def start(self): + self.task = asyncio.async(self._do()) + + @asyncio.coroutine + def stop(self): + self.task.cancel() + yield from asyncio.wait([self.task]) + del self.task + + @asyncio.coroutine + def _do(self): + raise NotImplementedError + + class WaitSet: def __init__(self): self._s = set()