Exemplo n.º 1
0
class TelldusLive(Plugin):
    observers = ObserverCollection(ITelldusLiveObserver)

    def __init__(self):
        print("Telldus Live! loading")
        self.email = ''
        self.supportedMethods = 0
        self.connected = False
        self.registered = False
        self.serverList = ServerList()
        Application().registerShutdown(self.stop)
        self.s = Settings('tellduslive.config')
        self.uuid = self.s['uuid']
        self.conn = ServerConnection()
        self.pingTimer = 0
        self.thread = threading.Thread(target=self.run)
        if self.conn.publicKey != '':
            # Only connect if the keys has been set.
            self.thread.start()

    @mainthread
    def handleMessage(self, message):
        if (message.name() == "notregistered"):
            self.email = ''
            self.connected = True
            self.registered = False
            params = message.argument(0).dictVal
            self.s['uuid'] = params['uuid'].stringVal
            print(
                "This client isn't activated, please activate it using this url:\n%s"
                % params['url'].stringVal)
            self.observers.liveConnected()
            return

        if (message.name() == "registered"):
            self.connected = True
            self.registered = True
            data = message.argument(0).toNative()
            if 'email' in data:
                self.email = data['email']
            self.observers.liveRegistered(data)
            return

        if (message.name() == "command"):
            # Extract ACK and handle it
            args = message.argument(0).dictVal
            if 'ACK' in args:
                msg = LiveMessage("ACK")
                msg.append(args['ACK'].intVal)
                self.send(msg)

        if (message.name() == "pong"):
            return

        if (message.name() == "disconnect"):
            self.conn.close()
            self.__disconnected()
            return

        handled = False
        for o in self.observers:
            for f in getattr(o, '_telldusLiveHandlers',
                             {}).get(message.name(), []):
                f(o, message)
                handled = True
        if not handled:
            print "Did not understand: %s" % message.toByteArray()

    def isConnected(self):
        return self.connected

    def isRegistered(self):
        return self.registered

    def run(self):
        self.running = True

        wait = 0
        pongTimer, self.pingTimer = (0, 0)
        while self.running:
            if wait > 0:
                wait = wait - 1
                time.sleep(1)
                continue
            state = self.conn.process()
            if state == ServerConnection.CLOSED:
                server = self.serverList.popServer()
                if not server:
                    wait = random.randint(60, 300)
                    print("No servers found, retry in %i seconds" % wait)
                    continue
                if not self.conn.connect(server['address'], int(
                        server['port'])):
                    wait = random.randint(60, 300)
                    print("Could not connect, retry in %i seconds" % wait)

            elif state == ServerConnection.CONNECTED:
                pongTimer, self.pingTimer = (time.time(), time.time())
                self.__sendRegisterMessage()

            elif state == ServerConnection.MSG_RECEIVED:
                msg = self.conn.popMessage()
                if msg is None:
                    continue
                pongTimer = time.time()
                self.handleMessage(msg)

            elif state == ServerConnection.DISCONNECTED:
                wait = random.randint(10, 50)
                print("Disconnected, reconnect in %i seconds" % wait)
                self.__disconnected()

            else:
                if (time.time() - pongTimer >= 360):  # No pong received
                    self.conn.close()
                    wait = random.randint(10, 50)
                    print(
                        "No pong received, disconnecting. Reconnect in %i seconds"
                        % wait)
                    self.__disconnected()
                elif (time.time() - self.pingTimer >= 120):
                    # Time to ping
                    self.conn.send(LiveMessage("Ping"))
                    self.pingTimer = time.time()

    def stop(self):
        self.running = False

    def send(self, message):
        self.conn.send(message)
        self.pingTimer = time.time()

    def pushToWeb(self, module, action, data):
        msg = LiveMessage("sendToWeb")
        msg.append(module)
        msg.append(action)
        msg.append(data)
        self.send(msg)

    def __disconnected(self):
        self.email = ''
        self.connected = False
        self.registered = False

        def sendNotification():
            self.observers.liveDisconnected()

        # Syncronize signal with main thread
        Application().queue(sendNotification)

    @staticmethod
    def handler(message):
        def call(fn):
            import sys
            frame = sys._getframe(1)
            frame.f_locals.setdefault('_telldusLiveHandlers',
                                      {}).setdefault(message, []).append(fn)
            return fn

        return call

    def __sendRegisterMessage(self):
        print("Send register")
        msg = LiveMessage('Register')
        msg.append({
            'key': self.conn.publicKey,
            'mac': TelldusLive.getMacAddr(Board.networkInterface()),
            'secret': Board.secret(),
            'hash': 'sha1'
        })
        msg.append({
            'protocol': 2,
            'version': Board.firmwareVersion(),
            'os': 'linux',
            'os-version': 'telldus'
        })
        self.conn.send(msg)

    @staticmethod
    def getMacAddr(ifname):
        addrs = netifaces.ifaddresses(ifname)
        try:
            mac = addrs[netifaces.AF_LINK][0]['addr']
        except IndexError, KeyError:
            return ''
        return mac.upper().replace(':', '')
Exemplo n.º 2
0
class MainApp(QMainWindow):
    def __init__(self, nets=[]):
        super().__init__()

        self.imgToPredict = None
        self.imgToPredictClass = None
        self.imgPredictedClass = None
        self.imgTrueClassLabel = QLabel()
        self.imgPredictedClassLabel = QLabel()

        self.model = convModel()
        self.nets = nets

        host = 'localhost'
        serverPort = getServerPort()
        self.clientsInNet = getClientsNumber()
        self.firstPort = getTesterPort()

        self.serverConnection = ServerConnection(host, serverPort, serverPort + 1)

        self.clients = []
        self.accBtns = []
        for i in range(self.clientsInNet):
            self.clients.append(ClientConnection('client-' + str(i), self.firstPort + (i * 2),
                                                 self.firstPort + (i * 2) + 1, self))

        for client in self.clients:
            client.start()

        self.setWindowTitle('Federated learning controller')

        self.mainWidget = QWidget()

        self.setCentralWidget(self.mainWidget)

        qss_file = open('style.qss').read()
        self.centralWidget().setStyleSheet(qss_file)

        self.layout = QGridLayout()
        self.layout.setAlignment(Qt.AlignTop)

        self.mainWidget.setLayout(self.layout)

        self.__addDropdown(nets)
        self.addClientInfo()
        self.__addImageFrame()
        self.addTrainButton()
        self.addPredictImage()

        self.serverConnection.addQtControls(self.preTrainVal, self.postTrainVal, self.trainBtn, self.netBtn,
                                                self.accBtns, self.downloadBtn, self.currentModel, self.modelDownloadedAcc)
        self.serverConnection.addModelRef(self.model)
        self.serverConnection.setCallbacks(self.imageIsSet, lambda: self.predictChangeState(True))
        self.serverConnection.start()

        self.disableButtons()

        self.show()

    def addClientInfo(self):
        clientWidget = QWidget()
        clientLayout = QVBoxLayout()
        clientWidget.setLayout(clientLayout)
        # clientLayout.setAlignment(Qt.AlignTop)

        clientsInNet = QWidget()
        clientNumberLayout = QHBoxLayout()
        clientNumberLayout.setContentsMargins(0, 0, 0, 0)
        clientsInNet.setLayout(clientNumberLayout)
        clientNumberLayout.addWidget(QLabel("Clients in symulation: " + str(self.clientsInNet)))

        clientLayout.addWidget(clientsInNet)

        for client in self.clients:
            clientLayout.addWidget(self.__addClientPanel(client))

        self.layout.addWidget(clientWidget, 1, 0)

    def addTrainButton(self):
        trainWidget = QWidget()
        trainLayout = QVBoxLayout()
        trainWidget.setLayout(trainLayout)

        trainingDetailsWidget = QWidget()
        trainDetLayout = QHBoxLayout()
        trainingDetailsWidget.setLayout(trainDetLayout)

        preLabel = QLabel('Pre train:')
        self.preTrainVal = QLabel()
        postLabel = QLabel('Post train:')
        self.postTrainVal = QLabel()

        trainDetLayout.addWidget(preLabel)
        trainDetLayout.addWidget(self.preTrainVal)
        trainDetLayout.addWidget(postLabel)
        trainDetLayout.addWidget(self.postTrainVal)

        def handleTrain():
            self.disableButtons()
            for client in self.clients:
                client.setServerStatusText('-')
                client.setAccuracyText('-')
                client.send([ComCodes.RETRAIN_MODEL])

        ########################################################### Add click event! Done
        btnWidget = QWidget()
        btnLayout = QHBoxLayout()
        btnLayout.setContentsMargins(0, 0, 0, 0)
        btnWidget.setLayout(btnLayout)
        self.trainBtn = QPushButton('Train')
        self.trainBtn.setFixedWidth(100)
        self.trainBtn.clicked.connect(handleTrain)
        btnLayout.addWidget(self.trainBtn)

        trainLayout.addWidget(QLabel('Accuracy:'))
        trainLayout.addWidget(trainingDetailsWidget)
        trainLayout.addWidget(btnWidget)

        self.layout.addWidget(trainWidget, 3, 0)

    def addPredictImage(self):
        predictWidget = QWidget()
        predictLayout = QVBoxLayout()
        predictLayout.setAlignment(Qt.AlignTop)

        predictWidget.setLayout(predictLayout)

        resultWidget = QWidget()
        resultLayout = QHBoxLayout()
        resultWidget.setLayout(resultLayout)

        trueClass = QLabel('True: ')
        predictedClass = QLabel('Predicted: ')
        resultLayout.addWidget(trueClass)
        resultLayout.addWidget(self.imgTrueClassLabel)
        resultLayout.addWidget(predictedClass)
        resultLayout.addWidget(self.imgPredictedClassLabel)

        def predict():
            im = self.pixmapToPIL()
            prediction = self.model.predict(im)
            self.imgPredictedClassLabel.setText(prediction)

        btnWidget = QWidget()
        btnWidget.setFixedWidth(255)
        btnLayout = QHBoxLayout()
        btnLayout.setContentsMargins(0, 0, 0, 0)
        btnWidget.setLayout(btnLayout)
        self.predictBtn = QPushButton('Predict')
        self.predictBtn.clicked.connect(predict)
        self.predictBtn.setFixedWidth(100)
        self.predictBtn.setEnabled(False)
        btnLayout.addWidget(self.predictBtn)

        predictLayout.addWidget(QLabel('Class:'))
        predictLayout.addWidget(resultWidget)
        predictLayout.addWidget(btnWidget)

        self.layout.addWidget(predictWidget, 3, 1)

    def __addDownloadModel(self):
        downloadWidget = QWidget()
        downloadLayout = QVBoxLayout()
        downloadLayout.setAlignment(Qt.AlignTop)
        downloadWidget.setLayout(downloadLayout)
        downloadWidget.setFixedWidth(255)
        downloadLayout.setContentsMargins(0, 0, 0, 0)

        downloadLayout.addWidget(QLabel('Model:'))

        modelDetailsWidget = QWidget()
        modelDetailsLayout = QHBoxLayout()
        modelDetailsWidget.setLayout(modelDetailsLayout)

        modelDetailsLayout.addWidget(QLabel('Current: '))
        self.currentModel = QLabel('-')
        modelDetailsLayout.addWidget(self.currentModel)

        modelDetailsLayout.addWidget(QLabel('Accuracy:'))
        self.modelDownloadedAcc = QLabel('-')
        modelDetailsLayout.addWidget(self.modelDownloadedAcc)

        def download():
            self.serverConnection.send([ComCodes.GET_STRUCTURE])

        ################################################################ Add event!
        self.downloadBtn = QPushButton('Download')
        self.downloadBtn.setFixedWidth(100)
        self.downloadBtn.clicked.connect(download)
        downloadBtnWidget = QWidget()
        downloadBtnLayout = QHBoxLayout()
        downloadBtnWidget.setLayout(downloadBtnLayout)
        downloadBtnLayout.addWidget(self.downloadBtn)

        downloadLayout.addWidget(modelDetailsWidget)
        downloadLayout.addWidget(downloadBtnWidget)

        return downloadWidget

    def __addClientPanel(self, conn):

        panel = QWidget()
        panelLayout = QVBoxLayout()
        panelLayout.setContentsMargins(0, 5, 0, 0)
        panelLayout.setAlignment(Qt.AlignTop)
        panel.setLayout(panelLayout)

        nameWidget = QWidget()
        nameLayout = QHBoxLayout()
        nameWidget.setLayout(nameLayout)
        nameLayout.setContentsMargins(0, 0, 0, 0)
        nameLayout.setAlignment(Qt.AlignTop)

        name = QLabel(conn.getName())
        server = QLabel('Server:')
        self.serverStatus = QLabel('-')
        nameLayout.addWidget(name)
        nameLayout.addWidget(server)
        nameLayout.addWidget(self.serverStatus)

        connection = QLabel('Connection: ' + conn.getConnectionDetails())

        accWidget = QWidget()
        accLayout = QHBoxLayout()
        accLayout.setContentsMargins(0, 0, 0, 0)
        accWidget.setLayout(accLayout)

        accuracy = QLabel('Accuracy: -')
        accLayout.addWidget(accuracy)

        conn.setQLabels(accuracy, self.serverStatus)

        getAccBtn = QPushButton('Update model')
        getAccBtn.setFixedWidth(100)
        getAccBtn.clicked.connect(lambda: conn.send([ComCodes.GET_ACCURACY]))
        accLayout.addWidget(getAccBtn)
        self.accBtns.append(getAccBtn)

        bottomLine = QFrame()
        bottomLine.setFixedHeight(1)
        bottomLine.setFrameStyle(1)

        panelLayout.addWidget(nameWidget)
        panelLayout.addWidget(connection)
        panelLayout.addWidget(accWidget)
        panelLayout.addWidget(bottomLine)

        return panel

    def __addDropdown(self, options):
        netSelect = QWidget()
        dropdownLayout = QHBoxLayout()
        # dropdownLayout.setAlignment(Qt.AlignTop)
        dropdownLayout.setContentsMargins(0, 0, 0, 0)
        netSelect.setFixedHeight(30)
        netSelect.setLayout(dropdownLayout)

        netLabel = QLabel("Selected network: ")
        netLabel.setFixedWidth(100)
        dropdownLayout.addWidget(netLabel)

        netsDropdown = QComboBox()
        netsDropdown.addItems(options)
        netsDropdown.setFixedWidth(50)
        dropdownLayout.addWidget(netsDropdown)

        def handleSetNet(net):
            self.disableButtons()
            print('sending')
            self.serverConnection.send([ComCodes.LOAD_MODEL, net])

        ############################################################# Add click event!
        self.netBtn = QPushButton("Set/ Reset Net")
        self.netBtn.setFixedWidth(100)
        self.netBtn.clicked.connect(lambda: handleSetNet(netsDropdown.currentText()))
        dropdownLayout.addWidget(self.netBtn)

        self.layout.addWidget(netSelect, 0, 0)

    def __addImageFrame(self):
        imageWidget = QWidget()
        widgetLayout = QVBoxLayout()
        widgetLayout.setAlignment(Qt.AlignTop)
        imageWidget.setLayout(widgetLayout)
        widgetLayout.addWidget(QLabel('Image to predict:'))

        self.imgFrame = QFrame()
        self.imgFrame.setFrameStyle(1)
        self.imgFrame.setFixedWidth(255)
        self.imgFrame.setFixedHeight(255)
        imgFrameLayout = QGridLayout()
        imgFrameLayout.setContentsMargins(0, 0, 0, 0)
        self.imgFrame.setLayout(imgFrameLayout)
        widgetLayout.addWidget(self.imgFrame)

        self.image = QLabel()
        self.__showImage()
        imgFrameLayout.addWidget(self.image)

        imageBtnWidget = QWidget()
        imageBtnWidget.setFixedWidth(255)
        imageBtnLayout = QHBoxLayout()
        imageBtnWidget.setLayout(imageBtnLayout)

        loadImageBtn = QPushButton("Open Image")
        loadImageBtn.setFixedWidth(100)
        loadImageBtn.clicked.connect(self.loadImg)
        imageBtnLayout.addWidget(loadImageBtn)

        clearImageBtn = QPushButton("Clear Image")
        clearImageBtn.setFixedWidth(100)
        clearImageBtn.clicked.connect(self.__clearImage)
        imageBtnLayout.addWidget(clearImageBtn)

        download = self.__addDownloadModel()

        widgetLayout.addWidget(imageBtnWidget)
        widgetLayout.addWidget(download)
        self.layout.addWidget(imageWidget, 0, 1, 2, 2)

    def setImgClass(self, classLabel):
        self.imgToPredictClass = classLabel
        if classLabel is None:
            self.imgTrueClassLabel.setText('-')
        else:
            self.imgTrueClassLabel.setText(classLabel)
        self.imgPredictedClassLabel.setText('-')

    def __showImage(self):
        if self.imgToPredict is not None and self.imgToPredict != '':
            self.image.setPixmap(QPixmap(self.imgToPredict).scaled(255, 255))
            iClass = self.imgToPredict.split('/')
            iClass = iClass[len(iClass) - 2]
            self.setImgClass(iClass)
        else:
            self.setImgClass(None)
            self.image.setText('No image selected.')
            self.image.setAlignment(Qt.AlignCenter)

    def pixmapToPIL(self):
        pmap = self.image.pixmap()
        imageBuffer = QBuffer()
        imageBuffer.open(QBuffer.ReadWrite)
        pmap.save(imageBuffer, "PNG")
        img = Image.open(io.BytesIO(imageBuffer.data()))
        return img

    def loadImg(self):
        img = QFileDialog.getOpenFileName(self, 'Open File', r'C:\Users\Pawel\Studia\inz\COVID-19 Radiography Database',
                                          'Image files (*.png *.jpg)')
        self.imgToPredict = img[0]
        if self.currentModel != '-':
            self.predictChangeState(True)
        self.__showImage()

    def __clearImage(self):
        self.imgToPredict = None
        self.predictChangeState(False)
        self.__showImage()

    def imageIsSet(self):
        return self.imgToPredict is not None

    def disableUpdateBtns(self):
        for btn in self.accBtns:
            btn.setEnabled(False)

    def disableButtons(self):
        self.disableUpdateBtns()
        self.trainBtn.setEnabled(False)
        self.netBtn.setEnabled(False)
        self.downloadBtn.setEnabled(False)

    def predictChangeState(self, state):
        self.predictBtn.setEnabled(state)