Beispiel #1
0
 def init_zocp(self):
     self.z = ZOCP("QT UI TEST")
     self.z.register_float("myFloat", 2.3, 'rw', 0, 5.0, 0.1)
     self.notifier = QSocketNotifier(self.z.inbox.getsockopt(zmq.FD),
                                     QSocketNotifier.Read)
     self.notifier.setEnabled(True)
     self.notifier.activated.connect(self.zocp_event)
     self.z.on_modified = self.on_modified
     self.z.start()
Beispiel #2
0
class QTZOCPNode(QWidget):
    def __init__(self):
        super(QTZOCPNode, self).__init__()
        self.qle = QTextEdit(self)
        self.qle.move(1, 1)
        self.qle.resize(640, 480)
        self.init_zocp()
        self.show()

    def init_zocp(self):
        self.z = ZOCP("QT UI TEST")
        self.z.register_float("myFloat", 2.3, 'rw', 0, 5.0, 0.1)
        self.notifier = QSocketNotifier(self.z.inbox.getsockopt(zmq.FD),
                                        QSocketNotifier.Read)
        self.notifier.setEnabled(True)
        self.notifier.activated.connect(self.zocp_event)
        self.z.on_modified = self.on_modified
        self.z.start()

    def zocp_event(self):
        print("ZOCP EVENT START")
        self.z.run_once(0)
        print("ZOCP EVENT END")

    def on_modified(self, peer, name, data, *args, **kwargs):
        t = self.qle.toPlainText()
        t = "{0}\n{1}".format(data, t)
        self.qle.setPlainText(t)

    def closeEvent(self, *args):
        print(args)
        self.z.stop()
        del self.z
Beispiel #3
0
    def initZOCP(self):
        self.zocp = ZOCP()
        self.zocp.set_name("ZOCP Node Editor@%s" % socket.gethostname())
        self.notifier = QSocketNotifier(self.zocp.inbox.getsockopt(zmq.FD),
                                        QSocketNotifier.Read)
        self.notifier.setEnabled(True)
        self.notifier.activated.connect(self.onZOCPEvent)
        self.zocp.on_peer_enter = self.onPeerEnter
        self.zocp.on_peer_exit = self.onPeerExit
        self.zocp.on_peer_modified = self.onPeerModified
        self.zocp.on_peer_signaled = self.onPeerSignaled
        self.zocp.start()

        zl = logging.getLogger("zocp")
        zl.setLevel(logging.INFO)
Beispiel #4
0
 def init_zocp(self):
     self.z = ZOCP(self.nodename)
     
     self.notifier = QtCore.QSocketNotifier(
             self.z.inbox.getsockopt(zmq.FD), 
             QtCore.QSocketNotifier.Read
             )
     self.notifier.setEnabled(True)
     self.notifier.activated.connect(self.zocp_event)
     self.z.start()
Beispiel #5
0
 def init_zocp(self):
     self.z = ZOCP("QT UI TEST")
     self.z.register_float("myFloat", 2.3, 'rw', 0, 5.0, 0.1)
     self.notifier = QSocketNotifier(
             self.z.inbox.getsockopt(zmq.FD), 
             QSocketNotifier.Read
             )
     self.notifier.setEnabled(True)
     self.notifier.activated.connect(self.zocp_event)
     self.z.on_modified = self.on_modified
     self.z.start()
Beispiel #6
0
 def init_zocp(self):
     self.z = ZOCP()
     self.z.set_node_name(self.nodename)
     
     self.notifier = QtCore.QSocketNotifier(
             self.z.inbox.getsockopt(zmq.FD), 
             QtCore.QSocketNotifier.Read
             )
     self.notifier.setEnabled(True)
     self.notifier.activated.connect(self.zocp_event)
     self.z.on_peer_signaled = self.on_peer_signaled
     self.z.on_peer_enter = self.on_peer_enter
     self.z.start()
Beispiel #7
0
    def initZOCP(self):
        self.zocp = ZOCP("ZOCP Node Editor@%s" % socket.gethostname())
        self.notifier = QSocketNotifier(
            self.zocp.inbox.getsockopt(zmq.FD),
            QSocketNotifier.Read)
        self.notifier.setEnabled(True)
        self.notifier.activated.connect(self.onZOCPEvent)
        self.zocp.on_peer_enter = self.onPeerEnter
        self.zocp.on_peer_exit = self.onPeerExit
        self.zocp.on_peer_modified = self.onPeerModified
        self.zocp.on_peer_signaled = self.onPeerSignaled
        self.zocp.start()

        zl = logging.getLogger("zocp")
        zl.setLevel(logging.INFO)
Beispiel #8
0
class QTZOCPNode(QtWidgets.QWidget):

    def __init__(self):
        super(QTZOCPNode, self).__init__()
        self.qle = QtWidgets.QTextEdit(self)
        self.qle.move(1, 1)
        self.qle.resize(640,480)
        self.init_zocp()
        self.show()

    def init_zocp(self):
        self.z = ZOCP()
        self.z.set_node_name("QT UI TEST")
        self.z.register_float("myFloat", 2.3, 'rw', 0, 5.0, 0.1)
        self.notifier = QtCore.QSocketNotifier(
                self.z.inbox.getsockopt(zmq.FD), 
                QtCore.QSocketNotifier.Read
                )
        self.notifier.setEnabled(True)
        self.notifier.activated.connect(self.zocp_event)
        self.z.on_modified = self.on_modified
        self.z.start()

    def zocp_event(self):
        print("ZOCP EVENT START")
        self.z.run_once(0)
        print("ZOCP EVENT END")

    def on_modified(self, peer, name, data, *args, **kwargs):
        t = self.qle.toPlainText()
        t = "{0}\n{1}".format(data, t)
        self.qle.setPlainText(t)

    def closeEvent(self, *args):
        print(args)
        self.z.stop()
Beispiel #9
0
#!/usr/bin/python

from zocp import ZOCP
import logging

if __name__ == '__main__':
    zl = logging.getLogger("zocp")
    zl.setLevel(logging.DEBUG)

    z = ZOCP("ZOCP-Test")
    z.register_bool("myBool", True, 'rwe')
    z.register_float("myFloat", 2.3, 'rws', 0, 5.0, 0.1)
    z.register_int('myInt', 10, access='rwes', min=-10, max=10, step=1)
    z.register_percent('myPercent', 12, access='rw')
    z.register_vec2f('myVec2', [0, 0], access='rwes')
    z.start()
    z.run()
    print("FINISH")
Beispiel #10
0
class QNEMainWindow(QMainWindow):
    def __init__(self, parent):
        super(QNEMainWindow, self).__init__(parent)

        self.logger = logging.getLogger("zne")
        self.logger.setLevel(logging.DEBUG)

        self.setMinimumSize(560,360)
        self.setWindowTitle("ZOCP Node Editor")
        self.setWindowIcon(QIcon('assets/icon.png'))

        self.scene = QGraphicsScene(self)
        self.view = QGraphicsView(self)
        self.view.setScene(self.scene)
        self.setCentralWidget(self.view)

        self.nodesEditor = QNodesEditor(self, self.scene, self.view)

        self.nodesEditor.onAddConnection = self.onAddConnection
        self.nodesEditor.onRemoveConnection = self.onRemoveConnection
        self.nodesEditor.onBlockMoved = self.onBlockMoved

        self.scale = 1
        self.installActions()

        self.initZOCP()

        self.nodes = {}
        self.pendingSubscribers = {}

        QTimer.singleShot(250, lambda: self.scene.invalidate())


    def closeEvent(self, *args):
        self.zocp.stop()


    def installActions(self):
        quitAct = QAction("&Quit", self, shortcut="Ctrl+Q",
            statusTip="Exit the application", triggered=self.close)
        if zconfigmanager_found:
            openAct = QAction("&Open...", self, shortcut="Ctrl+O",
                statusTip="Restore the network from a saved description", triggered=self.readNetwork)
            saveAct = QAction("&Save...", self, shortcut="Ctrl+S",
                statusTip="Write a description of the network to disc", triggered=self.writeNetwork)

        fileMenu = self.menuBar().addMenu("&File")
        if zconfigmanager_found:
            fileMenu.addAction(openAct)
            fileMenu.addAction(saveAct)
            fileMenu.addSeparator()
        fileMenu.addAction(quitAct)

        # for shortcuts
        self.view.addAction(quitAct)

        selectAllAct = QAction("Select &All", self, shortcut="Ctrl+A",
            triggered=self.nodesEditor.selectAll)
        selectNoneAct = QAction("Select &None", self, shortcut="Ctrl+D",
            triggered=self.nodesEditor.selectNone)
        selectInverseAct = QAction("Select &Inverse", self, shortcut="Ctrl+I",
            triggered=self.nodesEditor.selectInverse)
        deleteSelectedAct = QAction("&Delete Selected", self, shortcut="Del",
            triggered=self.nodesEditor.deleteSelected)

        editMenu = self.menuBar().addMenu("&Edit")
        editMenu.addAction(selectAllAct)
        editMenu.addAction(selectNoneAct)
        editMenu.addAction(selectInverseAct)
        editMenu.addSeparator()
        editMenu.addAction(deleteSelectedAct)

        self.view.addAction(selectAllAct)
        self.view.addAction(selectNoneAct)
        self.view.addAction(selectInverseAct)
        self.view.addAction(deleteSelectedAct)

        zoomInAct = QAction("Zoom &In", self, shortcut="Ctrl++",
            triggered=self.zoomIn)
        zoomOutAct = QAction("Zoom &Out", self, shortcut="Ctrl+-",
            triggered=self.zoomOut)
        zoomResetAct = QAction("&Reset Zoom", self, shortcut="Ctrl+0",
            triggered=self.zoomReset)

        viewMenu = self.menuBar().addMenu("&View")
        viewMenu.addAction(zoomInAct)
        viewMenu.addAction(zoomOutAct)
        viewMenu.addSeparator()
        viewMenu.addAction(zoomResetAct)

        self.view.addAction(zoomInAct)
        self.view.addAction(zoomOutAct)
        self.view.addAction(zoomResetAct)

        aboutAct = QAction("&About", self,
             triggered=self.about)

        helpMenu = self.menuBar().addMenu("&Help")
        helpMenu.addAction(aboutAct)

        self.view.addAction(aboutAct)


    def writeNetwork(self):
        fileName, filter = QFileDialog.getSaveFileName(self,
                                                       caption="Save as",
                                                       filter="ZOCP (*.zocp);;JSON (*.json)",
                                                       selectedFilter="ZOCP (*.zocp)")
        if fileName:
            # setup ZOCP node, and run it for some time to discover
            # the current network
            configManager = ZConfigManagerNode("ConfigManager@%s" % socket.gethostname())
            configManager.discover(0.5)

            # write network description to file
            configManager.write(fileName)

            # shut down ZOCP node
            configManager.stop()
            configManager = None


    def readNetwork(self):
        fileName, filter = QFileDialog.getOpenFileName(self,
                                                       caption="Open",
                                                       filter="All files (*.*);;ZOCP (*.zocp);;JSON (*.json)",
                                                       selectedFilter="ZOCP (*.zocp)")
        if fileName:
            # setup ZOCP node, and run it for some time to discover
            # the current network
            configManager = ZConfigManagerNode("ConfigManager@%s" % socket.gethostname())
            configManager.discover(0.5)

            # write network description to file
            configManager.read(fileName)

            # shut down ZOCP node
            configManager.stop()
            configManager = None


    def zoomIn(self):
        if self.scale < 4:
            self.scale *= 1.2
            self.view.scale(1.2, 1.2)


    def zoomOut(self):
        if self.scale > 0.1:
            self.scale /= 1.2
            self.view.scale(1/1.2, 1/1.2)


    def zoomReset(self):
        self.scale = 1
        self.view.setTransform(QTransform())


    def about(self):
        QMessageBox.about(self, "About ZOCP Node Editor",
            "<p>A monitor/editor for ZOCP nodes, implemented in PySide"
             "(Python/Qt4).</p><p>ZOCP is the Z25 Orchestration Control "
             "Protocol, currently in development at "
             "<a href='http://z25.org'>z25.org</a></p>")


    #########################################
    # Node editor callbacks
    #########################################
    def onAddConnection(self, connection, fromPort, toPort):
        fromBlock = fromPort.block()
        toBlock = toPort.block()

        emitter = fromPort.portName()
        emit_peer = fromBlock.uuid()
        receiver = toPort.portName()
        recv_peer = toBlock.uuid()

        self.zocp.signal_subscribe(recv_peer, receiver, emit_peer, emitter)

        self.logger.debug("added subscription from %s on %s to %s on %s" %
               (receiver, fromBlock.name(), emitter, toBlock.name()))


    def onRemoveConnection(self, connection, fromPort, toPort):
        fromBlock = fromPort.block()
        toBlock = toPort.block()

        emitter = fromPort.portName()
        emit_peer = fromBlock.uuid()
        receiver = toPort.portName()
        recv_peer = toBlock.uuid()

        self.zocp.signal_unsubscribe(recv_peer, receiver, emit_peer, emitter)

        self.logger.debug("removed subscription from %s on %s to %s on %s" %
               (receiver, fromBlock.name(), emitter, toBlock.name()))


    def onBlockMoved(self, block):
        pos = block.pos()
        peer = block.uuid()
        self.zocp.peer_set(peer, {"_zne_position": [pos.x(), pos.y()]})


    def onChangeValue(self, block, port, value):
        self.logger.debug("block %s port %s changed to %s" % (block.name(), port.portName(), value))
        peer = block.uuid()
        portName = port.portName()
        capability = self.zocp.peers_capabilities[peer][portName]
        typeHint = capability["typeHint"]
        validValue = True
        if typeHint == "int":
            try:
                value = int(float(value))
            except:
                validValue = False
        elif typeHint == "flt":
            try:
                value = float(value.strip())
            except:
                validValue = False
        elif typeHint == "percent":
            try:
                value = float(value.strip())
            except:
                validValue = False
        elif typeHint == "bool":
            value = (value.strip().lower() in ["true", "yes", "1"])
        elif typeHint == "string":
            pass
        elif typeHint.startswith("vec" ) and typeHint.endswith("f") and len(typeHint) == 5:
            try:
                value = [float(num) for num in ((value.strip())[1:-1]).split(",")]
            except:
                validValue = False

            if validValue:
                if len(value) != int(typeHint[3]):
                    validValue = False

        if validValue:
            self.zocp.peer_set(peer, {portName: {"value": value}})
            port.setValue(str(value))
        else:
            port.setValue(str(capability["value"]))



    #########################################
    # ZOCP implementation
    #########################################
    def initZOCP(self):
        self.zocp = ZOCP("ZOCP Node Editor@%s" % socket.gethostname())
        self.notifier = QSocketNotifier(
            self.zocp.inbox.getsockopt(zmq.FD),
            QSocketNotifier.Read)
        self.notifier.setEnabled(True)
        self.notifier.activated.connect(self.onZOCPEvent)
        self.zocp.on_peer_enter = self.onPeerEnter
        self.zocp.on_peer_exit = self.onPeerExit
        self.zocp.on_peer_modified = self.onPeerModified
        self.zocp.on_peer_signaled = self.onPeerSignaled
        self.zocp.start()

        zl = logging.getLogger("zocp")
        zl.setLevel(logging.INFO)


    def onZOCPEvent(self):
        self.zocp.run_once(0)


    def onPeerEnter(self, peer, name, *args, **kwargs):
        # Subscribe to any and all value changes
        self.zocp.signal_subscribe(self.zocp.uuid(), None, peer, None)

        # Add named block; ports are not known at this point
        block = QNEBlock(None)
        self.scene.addItem(block)
        block.setNodeEditor(self)
        block.setName(name)
        block.setUuid(peer)
        block.addPort(name, False, False, QNEPort.NamePort)
        block.setVisible(False)

        node = {}
        node["block"] = block
        node["ports"] = dict()

        self.nodes[peer.hex] = node


    def onPeerExit(self, peer, name, *args, **kwargs):
        # Unsubscribe from value changes
        self.zocp.signal_unsubscribe(self.zocp.uuid(), None, peer, None)

        # Remove block
        if peer.hex in self.nodes:
            self.nodes[peer.hex]["block"].delete()
            self.nodes.pop(peer.hex)


    def onPeerModified(self, peer, name, data, *args, **kwargs):
        for portname in data:
            portdata = data[portname]

            if portname not in self.nodes[peer.hex]["ports"]:
                if "access" in portdata:
                    hasInput = "s" in portdata["access"]
                    hasOutput = "e" in portdata["access"]
                    port = self.nodes[peer.hex]["block"].addPort(portname, hasInput, hasOutput)
                    port.setValue(str(portdata["value"]))
                    port.setAccess(str(portdata["access"]))
                    self.nodes[peer.hex]["ports"][portname] = port

                else:
                    # Metadata, not a capability
                    if portname == "_zne_position":
                        block = self.nodes[peer.hex]["block"]
                        block.setPos(portdata[0], portdata[1])

            else:
                port = self.nodes[peer.hex]["ports"][portname]
                if "value" in portdata:
                    port.setValue(str(portdata["value"]))
                if "access" in portdata:
                    port.setAccess(str(portdata["access"]))

            if "subscribers" in portdata:
                self.updateSubscribers(port, portdata["subscribers"])

        if len(self.nodes[peer.hex]["ports"]) > 0:
            self.nodes[peer.hex]["block"].setVisible(True)
        self.updatePendingSubscribers(peer)


    def onPeerSignaled(self, peer, name, data, *args, **kwargs):
        [portname, value] = data
        if portname in self.nodes[peer.hex]["ports"]:
            self.nodes[peer.hex]["ports"][portname].setValue(str(value))


    def updateSubscribers(self, port, subscribers):
        port1 = port.outputPort

        # check if any current connections should be removed
        connections = port.connections()
        for connection in connections:
            if(connection.port1() == port1):
                port2 = connection.port2()
            else:
                port2 = connection.port1()

            if not port2.isOutput():
                subscriber = [port2.block().uuid().hex, port2.portName()]
                if subscriber not in subscribers:
                    connection.delete()
                    self.logger.debug("peer removed subscription from %s on %s to %s on %s" %
                        (port1.portName(), port1.block().name(), port2.portName(), port2.block().name()))

        # add new connections for new subscriptions
        for subscriber in subscribers:
            [uuid, portname] = subscriber
            if uuid in self.nodes:
                node = self.nodes[uuid]
                if portname in node["ports"]:
                    port2 = node["ports"][portname]
                    if not port2.isConnected(port1):
                        # create new connection
                        connection = QNEConnection(None)
                        connection.setPort1(port1)
                        connection.setPort2(port2)
                        connection.updatePosFromPorts()
                        connection.updatePath()
                        self.scene.addItem(connection)
                        self.logger.debug("peer added subscription from %s on %s to %s on %s" %
                            (port1.portName(), port1.block().name(), port2.portName(), port2.block().name()))
                    continue

            # if the connection could not be made yet, add it to a list of
            # pending subscriber-connections
            if uuid not in self.pendingSubscribers:
                self.pendingSubscribers[uuid] = []
            self.pendingSubscribers[uuid].append([port1, portname])


    def updatePendingSubscribers(self, peer):
        if peer.hex in self.pendingSubscribers:
            for subscriber in self.pendingSubscribers[peer.hex]:
                [port1, portname] = subscriber
                if peer.hex in self.nodes and portname in self.nodes[peer.hex]["ports"]:
                    port2 = self.nodes[peer.hex]["ports"][portname]

                    connection = QNEConnection(None)
                    connection.setPort1(port1)
                    connection.setPort2(port2)
                    connection.updatePosFromPorts()
                    connection.updatePath()
                    self.scene.addItem(connection)
                else:
                    # TODO: handle case where port is still not available
                    pass

            self.pendingSubscribers.pop(peer.hex)
Beispiel #11
0
 def start(self):
     ZOCP.start(self)
Beispiel #12
0
import gi
from gi.repository import GObject

from zocp import ZOCP
import zmq

GObject.threads_init()
loop = GObject.MainLoop()

z = ZOCP("GLibTest")
z.register_percent('myPercent', 12, access='rw')


def zocp_handle(*args, **kwargs):
    z.run_once()
    return True


GObject.io_add_watch(z.inbox.getsockopt(zmq.FD), GObject.PRIORITY_DEFAULT,
                     GObject.IO_IN, zocp_handle)
z.start()
try:
    loop.run()
except Exception as e:
    print(e)
finally:
    z.stop()
Beispiel #13
0
import gi
from gi.repository import GObject

from zocp import ZOCP
import zmq

GObject.threads_init()
loop = GObject.MainLoop()

z = ZOCP("GLibTest")
z.register_percent('myPercent', 12, access='rw')

def zocp_handle(*args, **kwargs):
    z.run_once()
    return True

GObject.io_add_watch(
        z.inbox.getsockopt(zmq.FD), 
        GObject.PRIORITY_DEFAULT, 
        GObject.IO_IN, zocp_handle
    )
z.start()
try:
    loop.run()
except Exception as e:
    print(e)
finally:
    z.stop()
Beispiel #14
0
 def start(self):
     ZOCP.start(self)  # Start ZOCP
     self.thread = threading.Thread(target=self.run)
     self.thread.daemon = True
     self.thread.start()  # And run loop
     print(self.name(), "started")
Beispiel #15
0
 def start(self):
     ZOCP.start(self)                            # Start ZOCP        
     self.thread = threading.Thread(target=self.run)
     self.thread.daemon = True
     self.thread.start()                         # And run loop
     print(self.name(), "started")
Beispiel #16
0
#!/usr/bin/python

from zocp import ZOCP
import logging

if __name__ == '__main__':
    zl = logging.getLogger("zocp")
    zl.setLevel(logging.DEBUG)

    z = ZOCP()
    z.set_name("ZOCP-Test")
    z.register_bool("myBool", True, 'rwe')
    z.register_float("myFloat", 2.3, 'rws', 0, 5.0, 0.1)
    z.register_int('myInt', 10, access='rwes', min=-10, max=10, step=1)
    z.register_percent('myPercent', 12, access='rw')
    z.register_vec2f('myVec2', [0,0], access='rwes')
    z.start()
    z.run()
    print("FINISH")
Beispiel #17
0
import termios, fcntl, os
from zocp import ZOCP

if __name__ == '__main__':
    # see https://docs.python.org/2/faq/library.html#how-do-i-get-a-single-keypress-at-a-time
    fd = sys.stdin.fileno()

    oldterm = termios.tcgetattr(fd)
    newattr = termios.tcgetattr(fd)
    newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
    termios.tcsetattr(fd, termios.TCSANOW, newattr)

    oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

    z = ZOCP()
    hostname = socket.gethostname()
    z.set_name("keyboard@{0}".format(hostname))
    z.register_string("Keyboard", "", 're')
    z.start()

    zpoller = zmq.Poller()
    zpoller.register(sys.stdin, zmq.POLLIN)
    zpoller.register(z.inbox, zmq.POLLIN)
    def handle_key_in():
        input = sys.stdin.read(1)
        print("KEYBOARD IN: {0}".format(input))
        z.emit_signal("Keyboard", input)

    running = True
    try:
Beispiel #18
0
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
#
# Example:
# tail -f /var/log/syslog | zstdio.py

import sys
import zmq
import socket
import fcntl, os
from zocp import ZOCP

if __name__ == '__main__':
    hostname = socket.gethostname()
    z = ZOCP("zstdio@{0}".format(hostname))
    z.register_string("stdin", "", 're')
    z.start()

    # we need to set stdin to non blocking otherwise 
    # a read could potentially block
    flags = fcntl.fcntl(sys.stdin, fcntl.F_GETFL) 
    fcntl.fcntl(sys.stdin, fcntl.F_SETFL, flags | os.O_NONBLOCK)

    zpoller = zmq.Poller()
    zpoller.register(sys.stdin.fileno(), zmq.POLLIN)
    zpoller.register(z.inbox, zmq.POLLIN)
    def handle_stdin():
        input = sys.stdin.read(1024)
        sys.stdin.flush()
        if input:
Beispiel #19
0
import socket
import fcntl
import os
import array
import struct
import pyinotify
import termios
from zocp import ZOCP
import logging

if __name__ == '__main__':
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    logger.addHandler(logging.StreamHandler())
    hostname = socket.gethostname()
    z = ZOCP("zinotify@{0}".format(hostname))
    z.register_string("watchdir", "/tmp", "rw")
    z.register_string("file", "", 're')
    z.start()

    # setup inotify
    i = pyinotify.INotifyWrapper.create()
    ifd = i._inotify_init()
    # add a directory to watch
    iwd = i.inotify_add_watch( ifd, z.get_value('watchdir'), pyinotify.IN_DELETE )

    zpoller = zmq.Poller()
    zpoller.register(ifd, zmq.POLLIN)
    zpoller.register(z.inbox, zmq.POLLIN)
    
    def handle_modified(peer, name, data, *args, **kwargs):
Beispiel #20
0
 def start(self):
     ZOCP.start(self)
Beispiel #21
0
class QTZOCPnumber(QtGui.QWidget):
    
    def __init__(self):
        super(QTZOCPnumber, self).__init__()

         # Set name of Node
        self.nodename = "QT LCDdisplay@%s" % socket.gethostname()

        self.init_zocp()
        self.initUI()

    def init_zocp(self):
        self.z = ZOCP(self.nodename)
        
        self.notifier = QtCore.QSocketNotifier(
                self.z.inbox.getsockopt(zmq.FD), 
                QtCore.QSocketNotifier.Read
                )
        self.notifier.setEnabled(True)
        self.notifier.activated.connect(self.zocp_event)
        self.z.on_peer_signaled = self.on_peer_signaled
        self.z.on_peer_enter = self.on_peer_enter
        self.z.start()

          
    def initUI(self):
        
        self.lcd1 = QtGui.QLCDNumber(self)
        self.lcd2 = QtGui.QLCDNumber(self)
        self.lcd3 = QtGui.QLCDNumber(self)

        # Register the ZOCP variables
        self.z.register_int("display1", 0, access='rs')
        self.z.register_int("display2", 0, access='rs')
        self.z.register_int("display3", 0, access='rs')

        grid = QtGui.QGridLayout()
        grid.setSpacing(10)

        grid.addWidget(self.lcd1, 1, 1)
        grid.addWidget(self.lcd2, 1, 2)
        grid.addWidget(self.lcd3, 1, 3)
        
        self.setLayout(grid) 
        self.setGeometry(300, 300, 150, 70)
        self.setWindowTitle(self.nodename)
        self.show()

        

    def zocp_event(self):
        self.z.run_once(0)

    def on_peer_signaled(self, peer, name, data, *args, **kwargs):
        """
        Called when a peer signals that some of its data is modified.

        peer: id of peer whose data has been changed
        name: name of peer whose data has been changed
        data: changed data, formatted as [emitter, value]
              emitter: name of the emitter on the subscribee
              value: value of the emitter
        """
        zl.debug(" --> ZOCP PEER SIGNALED: %s modified %s" %(name, data))

        # Check if there is data
        if(len(data) > 1):

            if(data[0] == "slider1"):
                self.lcd1.display(data[1])
            elif(data[0] == "slider2"):
                self.lcd2.display(data[1])
            elif(data[0] == "slider3"):
                self.lcd3.display(data[1])


    def on_peer_enter(self, peer, name, *args, **kwargs):
        
        zl.debug(" -----> PEER ENTERED ",name," peer: ",peer)
        # This assumes that for testing the source to connect to is running on the same computer as the 
        # the destination trying to connect to it is.
        sourceTargetName = "QT Sliders@%s" % socket.gethostname()
        if(name == sourceTargetName):
            self.z.signal_subscribe(self.z.uuid(), 'display1', peer, 'slider1')
            self.z.signal_subscribe(self.z.uuid(), 'display2', peer, 'slider2')
            self.z.signal_subscribe(self.z.uuid(), 'display3', peer, 'slider3')
            zl.debug("Nodes are subscribed")


    def closeEvent(self, *args):
        zl.debug(args)
        self.z.stop()
Beispiel #22
0
class QNEMainWindow(QMainWindow):
    def __init__(self, parent):
        super(QNEMainWindow, self).__init__(parent)

        self.logger = logging.getLogger("zne")
        self.logger.setLevel(logging.DEBUG)

        self.setMinimumSize(560, 360)
        self.setWindowTitle("ZOCP Node Editor")
        self.setWindowIcon(QIcon('assets/icon.png'))

        self.scene = QGraphicsScene(self)
        self.view = QGraphicsView(self)
        self.view.setScene(self.scene)
        self.setCentralWidget(self.view)

        self.nodesEditor = QNodesEditor(self, self.scene, self.view)

        self.nodesEditor.onAddConnection = self.onAddConnection
        self.nodesEditor.onRemoveConnection = self.onRemoveConnection
        self.nodesEditor.onBlockMoved = self.onBlockMoved

        self.scale = 1
        self.installActions()

        self.initZOCP()

        self.nodes = {}
        self.pendingSubscribers = {}

        QTimer.singleShot(250, lambda: self.scene.invalidate())

    def closeEvent(self, *args):
        self.zocp.stop()

    def installActions(self):
        quitAct = QAction("&Quit",
                          self,
                          shortcut="Ctrl+Q",
                          statusTip="Exit the application",
                          triggered=self.close)

        fileMenu = self.menuBar().addMenu("&File")
        fileMenu.addAction(quitAct)

        # for shortcuts
        self.view.addAction(quitAct)

        selectAllAct = QAction("Select &All",
                               self,
                               shortcut="Ctrl+A",
                               triggered=self.nodesEditor.selectAll)
        selectNoneAct = QAction("Select &None",
                                self,
                                shortcut="Ctrl+D",
                                triggered=self.nodesEditor.selectNone)
        selectInverseAct = QAction("Select &Inverse",
                                   self,
                                   shortcut="Ctrl+I",
                                   triggered=self.nodesEditor.selectInverse)
        deleteSelectedAct = QAction("&Delete Selected",
                                    self,
                                    shortcut="Del",
                                    triggered=self.nodesEditor.deleteSelected)

        editMenu = self.menuBar().addMenu("&Edit")
        editMenu.addAction(selectAllAct)
        editMenu.addAction(selectNoneAct)
        editMenu.addAction(selectInverseAct)
        editMenu.addSeparator()
        editMenu.addAction(deleteSelectedAct)

        self.view.addAction(selectAllAct)
        self.view.addAction(selectNoneAct)
        self.view.addAction(selectInverseAct)
        self.view.addAction(deleteSelectedAct)

        zoomInAct = QAction("Zoom &In",
                            self,
                            shortcut="Ctrl++",
                            triggered=self.zoomIn)
        zoomOutAct = QAction("Zoom &Out",
                             self,
                             shortcut="Ctrl+-",
                             triggered=self.zoomOut)
        zoomResetAct = QAction("&Reset Zoom",
                               self,
                               shortcut="Ctrl+0",
                               triggered=self.zoomReset)

        viewMenu = self.menuBar().addMenu("&View")
        viewMenu.addAction(zoomInAct)
        viewMenu.addAction(zoomOutAct)
        viewMenu.addSeparator()
        viewMenu.addAction(zoomResetAct)

        self.view.addAction(zoomInAct)
        self.view.addAction(zoomOutAct)
        self.view.addAction(zoomResetAct)

        aboutAct = QAction("&About", self, triggered=self.about)

        helpMenu = self.menuBar().addMenu("&Help")
        helpMenu.addAction(aboutAct)

        self.view.addAction(aboutAct)

    def zoomIn(self):
        if self.scale < 4:
            self.scale *= 1.2
            self.view.scale(1.2, 1.2)

    def zoomOut(self):
        if self.scale > 0.1:
            self.scale /= 1.2
            self.view.scale(1 / 1.2, 1 / 1.2)

    def zoomReset(self):
        self.scale = 1
        self.view.setTransform(QTransform())

    def about(self):
        QMessageBox.about(
            self, "About ZOCP Node Editor",
            "<p>A monitor/editor for ZOCP nodes, implemented in PySide"
            "(Python/Qt4).</p><p>ZOCP is the Z25 Orchestration Control "
            "Protocol, currently in development at "
            "<a href='http://z25.org'>z25.org</a></p>")

    #########################################
    # Node editor callbacks
    #########################################
    def onAddConnection(self, connection, fromPort, toPort):
        fromBlock = fromPort.block()
        toBlock = toPort.block()

        emitter = toPort.portName()
        emit_peer = toBlock.uuid()
        receiver = fromPort.portName()
        recv_peer = fromBlock.uuid()

        self.zocp.signal_subscribe(recv_peer, receiver, emit_peer, emitter)

        self.logger.debug(
            "added subscription from %s on %s to %s on %s" %
            (receiver, fromBlock.name(), emitter, toBlock.name()))

    def onRemoveConnection(self, connection, fromPort, toPort):
        fromBlock = fromPort.block()
        toBlock = toPort.block()

        emitter = toPort.portName()
        emit_peer = toBlock.uuid()
        receiver = fromPort.portName()
        recv_peer = fromBlock.uuid()

        self.zocp.signal_unsubscribe(recv_peer, receiver, emit_peer, emitter)

        self.logger.debug(
            "removed subscription from %s on %s to %s on %s" %
            (receiver, fromBlock.name(), emitter, toBlock.name()))

    def onBlockMoved(self, block):
        pos = block.pos()
        peer = block.uuid()
        self.zocp.peer_set(peer, {"_zne_position": [pos.x(), pos.y()]})

    def onChangeValue(self, block, port, value):
        self.logger.debug("block %s port %s changed to %s" %
                          (block.name(), port.portName(), value))
        peer = block.uuid()
        portName = port.portName()
        capability = self.zocp.peers_capabilities[peer][portName]
        typeHint = capability["typeHint"]
        validValue = True
        if typeHint == "int":
            try:
                value = int(float(value))
            except:
                validValue = False
        elif typeHint == "flt":
            try:
                value = float(value.strip())
            except:
                validValue = False
        elif typeHint == "percent":
            try:
                value = float(value.strip())
            except:
                validValue = False
        elif typeHint == "bool":
            value = (value.strip() in ["true", "yes", "1"])
        elif typeHint == "string":
            pass
        elif typeHint == "vec2f" or typeHint == "vec3f" or typeHint == "vec4f":
            try:
                value = [
                    float(num) for num in ((value.strip())[1:-1]).split(",")
                ]
            except:
                validValue = False

            if validValue:
                if len(value) != int(typeHint[3]):
                    validValue = False

        if validValue:
            self.zocp.peer_set(peer, {portName: {"value": value}})
            port.setValue(str(value))
        else:
            port.setValue(str(capability["value"]))

    #########################################
    # ZOCP implementation
    #########################################
    def initZOCP(self):
        self.zocp = ZOCP()
        self.zocp.set_name("ZOCP Node Editor@%s" % socket.gethostname())
        self.notifier = QSocketNotifier(self.zocp.inbox.getsockopt(zmq.FD),
                                        QSocketNotifier.Read)
        self.notifier.setEnabled(True)
        self.notifier.activated.connect(self.onZOCPEvent)
        self.zocp.on_peer_enter = self.onPeerEnter
        self.zocp.on_peer_exit = self.onPeerExit
        self.zocp.on_peer_modified = self.onPeerModified
        self.zocp.on_peer_signaled = self.onPeerSignaled
        self.zocp.start()

        zl = logging.getLogger("zocp")
        zl.setLevel(logging.INFO)

    def onZOCPEvent(self):
        self.zocp.run_once(0)

    def onPeerEnter(self, peer, name, *args, **kwargs):
        # Subscribe to any and all value changes
        self.zocp.signal_subscribe(self.zocp.get_uuid(), None, peer, None)

        # Add named block; ports are not known at this point
        block = QNEBlock(None)
        self.scene.addItem(block)
        block.setNodeEditor(self)
        block.setName(name)
        block.setUuid(peer)
        block.addPort(name, False, False, QNEPort.NamePort)
        block.setVisible(False)

        node = {}
        node["block"] = block
        node["ports"] = dict()

        self.nodes[peer.hex] = node

    def onPeerExit(self, peer, name, *args, **kwargs):
        # Unsubscribe from value changes
        self.zocp.signal_unsubscribe(self.zocp.get_uuid(), None, peer, None)

        # Remove block
        if peer.hex in self.nodes:
            self.nodes[peer.hex]["block"].delete()
            self.nodes.pop(peer.hex)

    def onPeerModified(self, peer, name, data, *args, **kwargs):
        for portname in data:
            portdata = data[portname]

            if portname not in self.nodes[peer.hex]["ports"]:
                if "access" in portdata:
                    hasInput = "s" in portdata["access"]
                    hasOutput = "e" in portdata["access"]
                    port = self.nodes[peer.hex]["block"].addPort(
                        portname, hasInput, hasOutput)
                    port.setValue(str(portdata["value"]))
                    self.nodes[peer.hex]["ports"][portname] = port

                else:
                    # Metadata, not a capability
                    if portname == "_zne_position":
                        block = self.nodes[peer.hex]["block"]
                        block.setPos(portdata[0], portdata[1])

            else:
                port = self.nodes[peer.hex]["ports"][portname]
                if "value" in portdata:
                    port.setValue(str(portdata["value"]))

            if "subscribers" in portdata:
                self.updateSubscribers(port, portdata["subscribers"])

        if len(self.nodes[peer.hex]["ports"]) > 0:
            self.nodes[peer.hex]["block"].setVisible(True)
        self.updatePendingSubscribers(peer)

    def onPeerSignaled(self, peer, name, data, *args, **kwargs):
        [portname, value] = data
        if portname in self.nodes[peer.hex]["ports"]:
            self.nodes[peer.hex]["ports"][portname].setValue(str(value))

    def updateSubscribers(self, port, subscribers):
        port1 = port.outputPort

        # check if any current connections should be removed
        connections = port.connections()
        for connection in connections:
            if (connection.port1() == port1):
                port2 = connection.port2()
            else:
                port2 = connection.port1()

            if not port2.isOutput():
                subscriber = [port2.block().uuid().hex, port2.portName()]
                if subscriber not in subscribers:
                    connection.delete()
                    self.logger.debug(
                        "peer removed subscription from %s on %s to %s on %s" %
                        (port1.portName(), port1.block().name(),
                         port2.portName(), port2.block().name()))

        # add new connections for new subscriptions
        for subscriber in subscribers:
            [uuid, portname] = subscriber
            if uuid in self.nodes:
                node = self.nodes[uuid]
                if portname in node["ports"]:
                    port2 = node["ports"][portname]
                    if not port2.isConnected(port1):
                        # create new connection
                        connection = QNEConnection(None)
                        connection.setPort1(port1)
                        connection.setPort2(port2)
                        connection.updatePosFromPorts()
                        connection.updatePath()
                        self.scene.addItem(connection)
                        self.logger.debug(
                            "peer added subscription from %s on %s to %s on %s"
                            % (port1.portName(), port1.block().name(),
                               port2.portName(), port2.block().name()))
                    continue

            # if the connection could not be made yet, add it to a list of
            # pending subscriber-connections
            if uuid not in self.pendingSubscribers:
                self.pendingSubscribers[uuid] = []
            self.pendingSubscribers[uuid].append([port1, portname])

    def updatePendingSubscribers(self, peer):
        if peer.hex in self.pendingSubscribers:
            for subscriber in self.pendingSubscribers[peer.hex]:
                [port1, portname] = subscriber
                if peer.hex in self.nodes and portname in self.nodes[
                        peer.hex]["ports"]:
                    port2 = self.nodes[peer.hex]["ports"][portname]

                    connection = QNEConnection(None)
                    connection.setPort1(port1)
                    connection.setPort2(port2)
                    connection.updatePosFromPorts()
                    connection.updatePath()
                    self.scene.addItem(connection)
                else:
                    # TODO: handle case where port is still not available
                    pass

            self.pendingSubscribers.pop(peer.hex)
Beispiel #23
0
import sys
import zmq
import socket
import struct
from zocp import ZOCP

XSIGN = 1<<4
YSIGN = 1<<5

if __name__ == '__main__':
    fd = open('/dev/input/mouse0','rb')
    fn = fd.fileno()

    hostname = socket.gethostname()
    z = ZOCP("mouse@{0}".format(hostname))
    z.start()

    position = [0., 0.]
    button = [False, False, False]

    z.register_vec2f("Position", position, 're')
    z.register_bool("Left button", button[0], 're')
    z.register_bool("Right button", button[1], 're')
    z.register_bool("Middle button", button[2], 're')

    zpoller = zmq.Poller()
    zpoller.register(fd, zmq.POLLIN)
    zpoller.register(z.inbox, zmq.POLLIN)

    def handle_mouse_in():
        (buttons, dx, dy) = struct.unpack('BBB', fd.read(3))
Beispiel #24
0
class QTZOCPNode(QtGui.QWidget):

    def __init__(self):
        super(QTZOCPNode, self).__init__()

        # Set name of Node
        self.nodename = "QT Sliders@%s" % socket.gethostname()
        
        self.init_zocp()
        self.initUI()
 
    def init_zocp(self):
        self.z = ZOCP()
        self.z.set_name(self.nodename)
        
        self.notifier = QtCore.QSocketNotifier(
                self.z.inbox.getsockopt(zmq.FD), 
                QtCore.QSocketNotifier.Read
                )
        self.notifier.setEnabled(True)
        self.notifier.activated.connect(self.zocp_event)
        self.z.start()

    def initUI(self):      

        # Create Sliders
        sld1 = self.createSlider("slider1",0,100)
        sld2 = self.createSlider("slider2",0,100)
        sld3 = self.createSlider("slider3",0,100)

        # Create Layout Grid
        grid = QtGui.QGridLayout()
        grid.setSpacing(10)

        # add all the widgets to the grid
        grid.addWidget(sld1, 1, 1)
        grid.addWidget(sld1.label, 2, 1)
        grid.addWidget(sld2, 1, 2)
        grid.addWidget(sld2.label, 2, 2)
        grid.addWidget(sld3, 1, 3)
        grid.addWidget(sld3.label, 2, 3)
        
        # set layout of window
        self.setLayout(grid) 
        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle(self.nodename)
        self.show()

    def createSlider(self, _id, _min, _max):

        sld = QtGui.QSlider(QtCore.Qt.Vertical, self)
        sld.setAccessibleName(_id)
        sld.setFocusPolicy(QtCore.Qt.NoFocus)
        sld.valueChanged[int].connect(self.changeValue)
        sld.setMinimum(_min)
        sld.setMaximum(_max)
        
        sld.label = QtGui.QLabel(self)
        sld.label.setText(_id)

        # Register the ZOCP variable
        self.z.register_float(_id, 0, access='rwe', min=_min, max=_max, step=1)

        return sld

    def changeValue(self, value):
        sender = self.sender().accessibleName()
        zl.debug("value ",value," id ",sender)

        # ZOCP: HANDLE VALUE CHANGE  
        self.z.emit_signal(sender, value)

    
    # HANDLE INCOMING ZOCP MESSAGES 
    def zocp_event(self):
        self.z.run_once(0)
         
    def closeEvent(self, *args):
        zl.debug(args)
        self.z.stop()
Beispiel #25
0
from zocp import ZOCP

if __name__ == '__main__':
    # see https://docs.python.org/2/faq/library.html#how-do-i-get-a-single-keypress-at-a-time
    fd = sys.stdin.fileno()

    oldterm = termios.tcgetattr(fd)
    newattr = termios.tcgetattr(fd)
    newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
    termios.tcsetattr(fd, termios.TCSANOW, newattr)

    oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

    hostname = socket.gethostname()
    z = ZOCP("keyboard@{0}".format(hostname))
    z.register_string("Keyboard", "", 're')
    z.start()

    zpoller = zmq.Poller()
    zpoller.register(sys.stdin, zmq.POLLIN)
    zpoller.register(z.inbox, zmq.POLLIN)
    def handle_key_in():
        input = sys.stdin.read(1)
        print("KEYBOARD IN: {0}".format(input))
        z.emit_signal("Keyboard", input)

    running = True
    try:
        while running:
                items = dict(zpoller.poll())
Beispiel #26
0
import sys
import zmq
import socket
import struct
from zocp import ZOCP

XSIGN = 1<<4
YSIGN = 1<<5

if __name__ == '__main__':
    fd = open('/dev/input/mouse0','rb')
    fn = fd.fileno()

    z = ZOCP()
    hostname = socket.gethostname()
    z.set_name("mouse@{0}".format(hostname))
    z.start()

    position = [0., 0.]
    button = [False, False, False]

    z.register_vec2f("Position", position, 're')
    z.register_bool("Left button", button[0], 're')
    z.register_bool("Right button", button[1], 're')
    z.register_bool("Middle button", button[2], 're')

    zpoller = zmq.Poller()
    zpoller.register(fd, zmq.POLLIN)
    zpoller.register(z.inbox, zmq.POLLIN)

    def handle_mouse_in():