예제 #1
0
파일: comm.py 프로젝트: dodotronix/FDI-ANT
class Comm():
    def __init__(self, address, port):
        self.block = 0
        self.port = port
        self.delimiter = bytes('x', 'utf-8')
        self.address = address
        self.block = bytearray()
        self.initialize(address, port)

    def initialize(self, address, port):
        self.socket = QTcpSocket()
        self.socket.connectToHost(self.address, self.port)

    def decode(self, data):
        return data.decode('utf-8').replace('\x00', '').rsplit()

    def read(self):
        self.size = self.socket.bytesAvailable()
        self.block += self.socket.read(self.size)

    def get_data(self):
        if (self.delimiter in self.block):
            data = self.block[0:self.block.index(self.delimiter)]
            data = list(map(int, self.decode(data)))
            self.block = self.block[self.block.index(self.delimiter) + 1:-1]
            return data

    def send(self, data):
        self.socket.write(bytearray(data, 'utf-8'))

    def disconnect(self):
        self.socket.close()
예제 #2
0
    def exchangeData(self):

        if not checkIPAddress(ip_line_edit.text()):
            raise Exception("ERROR IP-address format")

        tcp_socket = QTcpSocket()
        tcp_socket.connectToHost(ip_line_edit.text(), 80, QIODevice.ReadWrite)
        self.update.emit(
            f"Connecting to {tcp_socket.peerAddress().toString()}:{tcp_socket.peerPort()}"
        )

        if not tcp_socket.waitForConnected(5000):
            raise Exception(f"ERROR connecting to {ip_line_edit.text()}:80")

        tcp_socket.waitForReadyRead(5000)
        arduino_state: bytes = b""
        while tcp_socket.bytesAvailable() > 0:
            arduino_state += tcp_socket.readAll().data()
        print(arduino_state)

        arduino_state = arduino_state.decode()
        if ("+" not in arduino_state):
            raise Exception(f"ERROR incomplete read")

        self.updateState(arduino_state)

        tcp_socket.write((self.getState() + "+\n").encode("utf-8"))
        tcp_socket.flush()

        if tcp_socket.bytesToWrite() > 0:
            raise Exception(f"ERROR incomplete write")

        tcp_socket.disconnectFromHost()
        tcp_socket.close()
예제 #3
0
    def __init__(self, sock_type='TCP Client', ip='127.0.0.1', port=2007):
        '''打开网络设备,建立连接
        ## sock_type:
           - 'TCP Client'
           - 'TCP Server'
           - 'UDP'
        '''
        self.sock_type = sock_type
        # self.ip = ip
        self.port = port

        if sock_type == 'TCP Client':
            tcp_client = QTcpSocket()
            tcp_client.connectToHost(ip, port)
            self.sock = tcp_client
        elif sock_type == 'TCP Server':
            tcp_server = QTcpServer()
            tcp_server.listen(QHostAddress(ip), port)
            self.sock = tcp_server

        elif sock_type == 'UDP':
            udp = QUdpSocket()
            udp.bind(QHostAddress(ip), port)
            self.sock = udp
        else:
            print('Unkonw sock_type=%r' % sock_type)
예제 #4
0
        def get_ip_mac_pinged(ip):
            """
                Returns a list  [ip,mac,pinged]
            """
            pinged = True
            mac = None
            sock = QTcpSocket()
            sock.connectToHost(ip, 80)
            sock.close()

            #ARP
            if pinged == True:
                if platform_system() == "Windows":
                    CREATE_NO_WINDOW = 0x08000000
                    arpexit = subprocess.check_output(
                        ["arp", "-a", ip], creationflags=CREATE_NO_WINDOW)
                    for s in arpexit.split(b" "):
                        if len(s) == 17 and s.find(b"-") != -1:
                            mac = s.decode().replace("-", ":").upper()
                else:
                    arpexit = subprocess.check_output(["arp", ip])
                    for s in arpexit.decode('utf-8').split(" "):
                        if len(s) == 17 and s.find(":") != -1:
                            mac = s.upper()
            return (ip, mac, pinged)
예제 #5
0
class TcpClient(QWidget):
    recvDataReady = pyqtSignal(bytes)

    def __init__(self):
        super(TcpClient, self).__init__()
        self.tcpClient = QTcpSocket()
        self.initUI()
        # self.signalSlot()

    def initUI(self):
        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.paraUI())
        self.setLayout(mainLayout)

    def paraUI(self):
        groupBox = QGroupBox('参数设置')
        # self.masterIP = QLineEdit('192.168.1.166')
        self.serverIP = QLineEdit('192.168.0.1')
        self.serverIP.setInputMask('000.000.000.000')
        self.serverIP.setToolTip('需要连接到Server的IP地址')

        self.serverPort = QLineEdit('2111')
        self.serverPort.setToolTip('需要连接到Server的端口')

        form = QFormLayout()
        form.addRow('Server IP地址:', self.serverIP)
        form.addRow('Server 端口号:', self.serverPort)

        self.linkRbtn = QRadioButton()

        mainLayout = QVBoxLayout()
        mainLayout.addLayout(form)
        mainLayout.addWidget(self.linkRbtn)
        mainLayout.addStretch(1)
        mainLayout.setAlignment(self.linkRbtn, Qt.AlignHCenter)

        groupBox.setLayout(mainLayout)
        return groupBox

    #
    # def signalSlot(self):
    #     self.linkRbtn.clicked.connect(self.ctrlTcpStatus)
    #     self.linkRbtn.clicked.connect(self.currentStatus)
    #     self.tcpClient.connected.connect(self.hasConnected)
    #     self.tcpClient.disconnected.connect(self.hasClosed)
    #     self.tcpClient.readyRead.connect(self.processTcpClientDatagrams)

    @pyqtSlot()
    def ctrlTcpStatus(self):
        if self.linkRbtn.isChecked():
            # self.tcpClient.connectToHost(self.serverIP.text(), int(self.serverPort.text()))
            self.tcpClient.connectToHost('192.168.0.1', 2111,
                                         QIODevice.ReadWrite)
            self.tcpClient.waitForConnected(1000)
        else:
            self.tcpClient.disconnectFromHost()
예제 #6
0
class TcpClient(QObject):
    finished = pyqtSignal()
    connected = pyqtSignal()
    connectionLost = pyqtSignal()
    interpretCmd = pyqtSignal(str)

    def __init__(self):
        super(TcpClient, self).__init__()
        self.__tcp_socket = None
        self.connectionLost.connect(self.finished)
        self.connectionLost.connect(
            lambda: print('## Disconnected from the robot ##'))

    @pyqtSlot()
    def start_client(self):
        print(f'## Connecting to robot at IP: {WIFI_IP}, PORT: {WIFI_PORT} ##')
        self.__tcp_socket = QTcpSocket()
        self.__tcp_socket.disconnected.connect(self.connectionLost)
        self.__tcp_socket.readyRead.connect(self.read_ready)
        self.__tcp_socket.connected.connect(self.connected)
        self.__tcp_socket.connectToHost(WIFI_IP, WIFI_PORT)
        if not self.__tcp_socket.waitForConnected(TIMEOUT_MSEC):
            print(
                f'## Timeout! {TIMEOUT_MSEC/1000}s has passed and it still hasn\'t connect ##'
            )
            self.__tcp_socket.disconnectFromHost()
            self.finished.emit()
        else:
            print(
                f'## Connected to robot at IP: {WIFI_IP}, PORT: {WIFI_PORT} ##'
            )

    def stop_client(self):
        if self.__tcp_socket is not None:
            self.__tcp_socket.disconnectFromHost()
            self.finished.emit()

    @pyqtSlot()
    def read_ready(self):
        try:
            data = self.__tcp_socket.readAll()
            self.interpretCmd.emit(str(data, "utf-8").strip())
        except Exception as err:
            print(f'tcpClient::read_ready() error msg: {err}')

    @pyqtSlot(str)
    def send_message(self, payload):
        try:
            # Example message: 'FP|tr'
            # self.__tcp_socket.write(QByteArray().append(json.dumps({'target': 'ARD', 'payload': 'hi'})))
            self.__tcp_socket.write(QByteArray().append(payload))
            # self.__tcp_socket.flush()
        except Exception as err:
            print(f'tcpClient::send_message() error msg: {err}')
예제 #7
0
    def connect(self, host, port):
        if self._server:
            raise RuntimeError(
                'MeetingServer: Must call either listen, or connect, not both')
        from PyQt5.QtNetwork import QTcpSocket
        socket = QTcpSocket()

        def socket_error(error_type, self=self, socket=socket):
            self._socket_error(error_type, socket)

        socket.error.connect(socket_error)
        socket.connectToHost(host, port)
        self._add_connection(socket)
        self._session.logger.status('Waiting for scene data from meeting host')
예제 #8
0
class SocketTest(QObject):
    def __init__(self, parent=None):
        super(SocketTest, self).__init__(parent)

    def connect(self):
        self.socket = QTcpSocket(self)

        self.socket.connectToHost(IP, PORT)

        if self.socket.waitForConnected(3000):
            print('Connected')

            self.socket.waitForReadyRead(3000)
            print(self.socket.bytesAvailable(), self.socket.readAll())

        else:
            print('Not Connected')
예제 #9
0
class TcpClient(QWidget, Ui_Form):
    def __init__(self):
        super(TcpClient, self).__init__()
        self.ui = Ui_Form()
        self.ui.setupUi(self)

        self.tcpSocket = QTcpSocket(self)
        self.ui.connectButton.clicked.connect(self.buttonConnect)
        self.tcpSocket.connected.connect(self.sucessConnect)
        self.ui.sendButton.clicked.connect(self.sendMessage)
        self.tcpSocket.readyRead.connect(self.showMessage)
        self.ui.closeButton.clicked.connect(self.closeConnect)

    def buttonConnect(self):
        ip = self.ui.IPLineEdit.text()
        port = self.ui.portLineEdit.text()
        self.tcpSocket.connectToHost(QHostAddress(ip), int(port))

    def sucessConnect(self):
        self.ui.showText.setText("成功和服务器建立连接")

    def sendMessage(self):
        message = self.ui.sendText.toPlainText()
        # self.communication = QByteArray()
        # stream = QDataStream(self.communication, QIODevice.WriteOnly)
        # stream.writeQString(message)
        # self.tcpSocket.write(self.communication)
        # self.ui.sendText.clear()
        message = message.encode(encoding='utf-8')
        self.tcpSocket.write(message)
        self.ui.sendText.clear()

    def showMessage(self):
        # stream = QDataStream(self.tcpSocket)
        # stream.setVersion(QDataStream.Qt_5_10)
        # message = stream.readQString()
        # self.ui.showText.append(message)
        self.message = QByteArray()
        self.message = self.tcpSocket.readAll()
        self.message = str(self.message, encoding='utf-8')  #找遍世界,终于找到可用的方法
        print(self.message)
        self.ui.showText.append(self.message)

    def closeConnect(self):
        self.tcpSocket.disconnectFromHost()
        self.tcpSocket.close()
예제 #10
0
class MyClientThread(QThread):
    def __init__(self, ip, port):
        super(MyClientThread, self).__init__()
        self.ip = ip
        self.port = port

    def run(self):
        print("新连接进入")
        self.clientSocket = QTcpSocket()

        self.clientSocket.connectToHost(QHostAddress(self.ip), self.port)
        clientSocketList.append((self.clientSocket, self.ip, self.port))
        self.clientSocket.connected.connect(lambda: print("连接成功"))

        self.clientSocket.readyRead.connect(lambda:self.handle_read(self.clientSocket),Qt.DirectConnection)

        self.clientSocket.disconnected.connect(self.dealDisconnected,Qt.DirectConnection)
        self.exec()

    def handle_read(self,socket):
        msg = socket.readAll()
        print(msg)
        self.handle_write()

    def handle_write(self):
        for socket, ip, port in clientSocketList:
            socket.write("郑兵".encode("utf-8"))

    def handle_runing_single(self, str):
        print(str)

    def dealDisconnected(self):
        print("断开连接")
        self.clientSocket.disconnectFromHost()
        self.clientSocket.close()
        self.clientSocket.deleteLater()

    def winClose(self):
        print("主窗口关闭了")
        for socket,ip,port in clientSocketList:
            print(socket)
        # self.clientSocket.disconnectFromHost()
        # self.clientSocket.close()
        # self.deleteLater()
        clientSocketList.clear()
예제 #11
0
    class TcpClient(QObject):
        def __init__(self, socket=None):
            super(TcpClient, self).__init__()
            self.is_connected = False
            if socket is None:
                self.socket = QTcpSocket()
            else:
                self.socket = socket
            self.socket.error.connect(self.error)
            self.socket.connected.connect(self.connected)
            self.socket.disconnected.connect(self.disconnected)
            self.socket.readyRead.connect(self.readyRead)

        @pyqtSlot()
        def error(self):
            print self.socket.errorString()

        @pyqtSlot()
        def connected(self):
            self.is_connected = True
            print 'TcpClient connected'

        @pyqtSlot()
        def disconnected(self):
            self.is_connected = False
            print 'TcpClient disconnected'

        @pyqtSlot()
        def readyRead(self):
            data = self.socket.readAll()
            self.parse_data(data)

        def connectToHost(self, host, port):
            print 'Trying to connect to host', host, 'at port', port
            self.socket.connectToHost(host, port)

        def disconnectFromHost(self):
            self.socket.disconnectFromHost()

        def write(self, buf):
            self.socket.write(buf)

        def parse_data(self, data):
            # Placeholder function; override it with your own implementation
            print str(data).strip()
예제 #12
0
class Client(QObject):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.log = logging.getLogger(__name__)
        self._socket_setup()

    def _socket_setup(self):
        self.socket = QTcpSocket(self)
        self.socket.setSocketOption(QTcpSocket.KeepAliveOption, 1)

        self.socket.connected.connect(self.on_connected)
        self.socket.disconnected.connect(self.on_disconnected)
        self.socket.readyRead.connect(self.on_readyRead)
        self.socket.error.connect(self.on_error)
        self.socket.stateChanged.connect(self.on_stateChanged)

    def connect(self, host=HOST, port=PORT):
        if not self.socket.isOpen():
            self.log.info('connecting to {}:{}'.format(host, port))
            self.socket.connectToHost(QHostAddress(host), port)

    def disconnect(self):
        self.log.info('disconnecting')
        self.socket.disconnectFromHost()

    def on_readyRead(self):
        data = bytes()
        while self.socket.bytesAvailable():
            data += self.socket.read(1024)

        self.log.debug(data)

    def on_connected(self):
        self.log.info('connected')

    def on_disconnected(self):
        self.log.info('disconnected')

    def on_error(self, error):
        self.log.error('error {}: {}'.format(error, self.socket.errorString()))

    def on_stateChanged(self, state):
        states = ['Unconnected', 'HostLookup', 'Connecting', 'Connected', 'Bound', 'Closing', 'Listening']
        self.log.debug('state changed to {}'.format(states[state]))
예제 #13
0
class TcpClient():
    
    def __init__(self, line_edit_widget=None, text_widget=None):
        self.line_edit = line_edit_widget
        self.text_widget = text_widget
        self.socket = QTcpSocket()      # client "is a" socket


    def connect_server(self):
        print('inside connect_server')
        print('Port is: ' + str(SERVER_PORT))
        self.socket.connectToHost(SERVER_ADDRESS, SERVER_PORT)


    def write_data(self):
        data_byte_array = QByteArray()
        stream = QDataStream(data_byte_array, QIODevice.WriteOnly)
        stream.setVersion(QDataStream.Qt_5_9)   
        stream.writeUInt32(0)
        if self.line_edit:
            print('inside write_data')
            stream.writeQString(self.line_edit.text())
            
        self.socket.write(data_byte_array)
        data_byte_array = None
        if self.line_edit:
            self.line_edit.setText("")
        
        
    def read_data(self):
        stream = QDataStream(self.socket)
        stream.setVersion(QDataStream.Qt_5_9)   

        while True:
            if self.socket.bytesAvailable() <= 0:
                break
            stream.readUInt32()
            text_from_server = stream.readQString()
            if self.text_widget:
                print('display_text')
                print(text_from_server)
                self.text_widget.append(text_from_server)
예제 #14
0
def send(message='ping 1234', port=PORT):
    ''' Sends a raw message

        Trick here is that PyQt5 does not do automatic str<->byte encoding, but pya does. Also something weird with the addresses
    '''
    payload = message + '\r\n'
    psock = QTcpSocket()
    if not isGSI():
        payload = payload.encode()
    psock.connectToHost(localhost, port)
    if psock.waitForConnected():
        psock.write(payload)
        if psock.waitForReadyRead(3000):
            ret = psock.readLine()
            if not isGSI():
                ret = bytes(ret).decode('utf-8')
            handle_query(ret)
        else:
            raise Exception('Not acknowledged')
    else:
        print('Connection Fail! (tried {}:{})'.format(localhost, port))
예제 #15
0
    def run(self):
        self.mutex.lock()
        serverName = self.hostName
        serverPort = self.port
        self.mutex.unlock()

        while not self.quit:
            Timeout = 5 * 1000

            socket = QTcpSocket()
            socket.connectToHost(serverName, serverPort)

            if not socket.waitForConnected(Timeout):
                self.error.emit(socket.error(), socket.errorString())
                return

            while socket.bytesAvailable() < 2:
                if not socket.waitForReadyRead(Timeout):
                    self.error.emit(socket.error(), socket.errorString())
                    return 

            instr = QDataStream(socket)
            instr.setVersion(QDataStream.Qt_4_0)
            blockSize = instr.readUInt16()

            while socket.bytesAvailable() < blockSize:
                if not socket.waitForReadyRead(Timeout):
                    self.error.emit(socket.error(), socket.errorString())
                    return

            self.mutex.lock()
            fortune = instr.readQString()
            self.newFortune.emit(fortune)

            self.cond.wait(self.mutex)
            serverName = self.hostName
            serverPort = self.port
            self.mutex.unlock()
예제 #16
0
    def run(self):
        self.mutex.lock()
        serverName = self.hostName
        serverPort = self.port
        self.mutex.unlock()

        while not self.quit:
            Timeout = 5 * 1000

            socket = QTcpSocket()
            socket.connectToHost(serverName, serverPort)

            if not socket.waitForConnected(Timeout):
                self.error.emit(socket.error(), socket.errorString())
                return

            while socket.bytesAvailable() < 2:
                if not socket.waitForReadyRead(Timeout):
                    self.error.emit(socket.error(), socket.errorString())
                    return

            instr = QDataStream(socket)
            instr.setVersion(QDataStream.Qt_4_0)
            blockSize = instr.readUInt16()

            while socket.bytesAvailable() < blockSize:
                if not socket.waitForReadyRead(Timeout):
                    self.error.emit(socket.error(), socket.errorString())
                    return

            self.mutex.lock()
            fortune = instr.readQString()
            self.newFortune.emit(fortune)

            self.cond.wait(self.mutex)
            serverName = self.hostName
            serverPort = self.port
            self.mutex.unlock()
예제 #17
0
class Client(QWidget, Ui_Form):
    def __init__(self):
        super(Client, self).__init__()
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.file = QFile()

        self.tcpsocket = QTcpSocket()
        self.ui.pushButton_Connect.clicked.connect(self.ConnectToServer)
        self.tcpsocket.connected.connect(self.SuccessConnect)
        self.tcpsocket.readyRead.connect(self.HandleReceive)

    def ConnectToServer(self):
        ip = self.ui.lineEdit_IPAddress.text()
        port = self.ui.lineEdit_PORT.text()
        self.tcpsocket.connectToHost(QHostAddress(ip), int(port))

    def SuccessConnect(self):
        self.ui.textEdit.setText("成功和服务器建立连接")

    def HandleReceive(self):
        with open('../FileRecv/test.txt', 'wb') as f:
            buf = self.tcpsocket.readAll()
            f.write(buf)
예제 #18
0
class Messenger(Messenger_Window):
    RANDOM_MESSAGES = ('Hello', 'How are you?', 'Hi there!',
                       'I’m fine, and you?', 'Your problems – my problems.',
                       'Hello, I’m awesome. How can I help you?', 'What’s up?',
                       'I was so bored. Thank you for saving me!',
                       'I’ve been expecting you!')

    def __init__(self, host, port):
        super().__init__()
        self.tcpSocket = QTcpSocket()
        self.blockSize = 0
        self.host = host
        self.port = port
        self.jim = None
        self.connected = False
        self.chat_list = []
        self.online_users = []
        self.active_chat = ''
        self.logon()

        # self.last_sent_message = ''

    def reset_connection(self):
        if self.connected:
            self.tcpSocket.disconnect()
        self.jim = None
        self.connected = False
        self.chat_list = []
        self.online_users = []
        self.active_chat = ''
        self.enable_server_buttons(False)
        self.enable_communication_buttons(False)
        self.setWindowTitle('My awesome client: disconnected')
        self.chat_label.setText('Disconnected')

    def debug(self):
        print('chat_list=' + ','.join(self.chat_list))
        print('online_users=' + ','.join(self.online_users))
        print('active_chat={}'.format(self.active_chat))
        try:
            print('username={}'.format(self.jim.username))
        except:
            print('username is none')
        print('connected={}'.format(self.connected))

    def logon(self):
        if self.connected:
            self.tcpSocket.disconnect()
        username, ok = QInputDialog.getText(self, 'Logon to chat',
                                            'Enter your name:',
                                            QLineEdit.Normal, 'Nastya')
        if ok:
            self.jim = JimClient(username)
            self.enable_server_buttons(True)
            self.enable_communication_buttons(False)
            self.setWindowTitle(
                'My awesome client: connected as {}'.format(username))
            self.tcpSocket.connectToHost(self.host, self.port,
                                         QIODevice.ReadWrite)
            # self.tcpSocket.waitForConnected()
            self.chat_label.setText('Please join chat...')
            self.tcpSocket.readyRead.connect(self.read_messages)
            self.tcpSocket.error.connect(self.display_error)
            # self.tcpSocket.write(self.jim.auth())
            self.tcpSocket.write(self.jim.presence())
            self.connected = True
            # self.tcpSocket.write(self.jim.request_chat_list())
            self.chat_area.clear()
        else:
            self.reset_connection()

    def before_exit(self):
        print('Exiting!')
        if self.jim:
            msg = self.jim.quit()
            self.tcpSocket.write(msg)
            time.sleep(5)
            print('Exiting! Message length is {}, message={}'.format(
                len(msg), msg))
        if self.connected:
            self.tcpSocket.disconnectFromHost()

    def dialog_join_chat(self):
        # print(self.chat_list)
        if self.connected:
            chat, ok = QInputDialog.getItem(self, 'Доступные чаты',
                                            'Выберите чат', self.chat_list, 0,
                                            False)
            if ok and chat:
                self.chat_label.setText('Active Chat: ' + chat)
                msg = self.jim.join_chat(chat)
                self.tcpSocket.write(msg)
                self.chat_area.clear()
                self.enable_communication_buttons(True)
                self.active_chat = chat

    def dialog_contact_user(self):
        # print(self.chat_list)
        if self.connected:
            user, ok = QInputDialog.getItem(self, 'Пользователи онлайн',
                                            'Выберите пользователя',
                                            self.online_users, 0, False)
            if ok and user:
                self.chat_label.setText('Dialog with ' + user)
                self.chat_area.clear()
                self.enable_communication_buttons(True)
                self.active_chat = user

    def random_message(self):
        message = self.RANDOM_MESSAGES[random.randint(
            0,
            len(self.RANDOM_MESSAGES) - 1)]
        self.message_area.clear()
        self.message_area.setText(message)
        self.send()

    def read_messages(self):
        data = self.tcpSocket.readAll().data()
        if data:
            received_messages = self.jim.unpack(data)
            for msg in received_messages:
                server_resp = self.jim.parse_server_message(msg)
                if 'response' in server_resp:
                    print('received server message {} "{}"'.format(
                        server_resp['response'], server_resp['alert']))
                    if server_resp['response'] in (200, 201):  # everything OK
                        # self.chat_area.append(time.strftime("%Y-%m-%d %H:%M", time.localtime(server_resp['time'])))
                        # self.chat_area.append('{}: {}'.format(self.jim.username, self.last_sent_message))
                        pass
                    elif server_resp['response'] == 203:  # a user is online
                        if not server_resp['username'] in self.online_users:
                            self.online_users.append(server_resp['username'])
                    elif server_resp[
                            'response'] == 204:  # a user has joined chat
                        if self.active_chat == server_resp['chat']:
                            # redColor = QColor(255, 0, 0)
                            # blackColor = QColor(0, 0, 0)
                            # tmpFont = QFont('Arial', pointSize=10, weight=400)
                            # self.chat_area.setTextColor(redColor)
                            # self.chat_area.setFont(tmpFont)
                            self.chat_area.append(
                                time.strftime(
                                    "%Y-%m-%d %H:%M",
                                    time.localtime(server_resp['time'])))
                            self.chat_area.append(
                                '{} has joined this chat'.format(
                                    server_resp['username']))
                            # self.chat_area.setFont(self.font)
                            # self.chat_area.setTextColor(blackColor)
                    elif server_resp['response'] == 215:
                        # received chat list
                        self.chat_list = server_resp['chat_list'].split(',')
                    elif server_resp['response'] == 216:
                        # received users list
                        self.online_users = server_resp['user_list'].split(',')
                    elif server_resp['response'] >= 400:
                        # received an error
                        self.chat_area.append(
                            time.strftime("%Y-%m-%d %H:%M",
                                          time.localtime(server_resp['time'])))
                        self.chat_area.append(server_resp['alert'])
                elif 'message' in server_resp:
                    # received a message
                    if self.chat_area.toPlainText(
                    ) == 'В чат пока ничего не написали':
                        self.chat_area.clear()
                    # display if it is a history message
                    if 'archive' in server_resp:
                        self.display_message(server_resp)
                    # if message to current chat or dialog then display it
                    elif (server_resp['from'] == self.active_chat and server_resp['to'] == self.jim.username) or \
                            (self.active_chat == server_resp['to']) :
                        self.display_message(server_resp)
                    print('received message {}'.format(server_resp))
                else:
                    print('something wrong in read_messages {}'.format(msg))

    def display_message(self, server_resp):
        self.chat_area.append(
            time.strftime("%Y-%m-%d %H:%M",
                          time.localtime(server_resp['time'])))
        self.chat_area.append('{}: {}'.format(server_resp['from'],
                                              server_resp['message']))

    def display_error(self):
        self.chat_area.append(time.strftime("%Y-%m-%d %H:%M",
                                            time.localtime()))
        self.chat_area.append('Connection error')
        self.reset_connection()

    def send(self):
        # message_html = self.message_area.toHtml()
        message_txt = self.message_area.toPlainText()
        msg_len = len(message_txt)
        if msg_len > 512:
            self.errorMessageDialog.showMessage(
                'Warning: Message {} bytes too long, max 512'.format(msg_len))
        elif not message_txt:
            pass
        else:
            message_json_packed = self.jim.message(self.active_chat,
                                                   message_txt)
            self.tcpSocket.write(message_json_packed)
            if self.active_chat != self.jim.username and self.active_chat in self.online_users:
                self.display_message({
                    'from': self.jim.username,
                    'message': message_txt,
                    'time': time.time()
                })
            self.message_area.clear()
            self.message_area.setFocus()
예제 #19
0
class IrcWidget(QWidget, Ui_IrcWidget):
    """
    Class implementing the IRC window.
    
    @signal autoConnected() emitted after an automatic connection was initiated
    """
    autoConnected = pyqtSignal()
    
    ServerDisconnected = 1
    ServerConnected = 2
    ServerConnecting = 3
    
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (QWidget)
        """
        super(IrcWidget, self).__init__(parent)
        self.setupUi(self)
        
        from .IrcNetworkManager import IrcNetworkManager
        self.__ircNetworkManager = IrcNetworkManager(self)
        
        self.__leaveButton = QToolButton(self)
        self.__leaveButton.setIcon(
            UI.PixmapCache.getIcon("ircCloseChannel.png"))
        self.__leaveButton.setToolTip(
            self.tr("Press to leave the current channel"))
        self.__leaveButton.clicked.connect(self.__leaveChannel)
        self.__leaveButton.setEnabled(False)
        self.channelsWidget.setCornerWidget(
            self.__leaveButton, Qt.BottomRightCorner)
        self.channelsWidget.setTabsClosable(False)
        if not isMacPlatform():
            self.channelsWidget.setTabPosition(QTabWidget.South)
        
        height = self.height()
        self.splitter.setSizes([height * 0.6, height * 0.4])
        
        self.__channelList = []
        self.__channelTypePrefixes = ""
        self.__userName = ""
        self.__identityName = ""
        self.__quitMessage = ""
        self.__nickIndex = -1
        self.__nickName = ""
        self.__server = None
        self.__registering = False
        
        self.__connectionState = IrcWidget.ServerDisconnected
        self.__sslErrorLock = False
        
        self.__buffer = ""
        self.__userPrefix = {}
        
        self.__socket = None
        if SSL_AVAILABLE:
            self.__sslErrorHandler = E5SslErrorHandler(self)
        else:
            self.__sslErrorHandler = None
        
        self.__patterns = [
            # :[email protected] PRIVMSG bar_ :some long message
            (re.compile(r":([^!]+)!([^ ]+)\sPRIVMSG\s([^ ]+)\s:(.*)"),
             self.__query),
            # :foo.bar.net COMMAND some message
            (re.compile(r""":([^ ]+)\s+([A-Z]+)\s+(.+)"""),
             self.__handleNamedMessage),
            # :foo.bar.net 123 * :info
            (re.compile(r""":([^ ]+)\s+(\d{3})\s+(.+)"""),
             self.__handleNumericMessage),
            # PING :ping message
            (re.compile(r"""PING\s+:(.*)"""), self.__ping),
        ]
        self.__prefixRe = re.compile(r""".*\sPREFIX=\((.*)\)([^ ]+).*""")
        self.__chanTypesRe = re.compile(r""".*\sCHANTYPES=([^ ]+).*""")
        
        ircPic = UI.PixmapCache.getPixmap("irc128.png")
        self.__emptyLabel = QLabel()
        self.__emptyLabel.setPixmap(ircPic)
        self.__emptyLabel.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter)
        self.channelsWidget.addTab(self.__emptyLabel, "")
        
        # all initialized, do connections now
        self.__ircNetworkManager.dataChanged.connect(self.__networkDataChanged)
        self.networkWidget.initialize(self.__ircNetworkManager)
        self.networkWidget.connectNetwork.connect(self.__connectNetwork)
        self.networkWidget.editNetwork.connect(self.__editNetwork)
        self.networkWidget.joinChannel.connect(self.joinChannel)
        self.networkWidget.nickChanged.connect(self.__changeNick)
        self.networkWidget.sendData.connect(self.__send)
        self.networkWidget.away.connect(self.__away)
        self.networkWidget.autoConnected.connect(self.autoConnected)
    
    def shutdown(self):
        """
        Public method to shut down the widget.
        
        @return flag indicating successful shutdown (boolean)
        """
        if self.__server:
            if Preferences.getIrc("AskOnShutdown"):
                ok = E5MessageBox.yesNo(
                    self,
                    self.tr("Disconnect from Server"),
                    self.tr(
                        """<p>Do you really want to disconnect from"""
                        """ <b>{0}</b>?</p><p>All channels will be closed."""
                        """</p>""").format(self.__server.getName()))
            else:
                ok = True
            if ok:
                self.__connectNetwork("", False, True)
        else:
            ok = True
        
        if ok:
            self.__ircNetworkManager.close()
        
        return ok
    
    def autoConnect(self):
        """
        Public method to initiate the IRC auto connection.
        """
        self.networkWidget.autoConnect()

    def __connectNetwork(self, name, connect, silent):
        """
        Private slot to connect to or disconnect from the given network.
        
        @param name name of the network to connect to (string)
        @param connect flag indicating to connect (boolean)
        @param silent flag indicating a silent connect/disconnect (boolean)
        """
        if connect:
            network = self.__ircNetworkManager.getNetwork(name)
            if network:
                self.__server = network.getServer()
                self.__identityName = network.getIdentityName()
                identity = self.__ircNetworkManager.getIdentity(
                    self.__identityName)
                if identity:
                    self.__userName = identity.getIdent()
                    self.__quitMessage = identity.getQuitMessage()
                    if self.__server:
                        useSSL = self.__server.useSSL()
                        if useSSL and not SSL_AVAILABLE:
                            E5MessageBox.critical(
                                self,
                                self.tr("SSL Connection"),
                                self.tr(
                                    """An encrypted connection to the IRC"""
                                    """ network was requested but SSL is not"""
                                    """ available. Please change the server"""
                                    """ configuration."""))
                            return
                        
                        if useSSL:
                            # create SSL socket
                            self.__socket = QSslSocket(self)
                            self.__socket.encrypted.connect(
                                self.__hostConnected)
                            self.__socket.sslErrors.connect(
                                self.__sslErrors)
                        else:
                            # create TCP socket
                            self.__socket = QTcpSocket(self)
                            self.__socket.connected.connect(
                                self.__hostConnected)
                        self.__socket.hostFound.connect(
                            self.__hostFound)
                        self.__socket.disconnected.connect(
                            self.__hostDisconnected)
                        self.__socket.readyRead.connect(
                            self.__readyRead)
                        self.__socket.error.connect(
                            self.__tcpError)
                        
                        self.__connectionState = IrcWidget.ServerConnecting
                        if useSSL:
                            self.networkWidget.addServerMessage(
                                self.tr("Info"),
                                self.tr("Looking for server {0} (port {1})"
                                        " using an SSL encrypted connection"
                                        "...").format(self.__server.getName(),
                                                      self.__server.getPort()))
                            self.__socket.connectToHostEncrypted(
                                self.__server.getName(),
                                self.__server.getPort()
                            )
                        else:
                            self.networkWidget.addServerMessage(
                                self.tr("Info"),
                                self.tr(
                                    "Looking for server {0} (port {1})...")
                                .format(
                                    self.__server.getName(),
                                    self.__server.getPort()))
                            self.__socket.connectToHost(
                                self.__server.getName(),
                                self.__server.getPort())
        else:
            if silent:
                ok = True
            else:
                ok = E5MessageBox.yesNo(
                    self,
                    self.tr("Disconnect from Server"),
                    self.tr("""<p>Do you really want to disconnect from"""
                            """ <b>{0}</b>?</p><p>All channels will be"""
                            """ closed.</p>""")
                    .format(self.__server.getName()))
            if ok:
                if self.__server is not None:
                    self.networkWidget.addServerMessage(
                        self.tr("Info"),
                        self.tr("Disconnecting from server {0}...").format(
                            self.__server.getName()))
                elif name:
                    self.networkWidget.addServerMessage(
                        self.tr("Info"),
                        self.tr("Disconnecting from network {0}...").format(
                            name))
                else:
                    self.networkWidget.addServerMessage(
                        self.tr("Info"),
                        self.tr("Disconnecting from server."))
                self.__closeAllChannels()
                self.__send("QUIT :" + self.__quitMessage)
                if self.__socket:
                    self.__socket.flush()
                    self.__socket.close()
                    if self.__socket:
                        # socket is still existing
                        self.__socket.deleteLater()
                        self.__socket = None
                self.__userName = ""
                self.__identityName = ""
                self.__quitMessage = ""
    
    def __editNetwork(self, name):
        """
        Private slot to edit the network configuration.
        
        @param name name of the network to edit (string)
        """
        from .IrcNetworkListDialog import IrcNetworkListDialog
        dlg = IrcNetworkListDialog(self.__ircNetworkManager, self)
        dlg.exec_()
    
    def __networkDataChanged(self):
        """
        Private slot handling changes of the network and identity definitions.
        """
        identity = self.__ircNetworkManager.getIdentity(self.__identityName)
        if identity:
            partMsg = identity.getPartMessage()
            for channel in self.__channelList:
                channel.setPartMessage(partMsg)
    
    def joinChannel(self, name, key=""):
        """
        Public slot to join a channel.
        
        @param name name of the channel (string)
        @param key key of the channel (string)
        """
        # step 1: check, if this channel is already joined
        for channel in self.__channelList:
            if channel.name() == name:
                return
        
        from .IrcChannelWidget import IrcChannelWidget
        channel = IrcChannelWidget(self)
        channel.setName(name)
        channel.setUserName(self.__nickName)
        identity = self.__ircNetworkManager.getIdentity(self.__identityName)
        if identity:
            channel.setPartMessage(identity.getPartMessage())
        channel.setUserPrivilegePrefix(self.__userPrefix)
        channel.initAutoWho()
        
        channel.sendData.connect(self.__send)
        channel.sendCtcpRequest.connect(self.__sendCtcpRequest)
        channel.sendCtcpReply.connect(self.__sendCtcpReply)
        channel.channelClosed.connect(self.__closeChannel)
        channel.openPrivateChat.connect(self.__openPrivate)
        channel.awayCommand.connect(self.networkWidget.handleAwayCommand)
        channel.leaveChannels.connect(self.__leaveChannels)
        channel.leaveAllChannels.connect(self.__leaveAllChannels)
        
        self.channelsWidget.addTab(channel, name)
        self.__channelList.append(channel)
        self.channelsWidget.setCurrentWidget(channel)
        
        joinCommand = ["JOIN", name]
        if key:
            joinCommand.append(key)
        self.__send(" ".join(joinCommand))
        self.__send("MODE " + name)
        
        emptyIndex = self.channelsWidget.indexOf(self.__emptyLabel)
        if emptyIndex > -1:
            self.channelsWidget.removeTab(emptyIndex)
            self.__leaveButton.setEnabled(True)
        self.channelsWidget.setTabsClosable(True)
    
    def __query(self, match):
        """
        Private method to handle a new private connection.
        
        @param match reference to the match object
        @return flag indicating, if the message was handled (boolean)
        """
        # group(1)   sender user name
        # group(2)   sender user@host
        # group(3)   target nick
        # group(4)   message
        if match.group(4).startswith("\x01"):
            return self.__handleCtcp(match)
        
        self.__openPrivate(match.group(1))
        # the above call sets the new channel as the current widget
        channel = self.channelsWidget.currentWidget()
        channel.addMessage(match.group(1), match.group(4))
        channel.setPrivateInfo(
            "{0} - {1}".format(match.group(1), match.group(2)))
        
        return True
    
    @pyqtSlot(str)
    def __openPrivate(self, name):
        """
        Private slot to open a private chat with the given user.
        
        @param name name of the user (string)
        """
        from .IrcChannelWidget import IrcChannelWidget
        channel = IrcChannelWidget(self)
        channel.setName(self.__nickName)
        channel.setUserName(self.__nickName)
        identity = self.__ircNetworkManager.getIdentity(self.__identityName)
        if identity:
            channel.setPartMessage(identity.getPartMessage())
        channel.setUserPrivilegePrefix(self.__userPrefix)
        channel.setPrivate(True, name)
        channel.addUsers([name, self.__nickName])
        
        channel.sendData.connect(self.__send)
        channel.sendCtcpRequest.connect(self.__sendCtcpRequest)
        channel.sendCtcpReply.connect(self.__sendCtcpReply)
        channel.channelClosed.connect(self.__closeChannel)
        channel.awayCommand.connect(self.networkWidget.handleAwayCommand)
        channel.leaveChannels.connect(self.__leaveChannels)
        channel.leaveAllChannels.connect(self.__leaveAllChannels)
        
        self.channelsWidget.addTab(channel, name)
        self.__channelList.append(channel)
        self.channelsWidget.setCurrentWidget(channel)
    
    @pyqtSlot()
    def __leaveChannel(self):
        """
        Private slot to leave a channel and close the associated tab.
        """
        channel = self.channelsWidget.currentWidget()
        channel.requestLeave()
    
    @pyqtSlot(list)
    def __leaveChannels(self, channelNames):
        """
        Private slot to leave a list of channels and close their associated
        tabs.
        
        @param channelNames list of channels to leave
        @type list of str
        """
        for channelName in channelNames:
            for channel in self.__channelList:
                if channel.name() == channelName:
                    channel.leaveChannel()
    
    @pyqtSlot()
    def __leaveAllChannels(self):
        """
        Private slot to leave all channels and close their tabs.
        """
        while self.__channelList:
            channel = self.__channelList[0]
            channel.leaveChannel()
    
    def __closeAllChannels(self):
        """
        Private method to close all channels.
        """
        while self.__channelList:
            channel = self.__channelList.pop()
            self.channelsWidget.removeTab(self.channelsWidget.indexOf(channel))
            channel.deleteLater()
            channel = None
        
        self.channelsWidget.addTab(self.__emptyLabel, "")
        self.__emptyLabel.show()
        self.__leaveButton.setEnabled(False)
        self.channelsWidget.setTabsClosable(False)
    
    def __closeChannel(self, name):
        """
        Private slot handling the closing of a channel.
        
        @param name name of the closed channel (string)
        """
        for channel in self.__channelList:
            if channel.name() == name:
                self.channelsWidget.removeTab(
                    self.channelsWidget.indexOf(channel))
                self.__channelList.remove(channel)
                channel.deleteLater()
        
        if self.channelsWidget.count() == 0:
            self.channelsWidget.addTab(self.__emptyLabel, "")
            self.__emptyLabel.show()
            self.__leaveButton.setEnabled(False)
            self.channelsWidget.setTabsClosable(False)
    
    @pyqtSlot(int)
    def on_channelsWidget_tabCloseRequested(self, index):
        """
        Private slot to close a channel by pressing the close button of
        the channels widget.
        
        @param index index of the tab to be closed (integer)
        """
        channel = self.channelsWidget.widget(index)
        channel.requestLeave()
    
    def __send(self, data):
        """
        Private slot to send data to the IRC server.
        
        @param data data to be sent (string)
        """
        if self.__socket:
            self.__socket.write(
                QByteArray("{0}\r\n".format(data).encode("utf-8")))
    
    def __sendCtcpRequest(self, receiver, request, arguments):
        """
        Private slot to send a CTCP request.
        
        @param receiver nick name of the receiver
        @type str
        @param request CTCP request to be sent
        @type str
        @param arguments arguments to be sent
        @type str
        """
        request = request.upper()
        if request == "PING":
            arguments = "Eric IRC {0}".format(
                QDateTime.currentMSecsSinceEpoch())
            
        self.__send("PRIVMSG {0} :\x01{1} {2}\x01".format(
            receiver, request, arguments))
    
    def __sendCtcpReply(self, receiver, text):
        """
        Private slot to send a CTCP reply.
        
        @param receiver nick name of the receiver
        @type str
        @param text text to be sent
        @type str
        """
        self.__send("NOTICE {0} :\x01{1}\x01".format(receiver, text))
    
    def __hostFound(self):
        """
        Private slot to indicate the host was found.
        """
        self.networkWidget.addServerMessage(
            self.tr("Info"),
            self.tr("Server found,connecting..."))
    
    def __hostConnected(self):
        """
        Private slot to log in to the server after the connection was
        established.
        """
        self.networkWidget.addServerMessage(
            self.tr("Info"),
            self.tr("Connected,logging in..."))
        self.networkWidget.setConnected(True)
        
        self.__registering = True
        serverPassword = self.__server.getPassword()
        if serverPassword:
            self.__send("PASS " + serverPassword)
        
        identity = self.__ircNetworkManager.getIdentity(
            self.__identityName)
        nick = self.networkWidget.getNickname()
        if not nick and identity:
            self.__nickIndex = 0
            try:
                nick = identity.getNickNames()[self.__nickIndex]
            except IndexError:
                nick = ""
        if not nick:
            nick = self.__userName
        self.__nickName = nick
        self.networkWidget.setNickName(nick)
        if identity:
            realName = identity.getRealName()
            if not realName:
                realName = "eric IDE chat"
            self.__send("NICK " + nick)
            self.__send("USER " + self.__userName + " 0 * :" + realName)
    
    def __hostDisconnected(self):
        """
        Private slot to indicate the host was disconnected.
        """
        if self.networkWidget.isConnected():
            self.__closeAllChannels()
            self.networkWidget.addServerMessage(
                self.tr("Info"),
                self.tr("Server disconnected."))
            self.networkWidget.setRegistered(False)
            self.networkWidget.setConnected(False)
            self.__server = None
            self.__nickName = ""
            self.__nickIndex = -1
            self.__channelTypePrefixes = ""
            
            if self.__socket:
                self.__socket.deleteLater()
            self.__socket = None
            
            self.__connectionState = IrcWidget.ServerDisconnected
            self.__sslErrorLock = False
    
    def __readyRead(self):
        """
        Private slot to read data from the socket.
        """
        if self.__socket:
            self.__buffer += str(
                self.__socket.readAll(),
                Preferences.getSystem("IOEncoding"),
                'replace')
            if self.__buffer.endswith("\r\n"):
                for line in self.__buffer.splitlines():
                    line = line.strip()
                    if line:
                        logging.debug("<IRC> %s", line)
                        handled = False
                        # step 1: give channels a chance to handle the message
                        for channel in self.__channelList:
                            handled = channel.handleMessage(line)
                            if handled:
                                break
                        else:
                            # step 2: try to process the message ourselves
                            for patternRe, patternFunc in self.__patterns:
                                match = patternRe.match(line)
                                if match is not None:
                                    if patternFunc(match):
                                        break
                            else:
                                # Oops, the message wasn't handled
                                self.networkWidget.addErrorMessage(
                                    self.tr("Message Error"),
                                    self.tr(
                                        "Unknown message received from server:"
                                        "<br/>{0}").format(line))
                
                self.__updateUsersCount()
                self.__buffer = ""
    
    def __handleCtcpReply(self, match):
        """
        Private method to handle a server message containing a CTCP reply.
        
        @param match reference to the match object
        """
        if "!" in match.group(1):
            sender = match.group(1).split("!", 1)[0]
            
            try:
                ctcpCommand = match.group(3).split(":", 1)[1]
            except IndexError:
                ctcpCommand = match.group(3)
            ctcpCommand = ctcpCommand[1:].split("\x01", 1)[0]
            if " " in ctcpCommand:
                ctcpReply, ctcpArg = ctcpCommand.split(" ", 1)
            else:
                ctcpReply, ctcpArg = ctcpCommand, ""
            ctcpReply = ctcpReply.upper()
            
            if ctcpReply == "PING" and ctcpArg.startswith("Eric IRC "):
                # it is a response to a ping request
                pingDateTime = int(ctcpArg.split()[-1])
                latency = QDateTime.currentMSecsSinceEpoch() - pingDateTime
                self.networkWidget.addServerMessage(
                    self.tr("CTCP"),
                    self.tr(
                        "Received CTCP-PING response from {0} with latency"
                        " of {1} ms.").format(sender, latency))
            else:
                self.networkWidget.addServerMessage(
                    self.tr("CTCP"),
                    self.tr(
                        "Received unknown CTCP-{0} response from {1}.")
                    .format(ctcpReply, sender))
    
    def __handleNamedMessage(self, match):
        """
        Private method to handle a server message containing a message name.
        
        @param match reference to the match object
        @return flag indicating, if the message was handled (boolean)
        """
        name = match.group(2)
        if name == "NOTICE":
            try:
                msg = match.group(3).split(":", 1)[1]
            except IndexError:
                msg = match.group(3)
            
            if msg.startswith("\x01"):
                self.__handleCtcpReply(match)
                return True
            
            if "!" in match.group(1):
                name = match.group(1).split("!", 1)[0]
                msg = "-{0}- {1}".format(name, msg)
            self.networkWidget.addServerMessage(self.tr("Notice"), msg)
            return True
        elif name == "MODE":
            self.__registering = False
            if ":" in match.group(3):
                # :foo MODE foo :+i
                name, modes = match.group(3).split(" :")
                sourceNick = match.group(1)
                if not self.isChannelName(name):
                    if name == self.__nickName:
                        if sourceNick == self.__nickName:
                            msg = self.tr(
                                "You have set your personal modes to"
                                " <b>[{0}]</b>.").format(modes)
                        else:
                            msg = self.tr(
                                "{0} has changed your personal modes to"
                                " <b>[{1}]</b>.").format(sourceNick, modes)
                        self.networkWidget.addServerMessage(
                            self.tr("Mode"), msg, filterMsg=False)
                        return True
        elif name == "PART":
            nick = match.group(1).split("!", 1)[0]
            if nick == self.__nickName:
                channel = match.group(3).split(None, 1)[0]
                self.networkWidget.addMessage(
                    self.tr("You have left channel {0}.").format(channel))
                return True
        elif name == "QUIT":
            # don't do anything with it here
            return True
        elif name == "NICK":
            # :[email protected] NICK :newnick
            oldNick = match.group(1).split("!", 1)[0]
            newNick = match.group(3).split(":", 1)[1]
            if oldNick == self.__nickName:
                self.networkWidget.addMessage(
                    self.tr("You are now known as {0}.").format(newNick))
                self.__nickName = newNick
                self.networkWidget.setNickName(newNick)
            else:
                self.networkWidget.addMessage(
                    self.tr("User {0} is now known as {1}.").format(
                        oldNick, newNick))
            return True
        elif name == "PONG":
            nick = match.group(3).split(":", 1)[1]
            self.networkWidget.addMessage(
                self.tr("Received PONG from {0}").format(nick))
            return True
        elif name == "ERROR":
            self.networkWidget.addErrorMessage(
                self.tr("Server Error"), match.group(3).split(":", 1)[1])
            return True
        
        return False
    
    def __handleNumericMessage(self, match):
        """
        Private method to handle a server message containing a numeric code.
        
        @param match reference to the match object
        @return flag indicating, if the message was handled (boolean)
        """
        code = int(match.group(2))
        if code < 400:
            return self.__handleServerReply(
                code, match.group(1), match.group(3))
        else:
            return self.__handleServerError(
                code, match.group(1), match.group(3))
    
    def __handleServerError(self, code, server, message):
        """
        Private slot to handle a server error reply.
        
        @param code numerical code sent by the server (integer)
        @param server name of the server (string)
        @param message message sent by the server (string)
        @return flag indicating, if the message was handled (boolean)
        """
        if code == 433:
            if self.__registering:
                self.__handleNickInUseLogin()
            else:
                self.__handleNickInUse()
        else:
            self.networkWidget.addServerMessage(self.tr("Error"), message)
        
        return True
    
    def __handleServerReply(self, code, server, message):
        """
        Private slot to handle a server reply.
        
        @param code numerical code sent by the server (integer)
        @param server name of the server (string)
        @param message message sent by the server (string)
        @return flag indicating, if the message was handled (boolean)
        """
        # determine message type
        if code in [1, 2, 3, 4]:
            msgType = self.tr("Welcome")
        elif code == 5:
            msgType = self.tr("Support")
        elif code in [250, 251, 252, 253, 254, 255, 265, 266]:
            msgType = self.tr("User")
        elif code in [372, 375, 376]:
            msgType = self.tr("MOTD")
        elif code in [305, 306]:
            msgType = self.tr("Away")
        else:
            msgType = self.tr("Info ({0})").format(code)
        
        # special treatment for some messages
        if code == 375:
            message = self.tr("Message of the day")
        elif code == 376:
            message = self.tr("End of message of the day")
        elif code == 4:
            parts = message.strip().split()
            message = self.tr(
                "Server {0} (Version {1}), User-Modes: {2},"
                " Channel-Modes: {3}"
            ).format(parts[1], parts[2], parts[3], parts[4])
        elif code == 265:
            parts = message.strip().split()
            message = self.tr(
                "Current users on {0}: {1}, max. {2}").format(
                server, parts[1], parts[2])
        elif code == 266:
            parts = message.strip().split()
            message = self.tr(
                "Current users on the network: {0}, max. {1}").format(
                parts[1], parts[2])
        elif code == 305:
            message = self.tr("You are no longer marked as being away.")
        elif code == 306:
            message = self.tr("You have been marked as being away.")
        else:
            first, message = message.split(None, 1)
            if message.startswith(":"):
                message = message[1:]
            else:
                message = message.replace(":", "", 1)
        
        self.networkWidget.addServerMessage(msgType, message)
        
        if code == 1:
            # register with services after the welcome message
            self.__connectionState = IrcWidget.ServerConnected
            self.__registerWithServices()
            self.networkWidget.setRegistered(True)
            QTimer.singleShot(1000, self.__autoJoinChannels)
        elif code == 5:
            # extract the user privilege prefixes
            # ... PREFIX=(ov)@+ ...
            m = self.__prefixRe.match(message)
            if m:
                self.__setUserPrivilegePrefix(m.group(1), m.group(2))
            # extract the channel type prefixes
            # ... CHANTYPES=# ...
            m = self.__chanTypesRe.match(message)
            if m:
                self.__setChannelTypePrefixes(m.group(1))
        
        return True
    
    def __registerWithServices(self):
        """
        Private method to register to services.
        """
        identity = self.__ircNetworkManager.getIdentity(self.__identityName)
        if identity:
            service = identity.getServiceName()
            password = identity.getPassword()
            if service and password:
                self.__send("PRIVMSG " + service + " :identify " + password)
    
    def __autoJoinChannels(self):
        """
        Private slot to join channels automatically once a server got
        connected.
        """
        for channel in self.networkWidget.getNetworkChannels():
            if channel.autoJoin():
                name = channel.getName()
                key = channel.getKey()
                self.joinChannel(name, key)
    
    def __tcpError(self, error):
        """
        Private slot to handle errors reported by the TCP socket.
        
        @param error error code reported by the socket
            (QAbstractSocket.SocketError)
        """
        if error == QAbstractSocket.RemoteHostClosedError:
            # ignore this one, it's a disconnect
            if self.__sslErrorLock:
                self.networkWidget.addErrorMessage(
                    self.tr("SSL Error"),
                    self.tr(
                        """Connection to server {0} (port {1}) lost while"""
                        """ waiting for user response to an SSL error.""")
                    .format(self.__server.getName(), self.__server.getPort()))
                self.__connectionState = IrcWidget.ServerDisconnected
        elif error == QAbstractSocket.HostNotFoundError:
            self.networkWidget.addErrorMessage(
                self.tr("Socket Error"),
                self.tr(
                    "The host was not found. Please check the host name"
                    " and port settings."))
        elif error == QAbstractSocket.ConnectionRefusedError:
            self.networkWidget.addErrorMessage(
                self.tr("Socket Error"),
                self.tr(
                    "The connection was refused by the peer. Please check the"
                    " host name and port settings."))
        elif error == QAbstractSocket.SslHandshakeFailedError:
            self.networkWidget.addErrorMessage(
                self.tr("Socket Error"),
                self.tr("The SSL handshake failed."))
        else:
            if self.__socket:
                self.networkWidget.addErrorMessage(
                    self.tr("Socket Error"),
                    self.tr(
                        "The following network error occurred:<br/>{0}")
                    .format(self.__socket.errorString()))
            else:
                self.networkWidget.addErrorMessage(
                    self.tr("Socket Error"),
                    self.tr("A network error occurred."))
    
    def __sslErrors(self, errors):
        """
        Private slot to handle SSL errors.
        
        @param errors list of SSL errors (list of QSslError)
        """
        ignored, defaultChanged = self.__sslErrorHandler.sslErrors(
            errors, self.__server.getName(), self.__server.getPort())
        if ignored == E5SslErrorHandler.NotIgnored:
            self.networkWidget.addErrorMessage(
                self.tr("SSL Error"),
                self.tr(
                    """Could not connect to {0} (port {1}) using an SSL"""
                    """ encrypted connection. Either the server does not"""
                    """ support SSL (did you use the correct port?) or"""
                    """ you rejected the certificate.""")
                .format(self.__server.getName(), self.__server.getPort()))
            self.__socket.close()
        else:
            if defaultChanged:
                self.__socket.setSslConfiguration(
                    QSslConfiguration.defaultConfiguration())
            if ignored == E5SslErrorHandler.UserIgnored:
                self.networkWidget.addErrorMessage(
                    self.tr("SSL Error"),
                    self.tr(
                        """The SSL certificate for the server {0} (port {1})"""
                        """ failed the authenticity check. SSL errors"""
                        """ were accepted by you.""")
                    .format(self.__server.getName(), self.__server.getPort()))
            if self.__connectionState == IrcWidget.ServerConnecting:
                self.__socket.ignoreSslErrors()
    
    def __setUserPrivilegePrefix(self, prefix1, prefix2):
        """
        Private method to set the user privilege prefix.
        
        @param prefix1 first part of the prefix (string)
        @param prefix2 indictors the first part gets mapped to (string)
        """
        # PREFIX=(ov)@+
        # o = @ -> @ircbot , channel operator
        # v = + -> +userName , voice operator
        for i in range(len(prefix1)):
            self.__userPrefix["+" + prefix1[i]] = prefix2[i]
            self.__userPrefix["-" + prefix1[i]] = ""
    
    def __ping(self, match):
        """
        Private method to handle a PING message.
        
        @param match reference to the match object
        @return flag indicating, if the message was handled (boolean)
        """
        self.__send("PONG " + match.group(1))
        return True
    
    def __handleCtcp(self, match):
        """
        Private method to handle a CTCP command.
        
        @param match reference to the match object
        @return flag indicating, if the message was handled (boolean)
        """
        # group(1)   sender user name
        # group(2)   sender user@host
        # group(3)   target nick
        # group(4)   message
        if match.group(4).startswith("\x01"):
            ctcpCommand = match.group(4)[1:].split("\x01", 1)[0]
            if " " in ctcpCommand:
                ctcpRequest, ctcpArg = ctcpCommand.split(" ", 1)
            else:
                ctcpRequest, ctcpArg = ctcpCommand, ""
            ctcpRequest = ctcpRequest.lower()
            if ctcpRequest == "version":
                if Version.startswith("@@"):
                    vers = ""
                else:
                    vers = " " + Version
                msg = "Eric IRC client{0}, {1}".format(vers, Copyright)
                self.networkWidget.addServerMessage(
                    self.tr("CTCP"),
                    self.tr("Received Version request from {0}.").format(
                        match.group(1)))
                self.__sendCtcpReply(match.group(1), "VERSION " + msg)
            elif ctcpRequest == "ping":
                self.networkWidget.addServerMessage(
                    self.tr("CTCP"),
                    self.tr(
                        "Received CTCP-PING request from {0},"
                        " sending answer.").format(match.group(1)))
                self.__sendCtcpReply(
                    match.group(1), "PING {0}".format(ctcpArg))
            elif ctcpRequest == "clientinfo":
                self.networkWidget.addServerMessage(
                    self.tr("CTCP"),
                    self.tr(
                        "Received CTCP-CLIENTINFO request from {0},"
                        " sending answer.").format(match.group(1)))
                self.__sendCtcpReply(
                    match.group(1),
                    "CLIENTINFO CLIENTINFO PING VERSION")
            else:
                self.networkWidget.addServerMessage(
                    self.tr("CTCP"),
                    self.tr(
                        "Received unknown CTCP-{0} request from {1}.")
                    .format(ctcpRequest, match.group(1)))
            return True
        
        return False
    
    def __updateUsersCount(self):
        """
        Private method to update the users count on the channel tabs.
        """
        for channel in self.__channelList:
            index = self.channelsWidget.indexOf(channel)
            self.channelsWidget.setTabText(
                index,
                self.tr("{0} ({1})", "channel name, users count").format(
                    channel.name(), channel.getUsersCount()))
    
    def __handleNickInUseLogin(self):
        """
        Private method to handle a 443 server error at login.
        """
        self.__nickIndex += 1
        try:
            identity = self.__ircNetworkManager.getIdentity(
                self.__identityName)
            if identity:
                nick = identity.getNickNames()[self.__nickIndex]
                self.__nickName = nick
            else:
                self.__connectNetwork("", False, True)
                self.__nickName = ""
                self.__nickIndex = -1
                return
        except IndexError:
            self.networkWidget.addServerMessage(
                self.tr("Critical"),
                self.tr(
                    "No nickname acceptable to the server configured"
                    " for <b>{0}</b>. Disconnecting...")
                .format(self.__userName),
                filterMsg=False)
            self.__connectNetwork("", False, True)
            self.__nickName = ""
            self.__nickIndex = -1
            return
        
        self.networkWidget.setNickName(nick)
        self.__send("NICK " + nick)
    
    def __handleNickInUse(self):
        """
        Private method to handle a 443 server error.
        """
        self.networkWidget.addServerMessage(
            self.tr("Critical"),
            self.tr("The given nickname is already in use."))
    
    def __changeNick(self, nick):
        """
        Private slot to use a new nick name.
        
        @param nick nick name to use (str)
        """
        if nick and nick != self.__nickName:
            self.__send("NICK " + nick)
    
    def __setChannelTypePrefixes(self, prefixes):
        """
        Private method to set the channel type prefixes.
        
        @param prefixes channel prefix characters (string)
        """
        self.__channelTypePrefixes = prefixes
    
    def isChannelName(self, name):
        """
        Public method to check, if the given name is a channel name.
        
        @param name name to check (string)
        @return flag indicating a channel name (boolean)
        """
        if not name:
            return False
        
        if self.__channelTypePrefixes:
            return name[0] in self.__channelTypePrefixes
        else:
            return name[0] in "#&"
    
    def __away(self, isAway):
        """
        Private slot handling the change of the away state.
        
        @param isAway flag indicating the current away state (boolean)
        """
        if isAway and self.__identityName:
            identity = self.__ircNetworkManager.getIdentity(
                self.__identityName)
            if identity and identity.rememberAwayPosition():
                for channel in self.__channelList:
                    channel.setMarkerLine()
예제 #20
0
class SocketTest(QObject):
    def __init__(self, parent=None):
        super(SocketTest, self).__init__(parent)

    def init_socket(self):
        self.socket = QTcpSocket(self)

        def connected():
            logger.info('connected , local port:{}'.format(self.socket.localPort()))
            # self.socket.write('f**k u'.encode(encoding='utf8'))

        def disconnect():
            logger.info('disconnected')

            self.socket.connectToHost(IP, PORT)

        @pyqtSlot(QAbstractSocket.SocketError)
        def error(err):
            dict = {
                0: 'QAbstractSocket::ConnectionRefusedError',
                1: 'QAbstractSocket::RemoteHostClosedError',
                2: 'QAbstractSocket::HostNotFoundError',
                3: 'QAbstractSocket::SocketAccessError',
                4: 'QAbstractSocket::SocketResourceError',
                5: 'QAbstractSocket::SocketTimeoutError',
                6: 'QAbstractSocket::DatagramTooLargeError',
                7: 'QAbstractSocket::NetworkError',
                8: 'QAbstractSocket::AddressInUseError',
                9: 'QAbstractSocket::SocketAddressNotAvailableError',
                10: 'QAbstractSocket::UnsupportedSocketOperationError',
                12: 'QAbstractSocket::ProxyAuthenticationRequiredError',
                13: 'QAbstractSocket::SslHandshakeFailedError',
                11: 'QAbstractSocket::UnfinishedSocketOperationError',
                14: 'QAbstractSocket::ProxyConnectionRefusedError',
                15: 'QAbstractSocket::ProxyConnectionClosedError',
                16: 'QAbstractSocket::ProxyConnectionTimeoutError',
                17: 'QAbstractSocket::ProxyNotFoundError',
                18: 'QAbstractSocket::ProxyProtocolError',
                19: 'QAbstractSocket::OperationError',
                20: 'QAbstractSocket::SslInternalError',
                21: 'QAbstractSocket::SslInvalidUserDataError',
                22: 'QAbstractSocket::TemporaryError',
                -1: 'QAbstractSocket::UnknownSocketError'
            }

            logger.info(dict[err])

        @pyqtSlot(QAbstractSocket.SocketState)
        def _state_changed(state):
            # http://doc.qt.io/qt-5/qabstractsocket.html#SocketState-enum
            dict = {
                0: 'QAbstractSocket::UnconnectedState',
                1: 'QAbstractSocket::HostLookupState',
                2: 'QAbstractSocket::ConnectingState',
                3: 'QAbstractSocket::ConnectedState',
                4: 'QAbstractSocket::BoundState',
                6: 'QAbstractSocket::ClosingState',
                5: 'QAbstractSocket::ListeningState'
            }

            logger.info(dict[state])

        def ready_ready():
            logger.info('ready read', end=': ')

            #logger.info(self.socket.readAll(q))

            self.socket.close()

        @pyqtSlot(int)
        def bytes_written(bytes):
            logger.info('{} bytes send'.format(bytes))

        #self.socket.connected.connect(connected)
        #self.socket.disconnected.connect(disconnect)
        self.socket.stateChanged.connect(_state_changed)
        self.socket.error.connect(error)
        # self.socket.readyRead.connect(ready_ready)
        # self.socket.bytesWritten.connect(bytes_written)
        self.socket.connectToHost(IP, PORT)
예제 #21
0
class TcpClient(QWidget):
    def __init__(self):
        super().__init__()
        self.isOnline = False
        self.port = 8888
        self.serverIP = QHostAddress('127.0.0.1')
        self.initUI()

    def initUI(self):
        self.ui = ui_tcpClient.Ui_Form()
        self.ui.setupUi(self)
        self.ui.sendBtn.setEnabled(False)
        self.ui.portLineEdit.setText(str(self.port))
        self.ui.serverIPLineEdit.setText(self.serverIP.toString())

        self.ui.enterBtn.clicked.connect(self.slotEnterOrLeave)
        self.ui.sendBtn.clicked.connect(self.slotSend)
        self.ui.sendLineEdit.returnPressed.connect(self.slotSend)

        self.show()

    def slotEnterOrLeave(self):
        if not self.isOnline:
            if not self.validate(): return
            self.enterRoom()
        else:
            self.leaveRoom()

    def validate(self):
        if self.ui.userNameLineEdit.text() == '':
            QMessageBox().information(self, 'ERROR', 'User Name Error!')
            return False
        self.userName = self.ui.userNameLineEdit.text()

        if not self.serverIP.setAddress(
                self.ui.serverIPLineEdit.text()):  # 判断给定的IP是否能够被正确解析
            QMessageBox().information(self, 'ERROR', 'Server IP Error!')
            return False

        if not (0 <= int(self.ui.portLineEdit.text()) <= 65535):
            QMessageBox().information(self, 'ERROR', 'Server Port Error!')
            return False
        self.port = int(self.ui.portLineEdit.text())
        return True

    def enterRoom(self):
        self.tcpSocket = QTcpSocket(self)
        self.tcpSocket.connectToHost(self.serverIP, self.port)

        self.tcpSocket.connected.connect(self.slotConnected)
        self.tcpSocket.readyRead.connect(self.slotDataReceived)
        self.tcpSocket.disconnected.connect(self.slotDisconnected)
        self.tcpSocket.error.connect(self.slotErrorOccured)

    def leaveRoom(self):
        sendData = '[-] ' + self.userName + ': Leave Chat Room'
        self.tcpSocket.write(bytes(sendData, encoding='utf-8'))
        self.tcpSocket.disconnectFromHost()

    def slotSend(self):
        if self.ui.sendLineEdit.text() == '':
            return
        sendData = self.userName + ': ' + self.ui.sendLineEdit.text()
        self.tcpSocket.write(bytes(sendData, encoding='utf-8'))
        self.ui.sendLineEdit.clear()

    def slotConnected(self):
        self.ui.sendBtn.setEnabled(True)
        self.ui.userNameLineEdit.setEnabled(False)
        self.ui.serverIPLineEdit.setEnabled(False)
        self.ui.portLineEdit.setEnabled(False)
        self.ui.enterBtn.setText('Leave Chat Room')
        self.isOnline = True

        sendData = '[+] ' + self.userName + ': Enter Chat Room'
        self.tcpSocket.write(bytes(sendData, encoding='utf-8'))

    def slotDataReceived(self):
        recvData = ''
        while self.tcpSocket.bytesAvailable() > 0:
            recvData = self.tcpSocket.read(self.tcpSocket.bytesAvailable())
        self.ui.contentListWidget.addItem(str(recvData, encoding='utf-8'))
        self.ui.contentListWidget.scrollToBottom()  # 滚动到最后一行

    def slotDisconnected(self):
        self.ui.sendBtn.setEnabled(False)
        self.ui.userNameLineEdit.setEnabled(True)
        self.ui.serverIPLineEdit.setEnabled(True)
        self.ui.portLineEdit.setEnabled(True)
        self.ui.enterBtn.setText('Enter Chat Room')
        self.isOnline = False

    def closeEvent(self, event):
        if self.isOnline:
            msg = 'Are you sure to leave the chat room ?'
            reply = QMessageBox().warning(self, 'Quit', msg,
                                          QMessageBox.Yes | QMessageBox.No,
                                          QMessageBox.No)
            if reply == QMessageBox.Yes:
                self.leaveRoom()
                event.accept()
            else:
                event.ignore()
        else:
            event.accept()

    def slotErrorOccured(self, socketError):
        if socketError == 0:
            msg = '[*] ConnectionRefusedError: The connection was refused by the peer (or timed out).'
            self.ui.contentListWidget.addItem(msg)
        elif socketError == 1:
            msg = '[*] RemoteHostClosedError: The remote host closed the connection.'
            self.ui.contentListWidget.addItem(msg)
예제 #22
0
class VNA(QMainWindow, Ui_VNA):

  max_size = 16383

  formatter = matplotlib.ticker.FuncFormatter(lambda x, pos: '%1.1fM' % (x * 1e-6) if abs(x) >= 1e6 else '%1.1fk' % (x * 1e-3) if abs(x) >= 1e3 else '%1.1f' % x if abs(x) >= 1e0 else '%1.1fm' % (x * 1e+3) if abs(x) >= 1e-3 else '%1.1fu' % (x * 1e+6) if abs(x) >= 1e-6 else '%1.1f' % x)

  def __init__(self):
    super(VNA, self).__init__()
    self.setupUi(self)
    # IP address validator
    rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')
    self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
    # state variable
    self.idle = True
    # sweep parameters
    self.sweep_start = 100
    self.sweep_stop = 60000
    self.sweep_size = 600
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    # buffer and offset for the incoming samples
    self.buffer = bytearray(32 * VNA.max_size)
    self.offset = 0
    self.data = np.frombuffer(self.buffer, np.complex64)
    self.adc1 = np.zeros(VNA.max_size, np.complex64)
    self.adc2 = np.zeros(VNA.max_size, np.complex64)
    self.dac1 = np.zeros(VNA.max_size, np.complex64)
    self.open = np.zeros(VNA.max_size, np.complex64)
    self.short = np.zeros(VNA.max_size, np.complex64)
    self.load = np.zeros(VNA.max_size, np.complex64)
    self.dut = np.zeros(VNA.max_size, np.complex64)
    self.mode = 'dut'
    # create figure
    self.figure = Figure()
    self.figure.set_facecolor('none')
    self.canvas = FigureCanvas(self.figure)
    self.plotLayout.addWidget(self.canvas)
    # create navigation toolbar
    self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
    # remove subplots action
    actions = self.toolbar.actions()
    self.toolbar.removeAction(actions[7])
    self.plotLayout.addWidget(self.toolbar)
    # create TCP socket
    self.socket = QTcpSocket(self)
    self.socket.connected.connect(self.connected)
    self.socket.readyRead.connect(self.read_data)
    self.socket.error.connect(self.display_error)
    # connect signals from buttons and boxes
    self.sweepFrame.setEnabled(False)
    self.dutSweep.setEnabled(False)
    self.connectButton.clicked.connect(self.start)
    self.writeButton.clicked.connect(self.write_cfg)
    self.readButton.clicked.connect(self.read_cfg)
    self.openSweep.clicked.connect(self.sweep_open)
    self.shortSweep.clicked.connect(self.sweep_short)
    self.loadSweep.clicked.connect(self.sweep_load)
    self.dutSweep.clicked.connect(self.sweep_dut)
    self.s1pButton.clicked.connect(self.write_s1p)
    self.startValue.valueChanged.connect(self.set_start)
    self.stopValue.valueChanged.connect(self.set_stop)
    self.sizeValue.valueChanged.connect(self.set_size)
    self.openPlot.clicked.connect(self.plot_open)
    self.shortPlot.clicked.connect(self.plot_short)
    self.loadPlot.clicked.connect(self.plot_load)
    self.dutPlot.clicked.connect(self.plot_dut)
    self.smithPlot.clicked.connect(self.plot_smith)
    self.impPlot.clicked.connect(self.plot_imp)
    self.rcPlot.clicked.connect(self.plot_rc)
    self.swrPlot.clicked.connect(self.plot_swr)
    self.rlPlot.clicked.connect(self.plot_rl)
    # create timer
    self.startTimer = QTimer(self)
    self.startTimer.timeout.connect(self.timeout)

  def start(self):
    if self.idle:
      self.connectButton.setEnabled(False)
      self.socket.connectToHost(self.addrValue.text(), 1001)
      self.startTimer.start(5000)
    else:
      self.stop()

  def stop(self):
    self.idle = True
    self.socket.abort()
    self.offset = 0
    self.connectButton.setText('Connect')
    self.connectButton.setEnabled(True)
    self.sweepFrame.setEnabled(False)
    self.selectFrame.setEnabled(True)
    self.dutSweep.setEnabled(False)

  def timeout(self):
    self.display_error('timeout')

  def connected(self):
    self.startTimer.stop()
    self.idle = False
    self.set_start(self.startValue.value())
    self.set_stop(self.stopValue.value())
    self.set_size(self.sizeValue.value())
    self.connectButton.setText('Disconnect')
    self.connectButton.setEnabled(True)
    self.sweepFrame.setEnabled(True)
    self.dutSweep.setEnabled(True)

  def read_data(self):
    size = self.socket.bytesAvailable()
    if self.offset + size < 32 * self.sweep_size:
      self.buffer[self.offset:self.offset + size] = self.socket.read(size)
      self.offset += size
    else:
      self.buffer[self.offset:32 * self.sweep_size] = self.socket.read(32 * self.sweep_size - self.offset)
      self.offset = 0
      self.adc1 = self.data[0::4]
      self.adc2 = self.data[1::4]
      self.dac1 = self.data[2::4]
      getattr(self, self.mode)[0:self.sweep_size] = self.adc1[0:self.sweep_size] / self.dac1[0:self.sweep_size]
      self.sweepFrame.setEnabled(True)
      self.selectFrame.setEnabled(True)
      getattr(self, 'plot_%s' % self.mode)()

  def display_error(self, socketError):
    self.startTimer.stop()
    if socketError == 'timeout':
      QMessageBox.information(self, 'VNA', 'Error: connection timeout.')
    else:
      QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString())
    self.stop()

  def set_start(self, value):
    self.sweep_start = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 0<<28 | int(value * 1000)))

  def set_stop(self, value):
    self.sweep_stop = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 1<<28 | int(value * 1000)))

  def set_size(self, value):
    self.sweep_size = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 2<<28 | int(value)))

  def sweep(self):
    if self.idle: return
    self.sweepFrame.setEnabled(False)
    self.selectFrame.setEnabled(False)
    self.socket.write(struct.pack('<I', 3<<28))

  def sweep_open(self):
    self.mode = 'open'
    self.sweep()

  def sweep_short(self):
    self.mode = 'short'
    self.sweep()

  def sweep_load(self):
    self.mode = 'load'
    self.sweep()

  def sweep_dut(self):
    self.mode = 'dut'
    self.sweep()

  def impedance(self):
    return 50.0 * (self.open[0:self.sweep_size] - self.load[0:self.sweep_size]) * (self.dut[0:self.sweep_size] - self.short[0:self.sweep_size]) / ((self.load[0:self.sweep_size] - self.short[0:self.sweep_size]) * (self.open[0:self.sweep_size] - self.dut[0:self.sweep_size]))

  def gamma(self):
    z = self.impedance()
    return (z - 50.0)/(z + 50.0)

  def plot_magphase(self, data):
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(top = 0.98, right = 0.88)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(VNA.formatter)
    axes1.yaxis.set_major_formatter(VNA.formatter)
    axes1.tick_params('y', color = 'blue', labelcolor = 'blue')
    axes1.yaxis.label.set_color('blue')
    axes1.plot(self.xaxis, np.absolute(data), color = 'blue')
    axes2 = axes1.twinx()
    axes2.spines['left'].set_color('blue')
    axes2.spines['right'].set_color('red')
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Magnitude')
    axes2.set_ylabel('Phase angle')
    axes2.tick_params('y', color = 'red', labelcolor = 'red')
    axes2.yaxis.label.set_color('red')
    axes2.plot(self.xaxis, np.angle(data, deg = True), color = 'red')
    self.canvas.draw()

  def plot_open(self):
    self.plot_magphase(self.open[0:self.sweep_size])

  def plot_short(self):
    self.plot_magphase(self.short[0:self.sweep_size])

  def plot_load(self):
    self.plot_magphase(self.load[0:self.sweep_size])

  def plot_dut(self):
    self.plot_magphase(self.dut[0:self.sweep_size])

  def plot_smith(self):
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(top = 0.90, right = 0.90)
    axes = self.figure.add_subplot(111, projection = 'smith', axes_radius = 0.55, axes_scale = 50.0)
    axes.cla()
    axes.plot(self.impedance())
    self.canvas.draw()

  def plot_imp(self):
    self.plot_magphase(self.impedance())

  def plot_rc(self):
    self.plot_magphase(self.gamma())

  def plot_swr(self):
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(top = 0.98, right = 0.88)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(VNA.formatter)
    axes1.yaxis.set_major_formatter(VNA.formatter)
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('SWR')
    magnitude = np.absolute(self.gamma())
    swr = np.maximum(1.0, np.minimum(100.0, (1.0 + magnitude) / np.maximum(1.0e-20, 1.0 - magnitude)))
    axes1.plot(self.xaxis, swr, color = 'blue')
    self.canvas.draw()

  def plot_rl(self):
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(top = 0.98, right = 0.88)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(VNA.formatter)
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Return loss, dB')
    magnitude = np.absolute(self.gamma())
    axes1.plot(self.xaxis, 20.0 * np.log10(magnitude), color = 'blue')
    self.canvas.draw()

  def write_cfg(self):
    name = QFileDialog.getSaveFileName(self, 'Write configuration settings', '.', '*.ini')
    settings = QSettings(name[0], QSettings.IniFormat)
    self.write_cfg_settings(settings)

  def read_cfg(self):
    name = QFileDialog.getOpenFileName(self, 'Read configuration settings', '.', '*.ini')
    settings = QSettings(name[0], QSettings.IniFormat)
    self.read_cfg_settings(settings)

  def write_cfg_settings(self, settings):
    settings.setValue('start', self.startValue.value())
    settings.setValue('stop', self.stopValue.value())
    size = self.sizeValue.value()
    settings.setValue('size', size)
    for i in range(0, size):
      settings.setValue('open_real_%d' % i, float(self.open.real[i]))
      settings.setValue('open_imag_%d' % i, float(self.open.imag[i]))
    for i in range(0, size):
      settings.setValue('short_real_%d' % i, float(self.short.real[i]))
      settings.setValue('short_imag_%d' % i, float(self.short.imag[i]))
    for i in range(0, size):
      settings.setValue('load_real_%d' % i, float(self.load.real[i]))
      settings.setValue('load_imag_%d' % i, float(self.load.imag[i]))
    for i in range(0, size):
      settings.setValue('dut_real_%d' % i, float(self.dut.real[i]))
      settings.setValue('dut_imag_%d' % i, float(self.dut.imag[i]))

  def read_cfg_settings(self, settings):
    self.startValue.setValue(settings.value('start', 100, type = int))
    self.stopValue.setValue(settings.value('stop', 60000, type = int))
    size = settings.value('size', 600, type = int)
    self.sizeValue.setValue(size)
    for i in range(0, size):
      real = settings.value('open_real_%d' % i, 0.0, type = float)
      imag = settings.value('open_imag_%d' % i, 0.0, type = float)
      self.open[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('short_real_%d' % i, 0.0, type = float)
      imag = settings.value('short_imag_%d' % i, 0.0, type = float)
      self.short[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('load_real_%d' % i, 0.0, type = float)
      imag = settings.value('load_imag_%d' % i, 0.0, type = float)
      self.load[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('dut_real_%d' % i, 0.0, type = float)
      imag = settings.value('dut_imag_%d' % i, 0.0, type = float)
      self.dut[i] = real + 1.0j * imag

  def write_s1p(self):
    name = QFileDialog.getSaveFileName(self, 'Write s1p file', '.', '*.s1p')
    fh = open(name[0], 'w')
    gamma = self.gamma()
    size = self.sizeValue.value()
    fh.write('# GHz S MA R 50\n')
    for i in range(0, size):
      fh.write('0.0%.8d   %8.6f %7.2f\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True)))
    fh.close()
예제 #23
0
class MKSOutputDevice(NetworkedPrinterOutputDevice):
    def __init__(self, instance_id: str, address: str, properties: dict,
                 **kwargs) -> None:
        super().__init__(device_id=instance_id,
                         address=address,
                         properties=properties,
                         **kwargs)
        self._address = address
        self._port = 8080
        self._key = instance_id
        self._properties = properties

        self._target_bed_temperature = 0
        self._num_extruders = 1
        self._hotend_temperatures = [0] * self._num_extruders
        self._target_hotend_temperatures = [0] * self._num_extruders

        self._monitor_view_qml_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), "MonitorItem4x.qml")
        # self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "MonitorItem.qml")

        self.setPriority(
            3
        )  # Make sure the output device gets selected above local file output and Octoprint XD
        self._active_machine = CuraApplication.getInstance().getMachineManager(
        ).activeMachine
        self.setName(instance_id)
        self.setShortDescription(
            i18n_catalog.i18nc("@action:button", "Print over TFT"))
        self.setDescription(
            i18n_catalog.i18nc("@properties:tooltip", "Print over TFT"))
        self.setIconName("print")
        self.setConnectionText(
            i18n_catalog.i18nc("@info:status",
                               "Connected to TFT on {0}").format(self._key))
        Application.getInstance().globalContainerStackChanged.connect(
            self._onGlobalContainerChanged)

        self._socket = None
        self._gl = None
        self._command_queue = Queue()
        self._isPrinting = False
        self._isPause = False
        self._isSending = False
        self._gcode = None
        self._isConnect = False
        self._printing_filename = ""
        self._printing_progress = 0
        self._printing_time = 0
        self._start_time = 0
        self._pause_time = 0
        self.last_update_time = 0
        self.angle = 10
        self._connection_state_before_timeout = None
        self._sdFileList = False
        self.sdFiles = []
        self._mdialog = None
        self._mfilename = None
        self._uploadpath = ''

        self._settings_reply = None
        self._printer_reply = None
        self._job_reply = None
        self._command_reply = None
        self._screenShot = None

        self._image_reply = None
        self._stream_buffer = b""
        self._stream_buffer_start_index = -1

        self._post_reply = None
        self._post_multi_part = None
        self._post_part = None
        self._last_file_name = None
        self._last_file_path = None

        self._progress_message = None
        self._error_message = None
        self._connection_message = None
        self.__additional_components_view = None

        self._update_timer = QTimer()
        self._update_timer.setInterval(
            2000)  # TODO; Add preference for update interval
        self._update_timer.setSingleShot(False)
        self._update_timer.timeout.connect(self._update)

        self._manager = QNetworkAccessManager()
        self._manager.finished.connect(self._onRequestFinished)

        self._preheat_timer = QTimer()
        self._preheat_timer.setSingleShot(True)
        self._preheat_timer.timeout.connect(self.cancelPreheatBed)
        self._exception_message = None
        self._output_controller = GenericOutputController(self)
        self._number_of_extruders = 1
        self._camera_url = ""
        # Application.getInstance().getOutputDeviceManager().outputDevicesChanged.connect(self._onOutputDevicesChanged)
        CuraApplication.getInstance().getCuraSceneController(
        ).activeBuildPlateChanged.connect(self.CreateMKSController)

    def _onOutputDevicesChanged(self):
        Logger.log("d", "MKS _onOutputDevicesChanged")

    def connect(self):
        if self._socket is not None:
            self._socket.close()
        self._socket = QTcpSocket()
        self._socket.connectToHost(self._address, self._port)
        global_container_stack = CuraApplication.getInstance(
        ).getGlobalContainerStack()
        self.setShortDescription(
            i18n_catalog.i18nc(
                "@action:button",
                "Print over " + global_container_stack.getName()))
        self.setDescription(
            i18n_catalog.i18nc(
                "@properties:tooltip",
                "Print over " + global_container_stack.getName()))
        Logger.log("d", "MKS socket connecting ")
        # self._socket.waitForConnected(2000)
        self.setConnectionState(
            cast(ConnectionState, UnifiedConnectionState.Connecting))
        self._setAcceptsCommands(True)
        self._socket.readyRead.connect(self.on_read)
        self._update_timer.start()

    def getProperties(self):
        return self._properties

    @pyqtSlot(str, result=str)
    def getProperty(self, key):
        key = key.encode("utf-8")
        if key in self._properties:
            return self._properties.get(key, b"").decode("utf-8")
        else:
            return ""

    @pyqtSlot(result=str)
    def getKey(self):
        return self._key

    @pyqtProperty(str, constant=True)
    def address(self):
        return self._properties.get(b"address", b"").decode("utf-8")

    @pyqtProperty(str, constant=True)
    def name(self):
        return self._properties.get(b"name", b"").decode("utf-8")

    @pyqtProperty(str, constant=True)
    def firmwareVersion(self):
        return self._properties.get(b"firmware_version", b"").decode("utf-8")

    @pyqtProperty(str, constant=True)
    def ipAddress(self):
        return self._address

    @pyqtSlot(float, float)
    def preheatBed(self, temperature, duration):
        self._setTargetBedTemperature(temperature)
        if duration > 0:
            self._preheat_timer.setInterval(duration * 1000)
            self._preheat_timer.start()
        else:
            self._preheat_timer.stop()

    @pyqtSlot()
    def cancelPreheatBed(self):
        self._setTargetBedTemperature(0)
        self._preheat_timer.stop()

    @pyqtSlot()
    def printtest(self):
        self.sendCommand("M104 S0\r\n M140 S0\r\n M106 S255")

    @pyqtSlot()
    def printer_state(self):
        if len(self._printers) <= 0:
            return "offline"
        return self.printers[0].state

    @pyqtSlot()
    def selectfile(self):
        if self._last_file_name:
            return True
        else:
            return False

    @pyqtSlot(str)
    def deleteSDFiles(self, filename):
        # filename = "几何图.gcode"
        self._sendCommand("M30 1:/" + filename)
        self.sdFiles.remove(filename)
        self._sendCommand("M20")

    @pyqtSlot(str)
    def printSDFiles(self, filename):
        self._sendCommand("M23 " + filename)
        self._sendCommand("M24")

    @pyqtSlot()
    def selectFileToUplload(self):
        preferences = Application.getInstance().getPreferences()
        preferences.addPreference("mkswifi/autoprint", "True")
        preferences.addPreference("mkswifi/savepath", "")
        filename, _ = QFileDialog.getOpenFileName(
            None, "choose file", preferences.getValue("mkswifi/savepath"),
            "Gcode(*.gcode;*.g;*.goc)")
        preferences.setValue("mkswifi/savepath", filename)
        self._uploadpath = filename
        if ".g" in filename.lower():
            # Logger.log("d", "selectfile:"+filename)
            if filename in self.sdFiles:
                if self._mdialog:
                    self._mdialog.close()
                self._mdialog = QDialog()
                self._mdialog.setWindowTitle("The " +
                                             filename[filename.rfind("/") +
                                                      1:] +
                                             " file already exists.")
                dialogvbox = QVBoxLayout()
                dialoghbox = QHBoxLayout()
                yesbtn = QPushButton("yes")
                nobtn = QPushButton("no")
                yesbtn.clicked.connect(lambda: self.renameupload(filename))
                nobtn.clicked.connect(self.closeMDialog)
                content = QLabel(
                    "The " + filename[filename.rfind("/") + 1:] +
                    " file already exists. Do you want to rename and upload it?"
                )
                self._mfilename = QLineEdit()
                self._mfilename.setText(filename[filename.rfind("/") + 1:])
                dialoghbox.addWidget(yesbtn)
                dialoghbox.addWidget(nobtn)
                dialogvbox.addWidget(content)
                dialogvbox.addWidget(self._mfilename)
                dialogvbox.addLayout(dialoghbox)
                self._mdialog.setLayout(dialogvbox)
                self._mdialog.exec_()
                return
            if len(filename[filename.rfind("/") + 1:]) >= 30:
                if self._mdialog:
                    self._mdialog.close()
                self._mdialog = QDialog()
                self._mdialog.setWindowTitle(
                    "File name is too long to upload, please rename it.")
                dialogvbox = QVBoxLayout()
                dialoghbox = QHBoxLayout()
                yesbtn = QPushButton("yes")
                nobtn = QPushButton("no")
                yesbtn.clicked.connect(lambda: self.renameupload(filename))
                nobtn.clicked.connect(self.closeMDialog)
                content = QLabel(
                    "File name is too long to upload, please rename it.")
                self._mfilename = QLineEdit()
                self._mfilename.setText(filename[filename.rfind("/") + 1:])
                dialoghbox.addWidget(yesbtn)
                dialoghbox.addWidget(nobtn)
                dialogvbox.addWidget(content)
                dialogvbox.addWidget(self._mfilename)
                dialogvbox.addLayout(dialoghbox)
                self._mdialog.setLayout(dialogvbox)
                self._mdialog.exec_()
                return
            if self.isBusy():
                if self._exception_message:
                    self._exception_message.hide()
                self._exception_message = Message(
                    i18n_catalog.i18nc(
                        "@info:status",
                        "File cannot be transferred during printing."))
                self._exception_message.show()
                return
            self.uploadfunc(filename)

    def closeMDialog(self):
        if self._mdialog:
            self._mdialog.close()

    def renameupload(self, filename):
        if self._mfilename and ".g" in self._mfilename.text().lower():
            filename = filename[:filename.
                                rfind("/")] + "/" + self._mfilename.text()
            if self._mfilename.text() in self.sdFiles:
                if self._mdialog:
                    self._mdialog.close()
                self._mdialog = QDialog()
                self._mdialog.setWindowTitle("The " +
                                             filename[filename.rfind("/") +
                                                      1:] +
                                             " file already exists.")
                dialogvbox = QVBoxLayout()
                dialoghbox = QHBoxLayout()
                yesbtn = QPushButton("yes")
                nobtn = QPushButton("no")
                yesbtn.clicked.connect(lambda: self.renameupload(filename))
                nobtn.clicked.connect(self.closeMDialog)
                content = QLabel(
                    "The " + filename[filename.rfind("/") + 1:] +
                    " file already exists. Do you want to rename and upload it?"
                )
                self._mfilename = QLineEdit()
                self._mfilename.setText(filename[filename.rfind("/") + 1:])
                dialoghbox.addWidget(yesbtn)
                dialoghbox.addWidget(nobtn)
                dialogvbox.addWidget(content)
                dialogvbox.addWidget(self._mfilename)
                dialogvbox.addLayout(dialoghbox)
                self._mdialog.setLayout(dialogvbox)
                self._mdialog.exec_()
                return
            if len(filename[filename.rfind("/") + 1:]) >= 30:
                if self._mdialog:
                    self._mdialog.close()
                self._mdialog = QDialog()
                self._mdialog.setWindowTitle(
                    "File name is too long to upload, please rename it.")
                dialogvbox = QVBoxLayout()
                dialoghbox = QHBoxLayout()
                yesbtn = QPushButton("yes")
                nobtn = QPushButton("no")
                yesbtn.clicked.connect(lambda: self.renameupload(filename))
                nobtn.clicked.connect(self.closeMDialog)
                content = QLabel(
                    "File name is too long to upload, please rename it.")
                self._mfilename = QLineEdit()
                self._mfilename.setText(filename[filename.rfind("/") + 1:])
                dialoghbox.addWidget(yesbtn)
                dialoghbox.addWidget(nobtn)
                dialogvbox.addWidget(content)
                dialogvbox.addWidget(self._mfilename)
                dialogvbox.addLayout(dialoghbox)
                self._mdialog.setLayout(dialogvbox)
                self._mdialog.exec_()
                return
            if self.isBusy():
                if self._exception_message:
                    self._exception_message.hide()
                self._exception_message = Message(
                    i18n_catalog.i18nc(
                        "@info:status",
                        "File cannot be transferred during printing."))
                self._exception_message.show()
                return
            self._mdialog.close()
            self.uploadfunc(filename)

    def uploadfunc(self, filename):
        preferences = Application.getInstance().getPreferences()
        preferences.addPreference("mkswifi/autoprint", "True")
        preferences.addPreference("mkswifi/savepath", "")
        self._update_timer.stop()
        self._isSending = True
        self._preheat_timer.stop()
        single_string_file_data = ""
        try:
            f = open(self._uploadpath, "r")
            single_string_file_data = f.read()
            file_name = filename[filename.rfind("/") + 1:]
            self._last_file_name = file_name
            self._progress_message = Message(
                i18n_catalog.i18nc("@info:status", "Sending data to printer"),
                0,
                False,
                -1,
                i18n_catalog.i18nc("@info:title", "Sending Data"),
                option_text=i18n_catalog.i18nc("@label", "Print jobs"),
                option_state=preferences.getValue("mkswifi/autoprint"))
            self._progress_message.addAction(
                "Cancel", i18n_catalog.i18nc("@action:button", "Cancel"), None,
                "")
            self._progress_message.actionTriggered.connect(
                self._cancelSendGcode)
            self._progress_message.optionToggled.connect(
                self._onOptionStateChanged)
            self._progress_message.show()
            self._post_multi_part = QHttpMultiPart(QHttpMultiPart.FormDataType)
            self._post_part = QHttpPart()
            self._post_part.setHeader(
                QNetworkRequest.ContentDispositionHeader,
                "form-data; name=\"file\"; filename=\"%s\"" % file_name)
            self._post_part.setBody(single_string_file_data.encode())
            self._post_multi_part.append(self._post_part)
            post_request = QNetworkRequest(
                QUrl("http://%s/upload?X-Filename=%s" %
                     (self._address, file_name)))
            post_request.setRawHeader(b'Content-Type',
                                      b'application/octet-stream')
            post_request.setRawHeader(b'Connection', b'keep-alive')
            self._post_reply = self._manager.post(post_request,
                                                  self._post_multi_part)
            self._post_reply.uploadProgress.connect(self._onUploadProgress)
            self._post_reply.sslErrors.connect(self._onUploadError)
            self._gcode = None
        except IOError as e:
            Logger.log(
                "e",
                "An exception occurred in network connection: %s" % str(e))
            self._progress_message.hide()
            self._error_message = Message(
                i18n_catalog.i18nc("@info:status",
                                   "Send file to printer failed."))
            self._error_message.show()
            self._update_timer.start()
        except Exception as e:
            self._update_timer.start()
            self._progress_message.hide()
            Logger.log(
                "e",
                "An exception occurred in network connection: %s" % str(e))

    @pyqtProperty("QVariantList")
    def getSDFiles(self):
        self._sendCommand("M20")
        return list(self.sdFiles)

    def _setTargetBedTemperature(self, temperature):
        if not self._updateTargetBedTemperature(temperature):
            return
        self._sendCommand(["M140 S%s" % temperature])

    @pyqtSlot(str)
    def sendCommand(self, cmd):
        self._sendCommand(cmd)

    def _sendCommand(self, cmd):
        # Logger.log("d", "_sendCommand %s" % str(cmd))
        if self._socket and self._socket.state() == 2 or self._socket.state(
        ) == 3:
            if isinstance(cmd, str):
                self._command_queue.put(cmd + "\r\n")
            elif isinstance(cmd, list):
                for eachCommand in cmd:
                    self._command_queue.put(eachCommand + "\r\n")

    def disconnect(self):
        # self._updateJobState("")
        self._isConnect = False
        self.setConnectionState(
            cast(ConnectionState, UnifiedConnectionState.Closed))
        if self._socket is not None:
            self._socket.readyRead.disconnect(self.on_read)
            self._socket.close()
        if self._progress_message:
            self._progress_message.hide()
        if self._error_message:
            self._error_message.hide()
        self._update_timer.stop()

    def isConnected(self):
        return self._isConnect

    def isBusy(self):
        return self._isPrinting or self._isPause

    def requestWrite(self,
                     node,
                     file_name=None,
                     filter_by_machine=False,
                     file_handler=None,
                     **kwargs):
        self.writeStarted.emit(self)
        self._update_timer.stop()
        self._isSending = True
        # imagebuff = self._gl.glReadPixels(0, 0, 800, 800, self._gl.GL_RGB,
        #                                   self._gl.GL_UNSIGNED_BYTE)
        active_build_plate = CuraApplication.getInstance(
        ).getMultiBuildPlateModel().activeBuildPlate
        scene = CuraApplication.getInstance().getController().getScene()
        gcode_dict = getattr(scene, "gcode_dict", None)
        if not gcode_dict:
            return
        self._gcode = gcode_dict.get(active_build_plate, None)
        # Logger.log("d", "mks ready for print")
        self.startPrint()

    def startPrint(self):
        global_container_stack = CuraApplication.getInstance(
        ).getGlobalContainerStack()
        if not global_container_stack:
            return
        if self._error_message:
            self._error_message.hide()
            self._error_message = None

        if self._progress_message:
            self._progress_message.hide()
            self._progress_message = None

        if self.isBusy():
            self._error_message = Message(
                i18n_catalog.i18nc("@info:status",
                                   "Sending data to printer"), 0, False, -1,
                i18n_catalog.i18nc("@info:title", "Sending Data"))
            self._error_message.show()
            return
        job_name = Application.getInstance().getPrintInformation(
        ).jobName.strip()
        if job_name is "":
            job_name = "untitled_print"
            job_name = "cura_file"
        filename = "%s.gcode" % job_name
        if filename in self.sdFiles:
            if self._mdialog:
                self._mdialog.close()
            self._mdialog = QDialog()
            self._mdialog.setWindowTitle("The " +
                                         filename[filename.rfind("/") + 1:] +
                                         " file already exists.")
            dialogvbox = QVBoxLayout()
            dialoghbox = QHBoxLayout()
            yesbtn = QPushButton("yes")
            nobtn = QPushButton("no")
            yesbtn.clicked.connect(self.recheckfilename)
            nobtn.clicked.connect(self.closeMDialog)
            content = QLabel(
                "The " + filename[filename.rfind("/") + 1:] +
                " file already exists. Do you want to rename and upload it?")
            self._mfilename = QLineEdit()
            self._mfilename.setText(filename[filename.rfind("/") + 1:])
            dialoghbox.addWidget(yesbtn)
            dialoghbox.addWidget(nobtn)
            dialogvbox.addWidget(content)
            dialogvbox.addWidget(self._mfilename)
            dialogvbox.addLayout(dialoghbox)
            self._mdialog.setLayout(dialogvbox)
            self._mdialog.exec_()
            return
        if len(filename[filename.rfind("/") + 1:]) >= 30:
            if self._mdialog:
                self._mdialog.close()
            self._mdialog = QDialog()
            self._mdialog.setWindowTitle(
                "File name is too long to upload, please rename it.")
            dialogvbox = QVBoxLayout()
            dialoghbox = QHBoxLayout()
            yesbtn = QPushButton("yes")
            nobtn = QPushButton("no")
            yesbtn.clicked.connect(self.recheckfilename)
            nobtn.clicked.connect(self.closeMDialog)
            content = QLabel(
                "File name is too long to upload, please rename it.")
            self._mfilename = QLineEdit()
            self._mfilename.setText(filename[filename.rfind("/") + 1:])
            dialoghbox.addWidget(yesbtn)
            dialoghbox.addWidget(nobtn)
            dialogvbox.addWidget(content)
            dialogvbox.addWidget(self._mfilename)
            dialogvbox.addLayout(dialoghbox)
            self._mdialog.setLayout(dialogvbox)
            self._mdialog.exec_()
            return
        self._startPrint(filename)

    def recheckfilename(self):
        if self._mfilename and ".g" in self._mfilename.text().lower():
            filename = self._mfilename.text()
            if filename in self.sdFiles:
                if self._mdialog:
                    self._mdialog.close()
                self._mdialog = QDialog()
                self._mdialog.setWindowTitle("The " +
                                             filename[filename.rfind("/") +
                                                      1:] +
                                             " file already exists.")
                dialogvbox = QVBoxLayout()
                dialoghbox = QHBoxLayout()
                yesbtn = QPushButton("yes")
                nobtn = QPushButton("no")
                yesbtn.clicked.connect(self.recheckfilename)
                nobtn.clicked.connect(self.closeMDialog)
                content = QLabel(
                    "The " + filename[filename.rfind("/") + 1:] +
                    " file already exists. Do you want to rename and upload it?"
                )
                self._mfilename = QLineEdit()
                self._mfilename.setText(filename[filename.rfind("/") + 1:])
                dialoghbox.addWidget(yesbtn)
                dialoghbox.addWidget(nobtn)
                dialogvbox.addWidget(content)
                dialogvbox.addWidget(self._mfilename)
                dialogvbox.addLayout(dialoghbox)
                self._mdialog.setLayout(dialogvbox)
                self._mdialog.exec_()
                return
            if len(filename[filename.rfind("/") + 1:]) >= 30:
                if self._mdialog:
                    self._mdialog.close()
                self._mdialog = QDialog()
                self._mdialog.setWindowTitle(
                    "File name is too long to upload, please rename it.")
                dialogvbox = QVBoxLayout()
                dialoghbox = QHBoxLayout()
                yesbtn = QPushButton("yes")
                nobtn = QPushButton("no")
                yesbtn.clicked.connect(self.recheckfilename)
                nobtn.clicked.connect(self.closeMDialog)
                content = QLabel(
                    "File name is too long to upload, please rename it.")
                self._mfilename = QLineEdit()
                self._mfilename.setText(filename[filename.rfind("/") + 1:])
                dialoghbox.addWidget(yesbtn)
                dialoghbox.addWidget(nobtn)
                dialogvbox.addWidget(content)
                dialogvbox.addWidget(self._mfilename)
                dialogvbox.addLayout(dialoghbox)
                self._mdialog.setLayout(dialogvbox)
                self._mdialog.exec_()
                return
            if self.isBusy():
                if self._exception_message:
                    self._exception_message.hide()
                self._exception_message = Message(
                    i18n_catalog.i18nc(
                        "@info:status",
                        "File cannot be transferred during printing."))
                self._exception_message.show()
                return
            self._mdialog.close()
            self._startPrint(filename)

    def _messageBoxCallback(self, button):
        def delayedCallback():
            if button == QMessageBox.Yes:
                self.startPrint()
            else:
                CuraApplication.getInstance().getController().setActiveStage(
                    "PrepareStage")

    def _startPrint(self, file_name="cura_file.gcode"):
        self._preheat_timer.stop()
        self._screenShot = utils.take_screenshot()
        try:
            preferences = Application.getInstance().getPreferences()
            preferences.addPreference("mkswifi/autoprint", "True")
            preferences.addPreference("mkswifi/savepath", "")
            # CuraApplication.getInstance().showPrintMonitor.emit(True)
            self._progress_message = Message(
                i18n_catalog.i18nc("@info:status", "Sending data to printer"),
                0,
                False,
                -1,
                i18n_catalog.i18nc("@info:title", "Sending Data"),
                option_text=i18n_catalog.i18nc("@label", "Print jobs"),
                option_state=preferences.getValue("mkswifi/autoprint"))
            self._progress_message.addAction(
                "Cancel", i18n_catalog.i18nc("@action:button", "Cancel"), None,
                "")
            self._progress_message.actionTriggered.connect(
                self._cancelSendGcode)
            self._progress_message.optionToggled.connect(
                self._onOptionStateChanged)
            self._progress_message.show()
            # job_name = Application.getInstance().getPrintInformation().jobName.strip()
            # if job_name is "":
            #     job_name = "untitled_print"
            # job_name = "cura_file"
            # file_name = "%s.gcode" % job_name
            self._last_file_name = file_name
            Logger.log(
                "d", "mks: " + file_name + Application.getInstance().
                getPrintInformation().jobName.strip())

            single_string_file_data = ""
            if self._screenShot:
                single_string_file_data += utils.add_screenshot(
                    self._screenShot, 50, 50, ";simage:")
                single_string_file_data += utils.add_screenshot(
                    self._screenShot, 200, 200, ";;gimage:")
                single_string_file_data += "\r"
            last_process_events = time.time()
            for line in self._gcode:
                single_string_file_data += line
                if time.time() > last_process_events + 0.05:
                    QCoreApplication.processEvents()
                    last_process_events = time.time()

            self._post_multi_part = QHttpMultiPart(QHttpMultiPart.FormDataType)
            self._post_part = QHttpPart()
            # self._post_part.setHeader(QNetworkRequest.ContentTypeHeader, b'application/octet-stream')
            self._post_part.setHeader(
                QNetworkRequest.ContentDispositionHeader,
                "form-data; name=\"file\"; filename=\"%s\"" % file_name)
            self._post_part.setBody(single_string_file_data.encode())
            self._post_multi_part.append(self._post_part)
            post_request = QNetworkRequest(
                QUrl("http://%s/upload?X-Filename=%s" %
                     (self._address, file_name)))
            post_request.setRawHeader(b'Content-Type',
                                      b'application/octet-stream')
            post_request.setRawHeader(b'Connection', b'keep-alive')
            self._post_reply = self._manager.post(post_request,
                                                  self._post_multi_part)
            self._post_reply.uploadProgress.connect(self._onUploadProgress)
            self._post_reply.sslErrors.connect(self._onUploadError)
            # Logger.log("d", "http://%s:80/upload?X-Filename=%s" % (self._address, file_name))
            self._gcode = None
        except IOError as e:
            Logger.log(
                "e",
                "An exception occurred in network connection: %s" % str(e))
            self._progress_message.hide()
            self._error_message = Message(
                i18n_catalog.i18nc("@info:status",
                                   "Send file to printer failed."))
            self._error_message.show()
            self._update_timer.start()
        except Exception as e:
            self._update_timer.start()
            self._progress_message.hide()
            Logger.log(
                "e",
                "An exception occurred in network connection: %s" % str(e))

    def _printFile(self):
        self._sendCommand("M23 " + self._last_file_name)
        self._sendCommand("M24")

    def _onUploadProgress(self, bytes_sent, bytes_total):
        if bytes_total > 0:
            new_progress = bytes_sent / bytes_total * 100
            # Treat upload progress as response. Uploading can take more than 10 seconds, so if we don't, we can get
            # timeout responses if this happens.
            self._last_response_time = time.time()
            if new_progress > self._progress_message.getProgress():
                self._progress_message.show(
                )  # Ensure that the message is visible.
                self._progress_message.setProgress(bytes_sent / bytes_total *
                                                   100)
        else:
            self._progress_message.setProgress(0)
            self._progress_message.hide()

    def _onUploadError(self, reply, sslerror):
        Logger.log("d", "Upload Error")

    def _setHeadPosition(self, x, y, z, speed):
        self._sendCommand("G0 X%s Y%s Z%s F%s" % (x, y, z, speed))

    def _setHeadX(self, x, speed):
        self._sendCommand("G0 X%s F%s" % (x, speed))

    def _setHeadY(self, y, speed):
        self._sendCommand("G0 Y%s F%s" % (y, speed))

    def _setHeadZ(self, z, speed):
        self._sendCommand("G0 Z%s F%s" % (z, speed))

    def _homeHead(self):
        self._sendCommand("G28 X Y")

    def _homeBed(self):
        self._sendCommand("G28 Z")

    def _moveHead(self, x, y, z, speed):
        self._sendCommand(
            ["G91", "G0 X%s Y%s Z%s F%s" % (x, y, z, speed), "G90"])

    def _update(self):
        if self._socket is not None and (self._socket.state() == 2
                                         or self._socket.state() == 3):
            _send_data = "M105\r\nM997\r\n"
            if self.isBusy():
                _send_data += "M994\r\nM992\r\nM27\r\n"
            while self._command_queue.qsize() > 0:
                _queue_data = self._command_queue.get()
                if "M23" in _queue_data:
                    self._socket.writeData(_queue_data.encode())
                    continue
                if "M24" in _queue_data:
                    self._socket.writeData(_queue_data.encode())
                    continue
                _send_data += _queue_data
            # Logger.log("d", "_send_data: \r\n%s" % _send_data)
            self._socket.writeData(_send_data.encode())
            self._socket.flush()
            # self._socket.waitForReadyRead()
        else:
            Logger.log("d", "MKS wifi reconnecting")
            self.disconnect()
            self.connect()

    def _setJobState(self, job_state):
        if job_state == "abort":
            command = "M26"
        elif job_state == "print":
            if self._isPause:
                command = "M25"
            else:
                command = "M24"
        elif job_state == "pause":
            command = "M25"
        if command:
            self._sendCommand(command)

    @pyqtSlot()
    def cancelPrint(self):
        self._sendCommand("M26")

    @pyqtSlot()
    def pausePrint(self):
        if self.printers[0].state == "paused":
            self._sendCommand("M24")
        else:
            self._sendCommand("M25")

    @pyqtSlot()
    def resumePrint(self):
        self._sendCommand("M25")

    def on_read(self):
        if not self._socket:
            self.disconnect()
            return
        try:
            if not self._isConnect:
                self._isConnect = True
            if self._connection_state != UnifiedConnectionState.Connected:
                self._sendCommand("M20")
                self.setConnectionState(
                    cast(ConnectionState, UnifiedConnectionState.Connected))
                self.setConnectionText(
                    i18n_catalog.i18nc("@info:status", "TFT Connect succeed"))
            # ss = str(self._socket.readLine().data(), encoding=sys.getfilesystemencoding())
            # while self._socket.canReadLine():
            # ss = str(self._socket.readLine().data(), encoding=sys.getfilesystemencoding())
            # ss_list = ss.split("\r\n")
            if not self._printers:
                self._createPrinterList()
            printer = self.printers[0]
            while self._socket.canReadLine():
                s = str(self._socket.readLine().data(),
                        encoding=sys.getfilesystemencoding())
                # Logger.log("d", "mks recv: "+s)
                s = s.replace("\r", "").replace("\n", "")
                # if time.time() - self.last_update_time > 10 or time.time() - self.last_update_time<-10:
                #     Logger.log("d", "mks time:"+str(self.last_update_time)+str(time.time()))
                #     self._sendCommand("M20")
                #     self.last_update_time = time.time()
                if "T" in s and "B" in s and "T0" in s:
                    t0_temp = s[s.find("T0:") + len("T0:"):s.find("T1:")]
                    t1_temp = s[s.find("T1:") + len("T1:"):s.find("@:")]
                    bed_temp = s[s.find("B:") + len("B:"):s.find("T0:")]
                    t0_nowtemp = float(t0_temp[0:t0_temp.find("/")])
                    t0_targettemp = float(t0_temp[t0_temp.find("/") +
                                                  1:len(t0_temp)])
                    t1_nowtemp = float(t1_temp[0:t1_temp.find("/")])
                    t1_targettemp = float(t1_temp[t1_temp.find("/") +
                                                  1:len(t1_temp)])
                    bed_nowtemp = float(bed_temp[0:bed_temp.find("/")])
                    bed_targettemp = float(bed_temp[bed_temp.find("/") +
                                                    1:len(bed_temp)])
                    # cura 3.4 new api
                    printer.updateBedTemperature(bed_nowtemp)
                    printer.updateTargetBedTemperature(bed_targettemp)
                    extruder = printer.extruders[0]
                    extruder.updateTargetHotendTemperature(t0_targettemp)
                    extruder.updateHotendTemperature(t0_nowtemp)
                    # self._number_of_extruders = 1
                    # extruder = printer.extruders[1]
                    # extruder.updateHotendTemperature(t1_nowtemp)
                    # extruder.updateTargetHotendTemperature(t1_targettemp)
                    # only on lower 3.4
                    # self._setBedTemperature(bed_nowtemp)
                    # self._updateTargetBedTemperature(bed_targettemp)
                    # if self._num_extruders > 1:
                    # self._setHotendTemperature(1, t1_nowtemp)
                    # self._updateTargetHotendTemperature(1, t1_targettemp)
                    # self._setHotendTemperature(0, t0_nowtemp)
                    # self._updateTargetHotendTemperature(0, t0_targettemp)
                    continue
                if printer.activePrintJob is None:
                    print_job = PrintJobOutputModel(
                        output_controller=self._output_controller)
                    printer.updateActivePrintJob(print_job)
                else:
                    print_job = printer.activePrintJob
                if s.startswith("M997"):
                    job_state = "offline"
                    if "IDLE" in s:
                        self._isPrinting = False
                        self._isPause = False
                        job_state = 'idle'
                    elif "PRINTING" in s:
                        self._isPrinting = True
                        self._isPause = False
                        job_state = 'printing'
                    elif "PAUSE" in s:
                        self._isPrinting = False
                        self._isPause = True
                        job_state = 'paused'
                    print_job.updateState(job_state)
                    printer.updateState(job_state)
                    # self._updateJobState(job_state)
                    continue
                # print_job.updateState('idle')
                # printer.updateState('idle')
                if s.startswith("M994"):
                    if self.isBusy() and s.rfind("/") != -1:
                        self._printing_filename = s[s.rfind("/") +
                                                    1:s.rfind(";")]
                    else:
                        self._printing_filename = ""
                    print_job.updateName(self._printing_filename)
                    # self.setJobName(self._printing_filename)
                    continue
                if s.startswith("M992"):
                    if self.isBusy():
                        tm = s[s.find("M992") + len("M992"):len(s)].replace(
                            " ", "")
                        mms = tm.split(":")
                        self._printing_time = int(mms[0]) * 3600 + int(
                            mms[1]) * 60 + int(mms[2])
                    else:
                        self._printing_time = 0
                    # Logger.log("d", self._printing_time)
                    print_job.updateTimeElapsed(self._printing_time)
                    # self.setTimeElapsed(self._printing_time)
                    # print_job.updateTimeTotal(self._printing_time)
                    # self.setTimeTotal(self._printing_time)
                    continue
                if s.startswith("M27"):
                    if self.isBusy():
                        self._printing_progress = float(
                            s[s.find("M27") + len("M27"):len(s)].replace(
                                " ", ""))
                        totaltime = self._printing_time / self._printing_progress * 100
                    else:
                        self._printing_progress = 0
                        totaltime = self._printing_time * 100
                    # Logger.log("d", self._printing_time)
                    # Logger.log("d", totaltime)
                    # self.setProgress(self._printing_progress)
                    print_job.updateTimeTotal(self._printing_time)
                    print_job.updateTimeElapsed(self._printing_time * 2 -
                                                totaltime)
                    continue
                if 'Begin file list' in s:
                    self._sdFileList = True
                    self.sdFiles = []
                    self.last_update_time = time.time()
                    continue
                if 'End file list' in s:
                    self._sdFileList = False
                    continue
                if self._sdFileList:
                    s = s.replace("\n", "").replace("\r", "")
                    if s.lower().endswith("gcode") or s.lower().endswith(
                            "gco") or s.lower.endswith("g"):
                        self.sdFiles.append(s)
                    continue
        except Exception as e:
            print(e)

    def _updateTargetBedTemperature(self, temperature):
        if self._target_bed_temperature == temperature:
            return False
        self._target_bed_temperature = temperature
        self.targetBedTemperatureChanged.emit()
        return True

    def _updateTargetHotendTemperature(self, index, temperature):
        if self._target_hotend_temperatures[index] == temperature:
            return False
        self._target_hotend_temperatures[index] = temperature
        self.targetHotendTemperaturesChanged.emit()
        return True

    def _createPrinterList(self):
        printer = PrinterOutputModel(
            output_controller=self._output_controller,
            number_of_extruders=self._number_of_extruders)
        printer.updateName(self.name)
        self._printers = [printer]
        self.printersChanged.emit()

    def _onRequestFinished(self, reply):
        http_status_code = reply.attribute(
            QNetworkRequest.HttpStatusCodeAttribute)
        self._isSending = True
        self._update_timer.start()
        self._sendCommand("M20")
        preferences = Application.getInstance().getPreferences()
        preferences.addPreference("mkswifi/autoprint", "True")
        # preferences.addPreference("mkswifi/savepath", "")
        # preferences.setValue("mkswifi/autoprint", str(self._progress_message.getOptionState()))
        if preferences.getValue("mkswifi/autoprint"):
            self._printFile()
        if not http_status_code:
            return

    def _onOptionStateChanged(self, optstate):
        preferences = Application.getInstance().getPreferences()
        preferences.setValue("mkswifi/autoprint", str(optstate))

    def _cancelSendGcode(self, message_id, action_id):
        self._update_timer.start()
        self._isSending = False
        self._progress_message.hide()
        self._post_reply.abort()

    def CreateMKSController(self):
        Logger.log("d", "Creating additional ui components for mkscontroller.")
        # self.__additional_components_view = CuraApplication.getInstance().createQmlComponent(self._monitor_view_qml_path, {"mkscontroller": self})
        self.__additional_components_view = Application.getInstance(
        ).createQmlComponent(self._monitor_view_qml_path, {"manager": self})
        # trlist = CuraApplication.getInstance()._additional_components
        # for comp in trlist:
        Logger.log("w", "create mkscontroller ")
        if not self.__additional_components_view:
            Logger.log("w", "Could not create ui components for tft35.")
            return

    def _onGlobalContainerChanged(self) -> None:
        self._global_container_stack = Application.getInstance(
        ).getGlobalContainerStack()
        definitions = self._global_container_stack.definition.findDefinitions(
            key="cooling")
        Logger.log("d", definitions[0].label)
예제 #24
0
파일: main_window.py 프로젝트: alon/emolog
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, args):
        super().__init__()
        self.socket = QTcpSocket()
        self.socket.connectToHost('localhost', args.port)
        self.socket.readyRead.connect(self.readFromEmotool)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setWindowTitle("EmoTool - {}".format(version()))
        self.main_widget = QtWidgets.QTabWidget(self)
        plot_tab = QtWidgets.QWidget(self.main_widget)
        self.main_widget.addTab(plot_tab, "plot")
        l = QtWidgets.QVBoxLayout(plot_tab)
        self.plot_widget = plot_widget = pg.PlotWidget()
        l.addWidget(plot_widget)
        self.plot_widget = plot_widget
        # TODO - make a menu action, not open by default
        c = pg.console.ConsoleWidget(namespace=globals(), text="test console")
        self.main_widget.addTab(c, "debug")
        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)

        self.statusBar().showMessage("Starting", 2000)

        self.ticks = defaultdict(list)
        self.vals = defaultdict(list)
        self.data_items = defaultdict(pg.PlotDataItem)

        self.incoming = b''
        self.next_message_size = None

    @coalesce_meth(10) # Limit refreshes, they can be costly
    def log_variables(self, msgs):
        """
        Show points on log window. both @ticks and @vars are arrays

        :param msgs: [(ticks_scalar, [(name, value)])]
        :return:
        """
        new_ticks, new_vals = to_dicts(msgs)
        # TODO - better logic. Right now just shows last second, no zoom in possible. Plus second[ticks] is fixed
        last_tick = msgs[-1][0]
        cutoff_tick = last_tick - 8000
        for name in set(self.ticks.keys()) | set(new_ticks.keys()):
            if name not in self.data_items:
                item = self.data_items[name]
                self.plot_widget.addItem(item)
            else:
                item = self.data_items[name]
            ticks = self.ticks[name]
            vals = self.vals[name]
            i_cutoff = bisect_left(ticks, cutoff_tick)
            del ticks[:i_cutoff]
            del vals[:i_cutoff]
            ticks.extend(new_ticks[name])
            vals.extend(new_vals[name])
            item.setData(ticks, vals)
        first_tick = min([ticks[0] for ticks in self.ticks.values()])
        self.plot_widget.setXRange(first_tick, last_tick)

    def readFromEmotool(self):
        """
        This is a temporary measure - instead of the better solution:
         serial2tcp process <-> app
        We have
         serial2tcp process <-> emotool <-> app
        Just to avoid rewriting the emotool parts to drop asyncio support so they can be reused for app and emotool.

        Quick transport costs calculation (copy cost):
        20000 msg/second
        msg size < 100 bytes
        < 2 MB /second
        """
        self.incoming += self.socket.readAll()
        N = len(self.incoming)
        i = 0
        messages = []
        while i < N:
            if self.next_message_size is None:
                if N - i < SIZEOF_UINT32:
                    break
                self.next_message_size, = unpack('<i', self.incoming[i : i + SIZEOF_UINT32])
                i += SIZEOF_UINT32
            if self.next_message_size > N - i:
                break
            data = self.incoming[i : i + self.next_message_size]
            i += self.next_message_size
            messages.extend(loads(data))
            self.next_message_size = None
        self.incoming = self.incoming[i:]
        if len(messages) > 0:
            self.log_variables(messages)


    def fileQuit(self):
        self.close()

    def closeEvent(self, ce):
        self.fileQuit()
예제 #25
0
class VNA(QMainWindow, Ui_VNA):

  max_size = 16384

  def __init__(self):
    super(VNA, self).__init__()
    self.setupUi(self)
    # IP address validator
    rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')
    self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
    # state variables
    self.idle = True
    self.reading = False
    # sweep parameters
    self.sweep_start = 100
    self.sweep_stop = 60000
    self.sweep_size = 600
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    # buffer and offset for the incoming samples
    self.buffer = bytearray(24 * VNA.max_size)
    self.offset = 0
    self.data = np.frombuffer(self.buffer, np.complex64)
    self.adc1 = np.zeros(VNA.max_size, np.complex64)
    self.adc2 = np.zeros(VNA.max_size, np.complex64)
    self.dac1 = np.zeros(VNA.max_size, np.complex64)
    self.open = np.zeros(VNA.max_size, np.complex64)
    self.short = np.zeros(VNA.max_size, np.complex64)
    self.load = np.zeros(VNA.max_size, np.complex64)
    self.dut = np.zeros(VNA.max_size, np.complex64)
    self.mode = 'dut'
    # create figure
    self.figure = Figure()
    self.figure.set_facecolor('none')
    self.canvas = FigureCanvas(self.figure)
    self.plotLayout.addWidget(self.canvas)
    # create navigation toolbar
    self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
    # initialize cursor
    self.cursor = None
    # remove subplots action
    actions = self.toolbar.actions()
    self.toolbar.removeAction(actions[7])
    self.plotLayout.addWidget(self.toolbar)
    # create TCP socket
    self.socket = QTcpSocket(self)
    self.socket.connected.connect(self.connected)
    self.socket.readyRead.connect(self.read_data)
    self.socket.error.connect(self.display_error)
    # connect signals from buttons and boxes
    self.sweepFrame.setEnabled(False)
    self.dutSweep.setEnabled(False)
    self.connectButton.clicked.connect(self.start)
    self.writeButton.clicked.connect(self.write_cfg)
    self.readButton.clicked.connect(self.read_cfg)
    self.openSweep.clicked.connect(self.sweep_open)
    self.shortSweep.clicked.connect(self.sweep_short)
    self.loadSweep.clicked.connect(self.sweep_load)
    self.dutSweep.clicked.connect(self.sweep_dut)
    self.csvButton.clicked.connect(self.write_csv)
    self.s1pButton.clicked.connect(self.write_s1p)
    self.s2pButton.clicked.connect(self.write_s2p)
    self.startValue.valueChanged.connect(self.set_start)
    self.stopValue.valueChanged.connect(self.set_stop)
    self.sizeValue.valueChanged.connect(self.set_size)
    self.rateValue.addItems(['500', '100', '50', '10', '5', '1'])
    self.rateValue.lineEdit().setReadOnly(True)
    self.rateValue.lineEdit().setAlignment(Qt.AlignRight)
    for i in range(0, self.rateValue.count()):
      self.rateValue.setItemData(i, Qt.AlignRight, Qt.TextAlignmentRole)
    self.rateValue.currentIndexChanged.connect(self.set_rate)
    self.corrValue.valueChanged.connect(self.set_corr)
    self.levelValue.valueChanged.connect(self.set_level)
    self.openPlot.clicked.connect(self.plot_open)
    self.shortPlot.clicked.connect(self.plot_short)
    self.loadPlot.clicked.connect(self.plot_load)
    self.dutPlot.clicked.connect(self.plot_dut)
    self.smithPlot.clicked.connect(self.plot_smith)
    self.impPlot.clicked.connect(self.plot_imp)
    self.rcPlot.clicked.connect(self.plot_rc)
    self.swrPlot.clicked.connect(self.plot_swr)
    self.rlPlot.clicked.connect(self.plot_rl)
    self.gainPlot.clicked.connect(self.plot_gain)
    # create timer
    self.startTimer = QTimer(self)
    self.startTimer.timeout.connect(self.timeout)

  def start(self):
    if self.idle:
      self.connectButton.setEnabled(False)
      self.socket.connectToHost(self.addrValue.text(), 1001)
      self.startTimer.start(5000)
    else:
      self.stop()

  def stop(self):
    self.idle = True
    self.socket.abort()
    self.connectButton.setText('Connect')
    self.connectButton.setEnabled(True)
    self.sweepFrame.setEnabled(False)
    self.selectFrame.setEnabled(True)
    self.dutSweep.setEnabled(False)

  def timeout(self):
    self.display_error('timeout')

  def connected(self):
    self.startTimer.stop()
    self.idle = False
    self.set_start(self.startValue.value())
    self.set_stop(self.stopValue.value())
    self.set_size(self.sizeValue.value())
    self.set_rate(self.rateValue.currentIndex())
    self.set_corr(self.corrValue.value())
    self.set_level(self.levelValue.value())
    self.connectButton.setText('Disconnect')
    self.connectButton.setEnabled(True)
    self.sweepFrame.setEnabled(True)
    self.dutSweep.setEnabled(True)

  def read_data(self):
    if not self.reading:
      self.socket.readAll()
      return
    size = self.socket.bytesAvailable()
    self.progress.setValue((self.offset + size) / 24)
    limit = 24 * (self.sweep_size + 1)
    if self.offset + size < limit:
      self.buffer[self.offset:self.offset + size] = self.socket.read(size)
      self.offset += size
    else:
      self.buffer[self.offset:limit] = self.socket.read(limit - self.offset)
      self.adc1 = self.data[0::3]
      self.adc2 = self.data[1::3]
      self.dac1 = self.data[2::3]
      getattr(self, self.mode)[0:self.sweep_size] = self.adc1[1:self.sweep_size + 1] / self.dac1[1:self.sweep_size + 1]
      getattr(self, 'plot_%s' % self.mode)()
      self.reading = False
      self.sweepFrame.setEnabled(True)
      self.selectFrame.setEnabled(True)

  def display_error(self, socketError):
    self.startTimer.stop()
    if socketError == 'timeout':
      QMessageBox.information(self, 'VNA', 'Error: connection timeout.')
    else:
      QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString())
    self.stop()

  def set_start(self, value):
    self.sweep_start = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 0<<28 | int(value * 1000)))

  def set_stop(self, value):
    self.sweep_stop = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 1<<28 | int(value * 1000)))

  def set_size(self, value):
    self.sweep_size = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 2<<28 | int(value)))

  def set_rate(self, value):
    if self.idle: return
    rate = [1, 5, 10, 50, 100, 500][value]
    self.socket.write(struct.pack('<I', 3<<28 | int(rate)))

  def set_corr(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 4<<28 | int(value)))

  def set_level(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 5<<28 | int(32767 * np.power(10.0, value / 20.0))))

  def sweep(self):
    if self.idle: return
    self.sweepFrame.setEnabled(False)
    self.selectFrame.setEnabled(False)
    self.socket.write(struct.pack('<I', 6<<28))
    self.offset = 0
    self.reading = True
    self.progress = QProgressDialog('Sweep status', 'Cancel', 0, self.sweep_size + 1)
    self.progress.setModal(True)
    self.progress.setMinimumDuration(1000)
    self.progress.canceled.connect(self.cancel)

  def cancel(self):
    self.offset = 0
    self.reading = False
    self.socket.write(struct.pack('<I', 7<<28))
    self.sweepFrame.setEnabled(True)
    self.selectFrame.setEnabled(True)

  def sweep_open(self):
    self.mode = 'open'
    self.sweep()

  def sweep_short(self):
    self.mode = 'short'
    self.sweep()

  def sweep_load(self):
    self.mode = 'load'
    self.sweep()

  def sweep_dut(self):
    self.mode = 'dut'
    self.sweep()

  def gain(self):
    size = self.sweep_size
    return self.dut[0:size]/self.short[0:size]

  def impedance(self):
    size = self.sweep_size
    return 50.0 * (self.open[0:size] - self.load[0:size]) * (self.dut[0:size] - self.short[0:size]) / ((self.load[0:size] - self.short[0:size]) * (self.open[0:size] - self.dut[0:size]))

  def gamma(self):
    z = self.impedance()
    return (z - 50.0)/(z + 50.0)

  def plot_gain(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.tick_params('y', color = 'blue', labelcolor = 'blue')
    axes1.yaxis.label.set_color('blue')
    gain = self.gain()
    axes1.plot(self.xaxis, 20.0 * np.log10(np.absolute(gain)), color = 'blue', label = 'Gain')
    axes2 = axes1.twinx()
    axes2.spines['left'].set_color('blue')
    axes2.spines['right'].set_color('red')
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Gain, dB')
    axes2.set_ylabel('Phase angle')
    axes2.tick_params('y', color = 'red', labelcolor = 'red')
    axes2.yaxis.label.set_color('red')
    axes2.plot(self.xaxis, np.angle(gain, deg = True), color = 'red', label = 'Phase angle')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def plot_magphase(self, data):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.tick_params('y', color = 'blue', labelcolor = 'blue')
    axes1.yaxis.label.set_color('blue')
    axes1.plot(self.xaxis, np.absolute(data), color = 'blue', label = 'Magnitude')
    axes2 = axes1.twinx()
    axes2.spines['left'].set_color('blue')
    axes2.spines['right'].set_color('red')
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Magnitude')
    axes2.set_ylabel('Phase angle')
    axes2.tick_params('y', color = 'red', labelcolor = 'red')
    axes2.yaxis.label.set_color('red')
    axes2.plot(self.xaxis, np.angle(data, deg = True), color = 'red', label = 'Phase angle')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def plot_open(self):
    self.plot_magphase(self.open[0:self.sweep_size])

  def plot_short(self):
    self.plot_magphase(self.short[0:self.sweep_size])

  def plot_load(self):
    self.plot_magphase(self.load[0:self.sweep_size])

  def plot_dut(self):
    self.plot_magphase(self.dut[0:self.sweep_size])

  def plot_smith_grid(self, axes, color):
    load = 50.0
    ticks = np.array([0.0, 0.2, 0.5, 1.0, 2.0, 5.0])
    for tick in ticks * load:
      axis = np.logspace(-4, np.log10(1.0e3), 200) * load
      z = tick + 1.0j * axis
      gamma = (z - load)/(z + load)
      axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      z = axis + 1.0j * tick
      gamma = (z - load)/(z + load)
      axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      if tick == 0.0:
        axes.text(1.0, 0.0, u'\u221E', color = color, ha = 'left', va = 'center', clip_on = True, fontsize = 18.0)
        axes.text(-1.0, 0.0, u'0\u03A9', color = color, ha = 'left', va = 'bottom', clip_on = True, fontsize = 12.0)
        continue
      lab = u'%d\u03A9' % tick
      x = (tick - load) / (tick + load)
      axes.text(x, 0.0, lab, color = color, ha = 'left', va = 'bottom', clip_on = True, fontsize = 12.0)
      lab = u'j%d\u03A9' % tick
      z =  1.0j * tick
      gamma = (z - load)/(z + load) * 1.05
      x = gamma.real
      y = gamma.imag
      angle = np.angle(gamma) * 180.0 / np.pi - 90.0
      axes.text(x, y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = angle, fontsize = 12.0)
      lab = u'-j%d\u03A9' % tick
      axes.text(x, -y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = -angle, fontsize = 12.0)

  def plot_smith(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.0, bottom = 0.0, right = 1.0, top = 1.0)
    axes1 = self.figure.add_subplot(111)
    self.plot_smith_grid(axes1, 'blue')
    gamma = self.gamma()
    plot, = axes1.plot(gamma.real, gamma.imag, color = 'red')
    axes1.axis('equal')
    axes1.set_xlim(-1.12, 1.12)
    axes1.set_ylim(-1.12, 1.12)
    axes1.xaxis.set_visible(False)
    axes1.yaxis.set_visible(False)
    for loc, spine in axes1.spines.items():
      spine.set_visible(False)
    self.cursor = datacursor(plot, formatter = SmithFormatter(self.xaxis), display = 'multiple')
    self.canvas.draw()

  def plot_imp(self):
    self.plot_magphase(self.impedance())

  def plot_rc(self):
    self.plot_magphase(self.gamma())

  def plot_swr(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('SWR')
    magnitude = np.absolute(self.gamma())
    swr = np.maximum(1.0, np.minimum(100.0, (1.0 + magnitude) / np.maximum(1.0e-20, 1.0 - magnitude)))
    axes1.plot(self.xaxis, swr, color = 'blue', label = 'SWR')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def plot_rl(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Return loss, dB')
    magnitude = np.absolute(self.gamma())
    axes1.plot(self.xaxis, 20.0 * np.log10(magnitude), color = 'blue', label = 'Return loss')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def write_cfg(self):
    dialog = QFileDialog(self, 'Write configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.write_cfg_settings(settings)

  def read_cfg(self):
    dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.setAcceptMode(QFileDialog.AcceptOpen)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.read_cfg_settings(settings)

  def write_cfg_settings(self, settings):
    settings.setValue('addr', self.addrValue.text())
    settings.setValue('start', self.startValue.value())
    settings.setValue('stop', self.stopValue.value())
    settings.setValue('rate', self.rateValue.currentIndex())
    settings.setValue('corr', self.corrValue.value())
    size = self.sizeValue.value()
    settings.setValue('size', size)
    for i in range(0, size):
      settings.setValue('open_real_%d' % i, float(self.open.real[i]))
      settings.setValue('open_imag_%d' % i, float(self.open.imag[i]))
    for i in range(0, size):
      settings.setValue('short_real_%d' % i, float(self.short.real[i]))
      settings.setValue('short_imag_%d' % i, float(self.short.imag[i]))
    for i in range(0, size):
      settings.setValue('load_real_%d' % i, float(self.load.real[i]))
      settings.setValue('load_imag_%d' % i, float(self.load.imag[i]))
    for i in range(0, size):
      settings.setValue('dut_real_%d' % i, float(self.dut.real[i]))
      settings.setValue('dut_imag_%d' % i, float(self.dut.imag[i]))

  def read_cfg_settings(self, settings):
    self.addrValue.setText(settings.value('addr', '192.168.1.100'))
    self.startValue.setValue(settings.value('start', 100, type = int))
    self.stopValue.setValue(settings.value('stop', 60000, type = int))
    self.rateValue.setCurrentIndex(settings.value('rate', 0, type = int))
    self.corrValue.setValue(settings.value('corr', 0, type = int))
    size = settings.value('size', 600, type = int)
    self.sizeValue.setValue(size)
    for i in range(0, size):
      real = settings.value('open_real_%d' % i, 0.0, type = float)
      imag = settings.value('open_imag_%d' % i, 0.0, type = float)
      self.open[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('short_real_%d' % i, 0.0, type = float)
      imag = settings.value('short_imag_%d' % i, 0.0, type = float)
      self.short[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('load_real_%d' % i, 0.0, type = float)
      imag = settings.value('load_imag_%d' % i, 0.0, type = float)
      self.load[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('dut_real_%d' % i, 0.0, type = float)
      imag = settings.value('dut_imag_%d' % i, 0.0, type = float)
      self.dut[i] = real + 1.0j * imag

  def write_csv(self):
    dialog = QFileDialog(self, 'Write csv file', '.', '*.csv')
    dialog.setDefaultSuffix('csv')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      gamma = self.gamma()
      size = self.sizeValue.value()
      fh.write('frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n')
      for i in range(0, size):
        fh.write('0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (self.xaxis[i], self.open.real[i], self.open.imag[i], self.short.real[i], self.short.imag[i], self.load.real[i], self.load.imag[i], self.dut.real[i], self.dut.imag[i]))
      fh.close()

  def write_s1p(self):
    dialog = QFileDialog(self, 'Write s1p file', '.', '*.s1p')
    dialog.setDefaultSuffix('s1p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      gamma = self.gamma()
      size = self.sizeValue.value()
      fh.write('# GHz S MA R 50\n')
      for i in range(0, size):
        fh.write('0.0%.8d   %8.6f %7.2f\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True)))
      fh.close()

  def write_s2p(self):
    dialog = QFileDialog(self, 'Write s2p file', '.', '*.s2p')
    dialog.setDefaultSuffix('s2p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      gain = self.gain()
      gamma = self.gamma()
      size = self.sizeValue.value()
      fh.write('# GHz S MA R 50\n')
      for i in range(0, size):
        fh.write('0.0%.8d   %8.6f %7.2f   %8.6f %7.2f   0.000000    0.00   0.000000    0.00\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True), np.absolute(gain[i]), np.angle(gain[i], deg = True)))
      fh.close()
예제 #26
0
class Main(QMainWindow):
    def __init__(self, *args):
        super(Main, self).__init__(*args)

        loadUi('mainwindow.ui', self)

        self.host.setText("localhost")
        self.port.setText("11010")
        self.prompt.setText("M114")

        self.conn = QTcpSocket(self)
        self.conn.readyRead.connect(self.readSocket)
        self.conn.error.connect(self.socketError)
        self.conn.connected.connect(self.socketConnect)
        self.conn.disconnected.connect(self.socketDisconnect)

        self.connected = False

        self.actionSave.triggered.connect(self.save)

        self.prompt.setFocus()

        self.do_connect()

    def append(self, text):
        self.text.append(text)

        if self.autoscroll.isChecked():
            c = self.text.textCursor()
            c.movePosition(QTextCursor.End, QTextCursor.MoveAnchor)
            self.text.setTextCursor(c)

    def readSocket(self):
        r = self.conn.readAll()
        if r:
            r = str(r).strip()
            for chunk in r.splitlines():
                if chunk:
                    if chunk[0] == '<':
                        self.text.setTextColor(QColor(200, 0, 0))
                    elif chunk[0] == '>':
                        self.text.setTextColor(QColor(0, 200, 0))
                    else:
                        self.text.setTextColor(QColor(0, 0, 200))

                    self.append(chunk)

    def info(self, errtext):
        self.text.setTextColor(QColor(20, 20, 20))
        self.append(errtext)

    def err(self, errtext):
        self.text.setTextColor(QColor(100, 0, 0))
        self.append(errtext)

    def socketDisconnect(self):
        self.connected = False
        self.err("Disconnected")

    def socketConnect(self):
        self.connected = True
        self.info("Connected")

    def socketError(self, socketError):
        if socketError == QAbstractSocket.RemoteHostClosedError:
            pass
        elif socketError == QAbstractSocket.HostNotFoundError:
            self.err("The host was not found. Please check the host name and "
                     "port settings.")

        elif socketError == QAbstractSocket.ConnectionRefusedError:
            self.err("The connection was refused by the peer. Make sure the "
                     "server is running, and check that the host name "
                     "and port settings are correct.")
        else:
            self.err("The following error occurred: {0}"
                     .format(self.conn.errorString()))

    def save(self):
        fname, sel = QFileDialog.getSaveFileName(
            self,
            'Save Log',)
            #'/path/to/default/directory', FIXME: lastused
            #selectedFilter='*.txt')

        if fname:
            with open(fname, 'w+') as f:
                f.write(self.text.toPlainText())

    def do_connect(self):
        self.conn.abort()
        self.conn.connectToHost(self.host.text(),
                                int(self.port.text()))

    @pyqtSlot()
    def on_connect_clicked(self):
        self.do_connect()
        self.prompt.setFocus()

    @pyqtSlot()
    def on_send_clicked(self):
        if not self.connected:
            self.err("Not connected")
            return
        out = (self.prompt.text() + '\n').encode('ascii')
        self.conn.write(out)

    @pyqtSlot()
    def on_right_on_clicked(self):
        self.action("e1")
예제 #27
0
class Scanner(QMainWindow, Ui_Scanner):
  def __init__(self):
    super(Scanner, self).__init__()
    self.setupUi(self)
    # IP address validator
    rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')
    self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
    # state variable
    self.idle = True
    # number of samples to show on the plot
    self.size = 512 * 512
    self.freq = 143.0
    # buffer and offset for the incoming samples
    self.buffer = bytearray(8 * self.size)
    self.offset = 0
    self.data = np.frombuffer(self.buffer, np.int32)
    # create figure
    figure = Figure()
    figure.set_facecolor('none')
    self.axes = figure.add_subplot(111)
    self.canvas = FigureCanvas(figure)
    self.plotLayout.addWidget(self.canvas)
    self.axes.axis((0.0, 512.0, 0.0, 512.0))
    x, y = np.meshgrid(np.linspace(0.0, 512.0, 513), np.linspace(0.0, 512.0, 513))
    z = x / 512.0 + y * 0.0
    self.mesh = self.axes.pcolormesh(x, y, z, cmap = cm.plasma)
    # create navigation toolbar
    self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
    # remove subplots action
    actions = self.toolbar.actions()
    if int(matplotlib.__version__[0]) < 2:
      self.toolbar.removeAction(actions[7])
    else:
      self.toolbar.removeAction(actions[6])
    self.plotLayout.addWidget(self.toolbar)
    # create TCP socket
    self.socket = QTcpSocket(self)
    self.socket.connected.connect(self.connected)
    self.socket.readyRead.connect(self.read_data)
    self.socket.error.connect(self.display_error)
    # connect signals from buttons and boxes
    self.connectButton.clicked.connect(self.start)
    self.scanButton.clicked.connect(self.scan)
    self.periodValue.valueChanged.connect(self.set_period)
    self.trgtimeValue.valueChanged.connect(self.set_trgtime)
    self.trginvCheck.stateChanged.connect(self.set_trginv)
    self.shdelayValue.valueChanged.connect(self.set_shdelay)
    self.shtimeValue.valueChanged.connect(self.set_shtime)
    self.shinvCheck.stateChanged.connect(self.set_shinv)
    self.acqdelayValue.valueChanged.connect(self.set_acqdelay)
    self.samplesValue.valueChanged.connect(self.set_samples)
    self.pulsesValue.valueChanged.connect(self.set_pulses)
    # create timers
    self.startTimer = QTimer(self)
    self.startTimer.timeout.connect(self.timeout)
    self.meshTimer = QTimer(self)
    self.meshTimer.timeout.connect(self.update_mesh)
    # set default values
    self.periodValue.setValue(200.0)

  def start(self):
    if self.idle:
      self.connectButton.setEnabled(False)
      self.socket.connectToHost(self.addrValue.text(), 1001)
      self.startTimer.start(5000)
    else:
      self.stop()

  def stop(self):
    self.idle = True
    self.socket.abort()
    self.offset = 0
    self.connectButton.setText('Connect')
    self.connectButton.setEnabled(True)
    self.scanButton.setEnabled(True)

  def timeout(self):
    self.display_error('timeout')

  def connected(self):
    self.startTimer.stop()
    self.idle = False
    self.set_period(self.periodValue.value())
    self.set_trgtime(self.trgtimeValue.value())
    self.set_trginv(self.trginvCheck.checkState())
    self.set_shdelay(self.shdelayValue.value())
    self.set_shtime(self.shtimeValue.value())
    self.set_shinv(self.shinvCheck.checkState())
    self.set_acqdelay(self.acqdelayValue.value())
    self.set_samples(self.samplesValue.value())
    self.set_pulses(self.pulsesValue.value())
    # start pulse generators
    self.socket.write(struct.pack('<I', 9<<28))
    self.connectButton.setText('Disconnect')
    self.connectButton.setEnabled(True)
    self.scanButton.setEnabled(True)

  def read_data(self):
    size = self.socket.bytesAvailable()
    if self.offset + size < 8 * self.size:
      self.buffer[self.offset:self.offset + size] = self.socket.read(size)
      self.offset += size
    else:
      self.meshTimer.stop()
      self.buffer[self.offset:8 * self.size] = self.socket.read(8 * self.size - self.offset)
      self.offset = 0
      self.update_mesh()
      self.scanButton.setEnabled(True)

  def display_error(self, socketError):
    self.startTimer.stop()
    if socketError == 'timeout':
      QMessageBox.information(self, 'Scanner', 'Error: connection timeout.')
    else:
      QMessageBox.information(self, 'Scanner', 'Error: %s.' % self.socket.errorString())
    self.stop()

  def set_period(self, value):
    # set maximum delays and times to half period
    maximum = int(value * 5.0 + 0.5) / 10.0
    self.trgtimeValue.setMaximum(maximum)
    self.shdelayValue.setMaximum(maximum)
    self.shtimeValue.setMaximum(maximum)
    self.acqdelayValue.setMaximum(maximum)
    # set maximum number of samples per pulse
    maximum = int(value * 500.0 + 0.5) / 10.0
    if maximum > 256.0: maximum = 256.0
    self.samplesValue.setMaximum(maximum)
    shdelay = value * 0.25
    samples = value * 0.5
    if self.idle: return
    self.socket.write(struct.pack('<I', 0<<28 | int(value * self.freq)))

  def set_trgtime(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 1<<28 | int(value * self.freq)))

  def set_trginv(self, checked):
    if self.idle: return
    self.socket.write(struct.pack('<I', 2<<28 | int(checked == Qt.Checked)))

  def set_shdelay(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 3<<28 | int(value * self.freq)))

  def set_shtime(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 4<<28 | int(value * self.freq)))

  def set_shinv(self, checked):
    if self.idle: return
    self.socket.write(struct.pack('<I', 5<<28 | int(checked == Qt.Checked)))

  def set_acqdelay(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 6<<28 | int(value * self.freq)))

  def set_samples(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 7<<28 | int(value)))

  def set_pulses(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 8<<28 | int(value)))

  def scan(self):
    if self.idle: return
    self.scanButton.setEnabled(False)
    self.data[:] = np.zeros(2 * 512 * 512, np.int32)
    self.update_mesh()
    self.socket.write(struct.pack('<I', 10<<28))
    self.meshTimer.start(1000)

  def update_mesh(self):
    self.mesh.set_array(self.data[0::2]/(self.samplesValue.value() * self.pulsesValue.value() * 8192.0))
    self.canvas.draw()
class TcpSocketClient(QObject, ICommunicateTCPIP):
    readyReadClientID = pyqtSignal(int)
    disconnectedClientID = pyqtSignal(int)

    def __init__(self, parent=None):
        super(TcpSocketClient, self).__init__()
        self.tcpSocketClient = QTcpSocket(parent)
        self.setIsConnected(False)
        self.setTcpClientID(0)
        self.setPeerFullAddrStr(str())
        self.tcpSocketClient.readyRead.connect(self.dataReceived)
        self.connectClientDisconnect(self.disConnected)

    def createConnection(self, ip, port):
        self.tcpSocketClient.connectToHost(ip, port)  # 向目的ip服务器的端口进行连接
        isOK = self.tcpSocketClient.waitForConnected(
            2000)  # 等2s, 若还无法连上服务器就算失败
        self.setIsConnected(isOK)
        return isOK

    def send(self, data):
        """
        发送
        :param data: str or bytearray
        :return: int
        """
        if len(data) == 0 or data is None:
            return
        if isinstance(data, str):
            return self.tcpSocketClient.write(QByteArray(bytes(data, 'utf8')))
        else:
            return self.tcpSocketClient.write(QByteArray(data))

    def connectRec(self, slotRec):
        self.tcpSocketClient.readyRead.connect(slotRec)

    def connectClientDisconnect(self, slotRec):
        self.tcpSocketClient.disconnected.connect(slotRec)

    def read(self):
        """
        读取数据
        :return: bytes
        """
        datagram = self.tcpSocketClient.readAll()
        self.setRecSrcIp(self.tcpSocketClient.peerAddress())
        self.setRecSrcPort(self.tcpSocketClient.peerPort())
        return datagram.data()

    def close(self):
        self.tcpSocketClient.close()

    def connectRecWithClientID(self, slotRec):
        self.readyReadClientID.connect(slotRec)

    def connectDisconnectWithClientID(self, slotRec):
        self.disconnectedClientID.connect(slotRec)

    def setSocketDescriptor(self, socketDescriptor):
        return self.tcpSocketClient.setSocketDescriptor(socketDescriptor)

    @pyqtSlot()
    def dataReceived(self):
        self.readyReadClientID.emit(self.getTcpClientID())

    @pyqtSlot()
    def disConnected(self):
        self.disconnectedClientID.emit(self.getTcpClientID())

    def setIsConnected(self, isConnected):
        self.isConnected = isConnected

    def getIsConnected(self):
        return self.isConnected

    def setTcpClientID(self, tcpClientID):
        self.tcpClientID = tcpClientID

    def getTcpClientID(self):
        return self.tcpClientID

    def setPeerFullAddrStr(self, peerFullAddrStr):
        self.peerFullAddrStr = peerFullAddrStr

    def getPeerFullAddrStr(self):
        return self.peerFullAddrStr

    def getPeerIp(self):
        return self.tcpSocketClient.peerAddress().toString()

    def getPeerPort(self):
        return self.tcpSocketClient.peerPort()
예제 #29
0
class sendMessage(QObject):
    doSomeThing = pyqtSignal(str)  # 收到一条命令去执行

    def __init__(self, parent=None):  # 初始化发送对象,首先要先建立连接
        super(sendMessage, self).__init__(parent)
        self.socket = QTcpSocket()
        self.nextBlockSize = 0
        self.socket.connectToHost(IP, PORT)
        self.deviceInfo = deviceInfo(DEVICE_FIX_ID, REGION_PROVINCE,
                                     REGION_CITY,
                                     REGION_AREA)  # 保存盒子信息,可从某个文件读取
        self.socket.connected.connect(self.initConnected)  # 初始化连接,第一次连上就发送信息
        self.socket.waitForConnected()  # 等待设备连接完成
        time.sleep(0.1)
        self.socket.readyRead.connect(self.readResponse)
        self.socket.disconnected.connect(self.serverHasStopped)
        self.socket.error.connect(self.serverHasError)
        self.doSomeThing.connect(self.doWhat)  # 收到某条命令要执行的函数

    def doWhat(self, order):  # 收到dosome命令要执行的函数
        if order:
            if ',' in order:
                order, model_type = order.split(",")
            else:
                model_type = None
            order_instance = generateOrder(order)
            t = Thread(target=order_instance.run,
                       args=(self.deviceInfo, IP, 8870, model_type))
            t.start()

    def fileToBytes(self, fileName):  # 将文件转换成二进制
        file = QFile(fileName)
        print(file.size())
        count = 0
        with open(fileName, 'rb') as f:
            while 1:
                filedata = f.read(1024)
                if not filedata:
                    break
                count = count + filedata.__len__()
        print(count)

    @startSendMessage
    def initConnected(
            self, stream):  # 每次连接上后 发送盒子的设备信息      fixID(固定id) region(所在地区)
        stream.writeQString('deviceInfo')  # 设定信息类型 state
        deviceInfoToByte = pickle.dumps(
            deviceInfoJson
        )  # 将设备信息序列化成二进制发送    s = pickle.dumps(sendMessage1.deviceInfo)
        stream.writeBytes(deviceInfoToByte)
        '''
        接下来还有几点
        1、盒子连接建立,发送设备信息。接收端接收一次。
        2、规定好发送文件的格式
        3、设计数据库
        4、与网页交互
        '''

    @startSendMessage
    def sendFileBytes(self, stream, filePath,
                      fileBytes):  # stream 由装饰器传值    状态 文件名 文件字节
        file = QFile(filePath)
        print(filePath)
        stream.writeQString('sendFile')  # 发送文件 状态
        stream.writeQString(file.fileName())  # 发送文件的名字
        print(file.size())
        stream.writeQString(str(file.size()))  # 发送文件的大小

        stream.writeBytes(fileBytes)

    def sendFile(self, filePath):
        with open(filePath, 'rb') as f:
            count = 0
            while 1:  # 循环传输

                filedata = f.read(204800)
                print(filedata.__sizeof__())
                if not filedata:
                    break
                self.sendFileBytes(filePath, filedata)
                count = count + filedata.__sizeof__()
                print(count)

    @startSendMessage
    def sendImage(self, stream, imagePath, kind):  # 传递图片,与图片类型    状态 图片类型 图片
        stream.writeQString('sendImage')
        stream.writeQString(kind)
        stream.writeBytes(self.fileToBytes(imagePath))

    @startSendMessage
    def sendResult(
            self, stream, kind, result, startTime,
            usedTime):  # ,发送成功的状态,发送来 success    日期  信号类型 识别结果 识别开始时间 识别时间

        stream.writeQString('successResult')  # 发送成功状态
        dateNow = time.strftime("%Y-%m-%d", time.localtime())
        resultObject = resultInfo(dateNow, kind, result, startTime,
                                  usedTime)  # 结果对象 (日期,类型,结果,开始时间,识别用时)
        resultBytes = pickle.dumps(resultObject)
        stream.writeBytes(resultBytes)

    def readResponse(self):  # 收命令,要做的事情,

        stream = QDataStream(self.socket)
        print('--------------------')
        print('服务器响应')
        stream.setVersion(QDataStream.Qt_5_7)

        while True:
            self.nextBlockSize = 0
            if self.nextBlockSize == 0:
                if self.socket.bytesAvailable() < SIZEOF_UINT16:
                    print('没有内容了')
                    break
                self.nextBlockSize = stream.readUInt16()

            else:
                print('错误')  # 客户端主动断开时,去掉字典中的对应,在这里做一部分操作。
                # 客户端主动断开的时候,要将其从self.myParent.sockeIdToSocketDict   self.myParent.fixIdToSocketIdDict 中删掉

                break
            if self.socket.bytesAvailable() < self.nextBlockSize:
                print("错误2")
                if (not self.socket.waitForReadyRead(60000)
                        or self.socket.bytesAvailable() < self.nextBlockSize):
                    break
            state = stream.readQString()  # 读命令         sendModel
            print('state==' + state)
            if state == 'SENDFILE':
                filename = stream.readQString()  # 读文件名
                fileSize = stream.readInt()  # 读文件大小
                with open('../TEST/' + filename, 'ab') as f:
                    while self.nextBlockSize > 0:
                        fileBytes = stream.readBytes()  # 读文件部分字节
                        f.write(fileBytes)

                        print(fileBytes.__len__())
                        self.nextBlockSize = stream.readUInt64()
                        print('self.nextBlockSize:' + str(self.nextBlockSize))
                        state = stream.readQString()
                        filename = stream.readQString()  # 读文件名
                        fileSize = stream.readInt()  # 读文件大小
                        print('filename:' + filename)
                        print('fileSize:' + str(fileSize))

            elif state == 'test':
                print(stream.readQString())

            elif state == 'ORDER':  # 收到一条命令      要执行的命令
                order = stream.readQString()  # 读是什么命令
                if order:  # shou dao doThing
                    self.doSomeThing.emit(order)

    def serverHasStopped(self):
        print('连接断开')
        self.socket.close()
        self.socket = QTcpSocket()
        print(self.socket.state())
        # while self.socket.state() == 0:
        #     print("重新连接")
        #     time.sleep(5)
        #     self.socket.connectToHost(IP, PORT)
        #     self.socket.waitForConnected()

        # self.socket.close()

    def serverHasError(self, error):
        self.socket.close()
예제 #30
0
파일: IrcWidget.py 프로젝트: Darriall/eric
class IrcWidget(QWidget, Ui_IrcWidget):
    """
    Class implementing the IRC window.
    
    @signal autoConnected() emitted after an automatic connection was initiated
    """
    autoConnected = pyqtSignal()
    
    ServerDisconnected = 1
    ServerConnected = 2
    ServerConnecting = 3
    
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (QWidget)
        """
        super(IrcWidget, self).__init__(parent)
        self.setupUi(self)
        
        from .IrcNetworkManager import IrcNetworkManager
        self.__ircNetworkManager = IrcNetworkManager(self)
        
        self.__leaveButton = QToolButton(self)
        self.__leaveButton.setIcon(
            UI.PixmapCache.getIcon("ircCloseChannel.png"))
        self.__leaveButton.setToolTip(
            self.tr("Press to leave the current channel"))
        self.__leaveButton.clicked.connect(self.__leaveChannel)
        self.__leaveButton.setEnabled(False)
        self.channelsWidget.setCornerWidget(
            self.__leaveButton, Qt.BottomRightCorner)
        self.channelsWidget.setTabsClosable(False)
        if not isMacPlatform():
            self.channelsWidget.setTabPosition(QTabWidget.South)
        
        height = self.height()
        self.splitter.setSizes([height * 0.6, height * 0.4])
        
        self.__channelList = []
        self.__channelTypePrefixes = ""
        self.__userName = ""
        self.__identityName = ""
        self.__quitMessage = ""
        self.__nickIndex = -1
        self.__nickName = ""
        self.__server = None
        self.__registering = False
        
        self.__connectionState = IrcWidget.ServerDisconnected
        self.__sslErrorLock = False
        
        self.__buffer = ""
        self.__userPrefix = {}
        
        self.__socket = None
        if SSL_AVAILABLE:
            self.__sslErrorHandler = E5SslErrorHandler(self)
        else:
            self.__sslErrorHandler = None
        
        self.__patterns = [
            # :[email protected] PRIVMSG bar_ :some long message
            (re.compile(r":([^!]+)!([^ ]+)\sPRIVMSG\s([^ ]+)\s:(.*)"),
             self.__query),
            # :foo.bar.net COMMAND some message
            (re.compile(r""":([^ ]+)\s+([A-Z]+)\s+(.+)"""),
             self.__handleNamedMessage),
            # :foo.bar.net 123 * :info
            (re.compile(r""":([^ ]+)\s+(\d{3})\s+(.+)"""),
             self.__handleNumericMessage),
            # PING :ping message
            (re.compile(r"""PING\s+:(.*)"""), self.__ping),
        ]
        self.__prefixRe = re.compile(r""".*\sPREFIX=\((.*)\)([^ ]+).*""")
        self.__chanTypesRe = re.compile(r""".*\sCHANTYPES=([^ ]+).*""")
        
        ircPic = UI.PixmapCache.getPixmap("irc128.png")
        self.__emptyLabel = QLabel()
        self.__emptyLabel.setPixmap(ircPic)
        self.__emptyLabel.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter)
        self.channelsWidget.addTab(self.__emptyLabel, "")
        
        # all initialized, do connections now
        self.__ircNetworkManager.dataChanged.connect(self.__networkDataChanged)
        self.networkWidget.initialize(self.__ircNetworkManager)
        self.networkWidget.connectNetwork.connect(self.__connectNetwork)
        self.networkWidget.editNetwork.connect(self.__editNetwork)
        self.networkWidget.joinChannel.connect(self.__joinChannel)
        self.networkWidget.nickChanged.connect(self.__changeNick)
        self.networkWidget.sendData.connect(self.__send)
        self.networkWidget.away.connect(self.__away)
        self.networkWidget.autoConnected.connect(self.autoConnected)
    
    def shutdown(self):
        """
        Public method to shut down the widget.
        
        @return flag indicating successful shutdown (boolean)
        """
        if self.__server:
            if Preferences.getIrc("AskOnShutdown"):
                ok = E5MessageBox.yesNo(
                    self,
                    self.tr("Disconnect from Server"),
                    self.tr(
                        """<p>Do you really want to disconnect from"""
                        """ <b>{0}</b>?</p><p>All channels will be closed."""
                        """</p>""").format(self.__server.getName()))
            else:
                ok = True
            if ok:
                self.__socket.blockSignals(True)
                
                self.__send("QUIT :" + self.__quitMessage)
                self.__socket.flush()
                self.__socket.close()
                self.__socket.deleteLater()
                self.__socket = None
        else:
            ok = True
        
        if ok:
            self.__ircNetworkManager.close()
        return ok
    
    def autoConnect(self):
        """
        Public method to initiate the IRC auto connection.
        """
        self.networkWidget.autoConnect()

    def __connectNetwork(self, name, connect, silent=False):
        """
        Private slot to connect to or disconnect from the given network.
        
        @param name name of the network to connect to (string)
        @param connect flag indicating to connect (boolean)
        @keyparam silent flag indicating a silent connect/disconnect (boolean)
        """
        if connect:
            network = self.__ircNetworkManager.getNetwork(name)
            if network:
                self.__server = network.getServer()
                self.__identityName = network.getIdentityName()
                identity = self.__ircNetworkManager.getIdentity(
                    self.__identityName)
                self.__userName = identity.getIdent()
                self.__quitMessage = identity.getQuitMessage()
                if self.__server:
                    useSSL = self.__server.useSSL()
                    if useSSL and not SSL_AVAILABLE:
                        E5MessageBox.critical(
                            self,
                            self.tr("SSL Connection"),
                            self.tr(
                                """An encrypted connection to the IRC"""
                                """ network was requested but SSL is not"""
                                """ available. Please change the server"""
                                """ configuration."""))
                        return
                    
                    if useSSL:
                        # create SSL socket
                        self.__socket = QSslSocket(self)
                        self.__socket.encrypted.connect(self.__hostConnected)
                        self.__socket.sslErrors.connect(self.__sslErrors)
                    else:
                        # create TCP socket
                        self.__socket = QTcpSocket(self)
                        self.__socket.connected.connect(self.__hostConnected)
                    self.__socket.hostFound.connect(self.__hostFound)
                    self.__socket.disconnected.connect(self.__hostDisconnected)
                    self.__socket.readyRead.connect(self.__readyRead)
                    self.__socket.error.connect(self.__tcpError)
                    
                    self.__connectionState = IrcWidget.ServerConnecting
                    if useSSL:
                        self.networkWidget.addServerMessage(
                            self.tr("Info"),
                            self.tr("Looking for server {0} (port {1})"
                                    " using an SSL encrypted connection"
                                    "...").format(self.__server.getName(),
                                                  self.__server.getPort()))
                        self.__socket.connectToHostEncrypted(
                            self.__server.getName(), self.__server.getPort())
                    else:
                        self.networkWidget.addServerMessage(
                            self.tr("Info"),
                            self.tr(
                                "Looking for server {0} (port {1})...").format(
                                self.__server.getName(),
                                self.__server.getPort()))
                        self.__socket.connectToHost(self.__server.getName(),
                                                    self.__server.getPort())
        else:
            if silent:
                ok = True
            else:
                ok = E5MessageBox.yesNo(
                    self,
                    self.tr("Disconnect from Server"),
                    self.tr("""<p>Do you really want to disconnect from"""
                            """ <b>{0}</b>?</p><p>All channels will be"""
                            """ closed.</p>""")
                    .format(self.__server.getName()))
            if ok:
                self.networkWidget.addServerMessage(
                    self.tr("Info"),
                    self.tr("Disconnecting from server {0}...").format(
                        self.__server.getName()))
                self.__closeAllChannels()
                self.__send("QUIT :" + self.__quitMessage)
                self.__socket and self.__socket.flush()
                self.__socket and self.__socket.close()
                self.__userName = ""
                self.__identityName = ""
                self.__quitMessage = ""
    
    def __editNetwork(self, name):
        """
        Private slot to edit the network configuration.
        
        @param name name of the network to edit (string)
        """
        from .IrcNetworkListDialog import IrcNetworkListDialog
        dlg = IrcNetworkListDialog(self.__ircNetworkManager, self)
        dlg.exec_()
    
    def __networkDataChanged(self):
        """
        Private slot handling changes of the network and identity definitions.
        """
        identity = self.__ircNetworkManager.getIdentity(self.__identityName)
        if identity:
            partMsg = identity.getPartMessage()
            for channel in self.__channelList:
                channel.setPartMessage(partMsg)
    
    def __joinChannel(self, name, key=""):
        """
        Private slot to join a channel.
        
        @param name name of the channel (string)
        @param key key of the channel (string)
        """
        # step 1: check, if this channel is already joined
        for channel in self.__channelList:
            if channel.name() == name:
                return
        
        from .IrcChannelWidget import IrcChannelWidget
        channel = IrcChannelWidget(self)
        channel.setName(name)
        channel.setUserName(self.__nickName)
        identity = self.__ircNetworkManager.getIdentity(self.__identityName)
        channel.setPartMessage(identity.getPartMessage())
        channel.setUserPrivilegePrefix(self.__userPrefix)
        channel.initAutoWho()
        
        channel.sendData.connect(self.__send)
        channel.sendCtcpReply.connect(self.__sendCtcpReply)
        channel.channelClosed.connect(self.__closeChannel)
        channel.openPrivateChat.connect(self.__openPrivate)
        
        self.channelsWidget.addTab(channel, name)
        self.__channelList.append(channel)
        self.channelsWidget.setCurrentWidget(channel)
        
        joinCommand = ["JOIN", name]
        if key:
            joinCommand.append(key)
        self.__send(" ".join(joinCommand))
        self.__send("MODE " + name)
        
        emptyIndex = self.channelsWidget.indexOf(self.__emptyLabel)
        if emptyIndex > -1:
            self.channelsWidget.removeTab(emptyIndex)
            self.__leaveButton.setEnabled(True)
        self.channelsWidget.setTabsClosable(True)
    
    def __query(self, match):
        """
        Private method to handle a new private connection.
        
        @param match reference to the match object
        @return flag indicating, if the message was handled (boolean)
        """
        # group(1)   sender user name
        # group(2)   sender user@host
        # group(3)   target nick
        # group(4)   message
        if match.group(4).startswith("\x01"):
            return self.__handleCtcp(match)
        
        self.__openPrivate(match.group(1))
        # the above call sets the new channel as the current widget
        channel = self.channelsWidget.currentWidget()
        channel.addMessage(match.group(1), match.group(4))
        channel.setPrivateInfo(
            "{0} - {1}".format(match.group(1), match.group(2)))
        
        return True
    
    @pyqtSlot(str)
    def __openPrivate(self, name):
        """
        Private slot to open a private chat with the given user.
        
        @param name name of the user (string)
        """
        from .IrcChannelWidget import IrcChannelWidget
        channel = IrcChannelWidget(self)
        channel.setName(self.__nickName)
        channel.setUserName(self.__nickName)
        identity = self.__ircNetworkManager.getIdentity(self.__identityName)
        channel.setPartMessage(identity.getPartMessage())
        channel.setUserPrivilegePrefix(self.__userPrefix)
        channel.setPrivate(True, name)
        channel.addUsers([name, self.__nickName])
        
        channel.sendData.connect(self.__send)
        channel.sendCtcpReply.connect(self.__sendCtcpReply)
        channel.channelClosed.connect(self.__closeChannel)
        
        self.channelsWidget.addTab(channel, name)
        self.__channelList.append(channel)
        self.channelsWidget.setCurrentWidget(channel)
    
    @pyqtSlot()
    def __leaveChannel(self):
        """
        Private slot to leave a channel and close the associated tab.
        """
        channel = self.channelsWidget.currentWidget()
        channel.requestLeave()
    
    def __closeAllChannels(self):
        """
        Private method to close all channels.
        """
        while self.__channelList:
            channel = self.__channelList.pop()
            self.channelsWidget.removeTab(self.channelsWidget.indexOf(channel))
            channel.deleteLater()
            channel = None
        
        self.channelsWidget.addTab(self.__emptyLabel, "")
        self.__emptyLabel.show()
        self.__leaveButton.setEnabled(False)
        self.channelsWidget.setTabsClosable(False)
    
    def __closeChannel(self, name):
        """
        Private slot handling the closing of a channel.
        
        @param name name of the closed channel (string)
        """
        for channel in self.__channelList:
            if channel.name() == name:
                self.channelsWidget.removeTab(
                    self.channelsWidget.indexOf(channel))
                self.__channelList.remove(channel)
                channel.deleteLater()
        
        if self.channelsWidget.count() == 0:
            self.channelsWidget.addTab(self.__emptyLabel, "")
            self.__emptyLabel.show()
            self.__leaveButton.setEnabled(False)
            self.channelsWidget.setTabsClosable(False)
    
    @pyqtSlot(int)
    def on_channelsWidget_tabCloseRequested(self, index):
        """
        Private slot to close a channel by pressing the close button of
        the channels widget.
        
        @param index index of the tab to be closed (integer)
        """
        channel = self.channelsWidget.widget(index)
        channel.requestLeave()
    
    def __send(self, data):
        """
        Private slot to send data to the IRC server.
        
        @param data data to be sent (string)
        """
        if self.__socket:
            self.__socket.write(
                QByteArray("{0}\r\n".format(data).encode("utf-8")))
    
    def __sendCtcpReply(self, receiver, text):
        """
        Private slot to send a CTCP reply.
        
        @param receiver nick name of the receiver (string)
        @param text text to be sent (string)
        """
        self.__send("NOTICE {0} :\x01{1}\x01".format(receiver, text))
    
    def __hostFound(self):
        """
        Private slot to indicate the host was found.
        """
        self.networkWidget.addServerMessage(
            self.tr("Info"),
            self.tr("Server found,connecting..."))
    
    def __hostConnected(self):
        """
        Private slot to log in to the server after the connection was
        established.
        """
        self.networkWidget.addServerMessage(
            self.tr("Info"),
            self.tr("Connected,logging in..."))
        self.networkWidget.setConnected(True)
        
        self.__registering = True
        serverPassword = self.__server.getPassword()
        if serverPassword:
            self.__send("PASS " + serverPassword)
        nick = self.networkWidget.getNickname()
        if not nick:
            self.__nickIndex = 0
            try:
                nick = self.__ircNetworkManager.getIdentity(
                    self.__identityName).getNickNames()[self.__nickIndex]
            except IndexError:
                nick = ""
        if not nick:
            nick = self.__userName
        self.__nickName = nick
        self.networkWidget.setNickName(nick)
        realName = self.__ircNetworkManager.getIdentity(
            self.__identityName).getRealName()
        if not realName:
            realName = "eric IDE chat"
        self.__send("NICK " + nick)
        self.__send("USER " + self.__userName + " 0 * :" + realName)
    
    def __hostDisconnected(self):
        """
        Private slot to indicate the host was disconnected.
        """
        if self.networkWidget.isConnected():
            self.__closeAllChannels()
            self.networkWidget.addServerMessage(
                self.tr("Info"),
                self.tr("Server disconnected."))
            self.networkWidget.setRegistered(False)
            self.networkWidget.setConnected(False)
            self.__server = None
            self.__nickName = ""
            self.__nickIndex = -1
            self.__channelTypePrefixes = ""
            
            self.__socket.deleteLater()
            self.__socket = None
            
            self.__connectionState = IrcWidget.ServerDisconnected
            self.__sslErrorLock = False
    
    def __readyRead(self):
        """
        Private slot to read data from the socket.
        """
        if self.__socket:
            self.__buffer += str(
                self.__socket.readAll(),
                Preferences.getSystem("IOEncoding"),
                'replace')
            if self.__buffer.endswith("\r\n"):
                for line in self.__buffer.splitlines():
                    line = line.strip()
                    if line:
                        logging.debug("<IRC> " + line)
                        handled = False
                        # step 1: give channels a chance to handle the message
                        for channel in self.__channelList:
                            handled = channel.handleMessage(line)
                            if handled:
                                break
                        else:
                            # step 2: try to process the message ourselves
                            for patternRe, patternFunc in self.__patterns:
                                match = patternRe.match(line)
                                if match is not None:
                                    if patternFunc(match):
                                        break
                            else:
                                # Oops, the message wasn't handled
                                self.networkWidget.addErrorMessage(
                                    self.tr("Message Error"),
                                    self.tr(
                                        "Unknown message received from server:"
                                        "<br/>{0}").format(line))
                
                self.__updateUsersCount()
                self.__buffer = ""
    
    def __handleNamedMessage(self, match):
        """
        Private method to handle a server message containing a message name.
        
        @param match reference to the match object
        @return flag indicating, if the message was handled (boolean)
        """
        name = match.group(2)
        if name == "NOTICE":
            try:
                msg = match.group(3).split(":", 1)[1]
            except IndexError:
                msg = match.group(3)
            if "!" in match.group(1):
                name = match.group(1).split("!", 1)[0]
                msg = "-{0}- {1}".format(name, msg)
            self.networkWidget.addServerMessage(self.tr("Notice"), msg)
            return True
        elif name == "MODE":
            self.__registering = False
            if ":" in match.group(3):
                # :detlev_ MODE detlev_ :+i
                name, modes = match.group(3).split(" :")
                sourceNick = match.group(1)
                if not self.isChannelName(name):
                    if name == self.__nickName:
                        if sourceNick == self.__nickName:
                            msg = self.tr(
                                "You have set your personal modes to"
                                " <b>[{0}]</b>.").format(modes)
                        else:
                            msg = self.tr(
                                "{0} has changed your personal modes to"
                                " <b>[{1}]</b>.").format(sourceNick, modes)
                        self.networkWidget.addServerMessage(
                            self.tr("Mode"), msg, filterMsg=False)
                        return True
        elif name == "PART":
            nick = match.group(1).split("!", 1)[0]
            if nick == self.__nickName:
                channel = match.group(3).split(None, 1)[0]
                self.networkWidget.addMessage(
                    self.tr("You have left channel {0}.").format(channel))
                return True
        elif name == "QUIT":
            # don't do anything with it here
            return True
        elif name == "NICK":
            # :[email protected] NICK :newnick
            oldNick = match.group(1).split("!", 1)[0]
            newNick = match.group(3).split(":", 1)[1]
            if oldNick == self.__nickName:
                self.networkWidget.addMessage(
                    self.tr("You are now known as {0}.").format(newNick))
                self.__nickName = newNick
                self.networkWidget.setNickName(newNick)
            else:
                self.networkWidget.addMessage(
                    self.tr("User {0} is now known as {1}.").format(
                        oldNick, newNick))
            return True
        elif name == "ERROR":
            self.networkWidget.addErrorMessage(
                self.tr("Server Error"), match.group(3).split(":", 1)[1])
            return True
        
        return False
    
    def __handleNumericMessage(self, match):
        """
        Private method to handle a server message containing a numeric code.
        
        @param match reference to the match object
        @return flag indicating, if the message was handled (boolean)
        """
        code = int(match.group(2))
        if code < 400:
            return self.__handleServerReply(
                code, match.group(1), match.group(3))
        else:
            return self.__handleServerError(
                code, match.group(1), match.group(3))
    
    def __handleServerError(self, code, server, message):
        """
        Private slot to handle a server error reply.
        
        @param code numerical code sent by the server (integer)
        @param server name of the server (string)
        @param message message sent by the server (string)
        @return flag indicating, if the message was handled (boolean)
        """
        if code == 433:
            if self.__registering:
                self.__handleNickInUseLogin()
            else:
                self.__handleNickInUse()
        else:
            self.networkWidget.addServerMessage(self.tr("Error"), message)
        
        return True
    
    def __handleServerReply(self, code, server, message):
        """
        Private slot to handle a server reply.
        
        @param code numerical code sent by the server (integer)
        @param server name of the server (string)
        @param message message sent by the server (string)
        @return flag indicating, if the message was handled (boolean)
        """
        # determine message type
        if code in [1, 2, 3, 4]:
            msgType = self.tr("Welcome")
        elif code == 5:
            msgType = self.tr("Support")
        elif code in [250, 251, 252, 253, 254, 255, 265, 266]:
            msgType = self.tr("User")
        elif code in [372, 375, 376]:
            msgType = self.tr("MOTD")
        elif code in [305, 306]:
            msgType = self.tr("Away")
        else:
            msgType = self.tr("Info ({0})").format(code)
        
        # special treatment for some messages
        if code == 375:
            message = self.tr("Message of the day")
        elif code == 376:
            message = self.tr("End of message of the day")
        elif code == 4:
            parts = message.strip().split()
            message = self.tr(
                "Server {0} (Version {1}), User-Modes: {2},"
                " Channel-Modes: {3}")\
                .format(parts[1], parts[2], parts[3], parts[4])
        elif code == 265:
            parts = message.strip().split()
            message = self.tr(
                "Current users on {0}: {1}, max. {2}").format(
                server, parts[1], parts[2])
        elif code == 266:
            parts = message.strip().split()
            message = self.tr(
                "Current users on the network: {0}, max. {1}").format(
                parts[1], parts[2])
        elif code == 305:
            message = self.tr("You are no longer marked as being away.")
        elif code == 306:
            message = self.tr("You have been marked as being away.")
        else:
            first, message = message.split(None, 1)
            if message.startswith(":"):
                message = message[1:]
            else:
                message = message.replace(":", "", 1)
        
        self.networkWidget.addServerMessage(msgType, message)
        
        if code == 1:
            # register with services after the welcome message
            self.__connectionState = IrcWidget.ServerConnected
            self.__registerWithServices()
            self.networkWidget.setRegistered(True)
            QTimer.singleShot(1000, self.__autoJoinChannels)
        elif code == 5:
            # extract the user privilege prefixes
            # ... PREFIX=(ov)@+ ...
            m = self.__prefixRe.match(message)
            if m:
                self.__setUserPrivilegePrefix(m.group(1), m.group(2))
            # extract the channel type prefixes
            # ... CHANTYPES=# ...
            m = self.__chanTypesRe.match(message)
            if m:
                self.__setChannelTypePrefixes(m.group(1))
        
        return True
    
    def __registerWithServices(self):
        """
        Private method to register to services.
        """
        identity = self.__ircNetworkManager.getIdentity(self.__identityName)
        service = identity.getServiceName()
        password = identity.getPassword()
        if service and password:
            self.__send("PRIVMSG " + service + " :identify " + password)
    
    def __autoJoinChannels(self):
        """
        Private slot to join channels automatically once a server got
        connected.
        """
        for channel in self.networkWidget.getNetworkChannels():
            if channel.autoJoin():
                name = channel.getName()
                key = channel.getKey()
                self.__joinChannel(name, key)
    
    def __tcpError(self, error):
        """
        Private slot to handle errors reported by the TCP socket.
        
        @param error error code reported by the socket
            (QAbstractSocket.SocketError)
        """
        if error == QAbstractSocket.RemoteHostClosedError:
            # ignore this one, it's a disconnect
            if self.__sslErrorLock:
                self.networkWidget.addErrorMessage(
                    self.tr("SSL Error"),
                    self.tr(
                        """Connection to server {0} (port {1}) lost while"""
                        """ waiting for user response to an SSL error.""")
                    .format(self.__server.getName(), self.__server.getPort()))
                self.__connectionState = IrcWidget.ServerDisconnected
        elif error == QAbstractSocket.HostNotFoundError:
            self.networkWidget.addErrorMessage(
                self.tr("Socket Error"),
                self.tr(
                    "The host was not found. Please check the host name"
                    " and port settings."))
        elif error == QAbstractSocket.ConnectionRefusedError:
            self.networkWidget.addErrorMessage(
                self.tr("Socket Error"),
                self.tr(
                    "The connection was refused by the peer. Please check the"
                    " host name and port settings."))
        elif error == QAbstractSocket.SslHandshakeFailedError:
            self.networkWidget.addErrorMessage(
                self.tr("Socket Error"),
                self.tr("The SSL handshake failed."))
        else:
            if self.__socket:
                self.networkWidget.addErrorMessage(
                    self.tr("Socket Error"),
                    self.tr(
                        "The following network error occurred:<br/>{0}")
                    .format(self.__socket.errorString()))
            else:
                self.networkWidget.addErrorMessage(
                    self.tr("Socket Error"),
                    self.tr("A network error occurred."))
    
    def __sslErrors(self, errors):
        """
        Private slot to handle SSL errors.
        
        @param errors list of SSL errors (list of QSslError)
        """
        ignored, defaultChanged = self.__sslErrorHandler.sslErrors(
            errors, self.__server.getName(), self.__server.getPort())
        if ignored == E5SslErrorHandler.NotIgnored:
            self.networkWidget.addErrorMessage(
                self.tr("SSL Error"),
                self.tr(
                    """Could not connect to {0} (port {1}) using an SSL"""
                    """ encrypted connection. Either the server does not"""
                    """ support SSL (did you use the correct port?) or"""
                    """ you rejected the certificate.""")
                .format(self.__server.getName(), self.__server.getPort()))
            self.__socket.close()
        else:
            if defaultChanged:
                self.__socket.setSslConfiguration(
                    QSslConfiguration.defaultConfiguration())
            if ignored == E5SslErrorHandler.UserIgnored:
                self.networkWidget.addErrorMessage(
                    self.tr("SSL Error"),
                    self.tr(
                        """The SSL certificate for the server {0} (port {1})"""
                        """ failed the authenticity check. SSL errors"""
                        """ were accepted by you.""")
                    .format(self.__server.getName(), self.__server.getPort()))
            if self.__connectionState == IrcWidget.ServerConnecting:
                self.__socket.ignoreSslErrors()
    
    def __setUserPrivilegePrefix(self, prefix1, prefix2):
        """
        Private method to set the user privilege prefix.
        
        @param prefix1 first part of the prefix (string)
        @param prefix2 indictors the first part gets mapped to (string)
        """
        # PREFIX=(ov)@+
        # o = @ -> @ircbot , channel operator
        # v = + -> +userName , voice operator
        for i in range(len(prefix1)):
            self.__userPrefix["+" + prefix1[i]] = prefix2[i]
            self.__userPrefix["-" + prefix1[i]] = ""
    
    def __ping(self, match):
        """
        Private method to handle a PING message.
        
        @param match reference to the match object
        @return flag indicating, if the message was handled (boolean)
        """
        self.__send("PONG " + match.group(1))
        return True
    
    def __handleCtcp(self, match):
        """
        Private method to handle a CTCP command.
        
        @param match reference to the match object
        @return flag indicating, if the message was handled (boolean)
        """
        # group(1)   sender user name
        # group(2)   sender user@host
        # group(3)   target nick
        # group(4)   message
        if match.group(4).startswith("\x01"):
            ctcpCommand = match.group(4)[1:].split("\x01", 1)[0]
            if " " in ctcpCommand:
                ctcpRequest, ctcpArg = ctcpCommand.split(" ", 1)
            else:
                ctcpRequest, ctcpArg = ctcpCommand, ""
            ctcpRequest = ctcpRequest.lower()
            if ctcpRequest == "version":
                if Version.startswith("@@"):
                    vers = ""
                else:
                    vers = " " + Version
                msg = "Eric IRC client{0}, {1}".format(vers, Copyright)
                self.networkWidget.addServerMessage(
                    self.tr("CTCP"),
                    self.tr("Received Version request from {0}.").format(
                        match.group(1)))
                self.__sendCtcpReply(match.group(1), "VERSION " + msg)
            elif ctcpRequest == "ping":
                self.networkWidget.addServerMessage(
                    self.tr("CTCP"),
                    self.tr(
                        "Received CTCP-PING request from {0},"
                        " sending answer.").format(match.group(1)))
                self.__sendCtcpReply(
                    match.group(1), "PING {0}".format(ctcpArg))
            elif ctcpRequest == "clientinfo":
                self.networkWidget.addServerMessage(
                    self.tr("CTCP"),
                    self.tr(
                        "Received CTCP-CLIENTINFO request from {0},"
                        " sending answer.").format(match.group(1)))
                self.__sendCtcpReply(
                    match.group(1),
                    "CLIENTINFO CLIENTINFO PING VERSION")
            else:
                self.networkWidget.addServerMessage(
                    self.tr("CTCP"),
                    self.tr(
                        "Received unknown CTCP-{0} request from {1}.")
                    .format(ctcpRequest, match.group(1)))
            return True
        
        return False
    
    def __updateUsersCount(self):
        """
        Private method to update the users count on the channel tabs.
        """
        for channel in self.__channelList:
            index = self.channelsWidget.indexOf(channel)
            self.channelsWidget.setTabText(
                index,
                self.tr("{0} ({1})", "channel name, users count").format(
                    channel.name(), channel.getUsersCount()))
    
    def __handleNickInUseLogin(self):
        """
        Private method to handle a 443 server error at login.
        """
        self.__nickIndex += 1
        try:
            nick = self.__ircNetworkManager.getIdentity(self.__identityName)\
                .getNickNames()[self.__nickIndex]
            self.__nickName = nick
        except IndexError:
            self.networkWidget.addServerMessage(
                self.tr("Critical"),
                self.tr(
                    "No nickname acceptable to the server configured"
                    " for <b>{0}</b>. Disconnecting...")
                .format(self.__userName),
                filterMsg=False)
            self.__connectNetwork("", False, silent=True)
            self.__nickName = ""
            self.__nickIndex = -1
            return
        
        self.networkWidget.setNickName(nick)
        self.__send("NICK " + nick)
    
    def __handleNickInUse(self):
        """
        Private method to handle a 443 server error.
        """
        self.networkWidget.addServerMessage(
            self.tr("Critical"),
            self.tr("The given nickname is already in use."))
    
    def __changeNick(self, nick):
        """
        Private slot to use a new nick name.
        
        @param nick nick name to use (str)
        """
        if nick and nick != self.__nickName:
            self.__send("NICK " + nick)
    
    def __setChannelTypePrefixes(self, prefixes):
        """
        Private method to set the channel type prefixes.
        
        @param prefixes channel prefix characters (string)
        """
        self.__channelTypePrefixes = prefixes
    
    def isChannelName(self, name):
        """
        Public method to check, if the given name is a channel name.
        
        @param name name to check (string)
        @return flag indicating a channel name (boolean)
        """
        if not name:
            return False
        
        if self.__channelTypePrefixes:
            return name[0] in self.__channelTypePrefixes
        else:
            return name[0] in "#&"
    
    def __away(self, isAway):
        """
        Private slot handling the change of the away state.
        
        @param isAway flag indicating the current away state (boolean)
        """
        if isAway and self.__identityName:
            identity = self.__ircNetworkManager.getIdentity(
                self.__identityName)
            if identity.rememberAwayPosition():
                for channel in self.__channelList:
                    channel.setMarkerLine()
예제 #31
0
class Dialog(QDialog):
    TotalBytes = 50 * 1024 * 1024
    PayloadSize = 65536

    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)

        self.tcpServer = QTcpServer()
        self.tcpClient = QTcpSocket()
        self.bytesToWrite = 0
        self.bytesWritten = 0
        self.bytesReceived = 0

        self.clientProgressBar = QProgressBar()
        self.clientStatusLabel = QLabel("Client ready")
        self.serverProgressBar = QProgressBar()
        self.serverStatusLabel = QLabel("Server ready")

        self.startButton = QPushButton("&Start")
        self.quitButton = QPushButton("&Quit")

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.startButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(self.quitButton, QDialogButtonBox.RejectRole)

        self.startButton.clicked.connect(self.start)
        self.quitButton.clicked.connect(self.close)
        self.tcpServer.newConnection.connect(self.acceptConnection)
        self.tcpClient.connected.connect(self.startTransfer)
        self.tcpClient.bytesWritten.connect(self.updateClientProgress)
        self.tcpClient.error.connect(self.displayError)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.clientProgressBar)
        mainLayout.addWidget(self.clientStatusLabel)
        mainLayout.addWidget(self.serverProgressBar)
        mainLayout.addWidget(self.serverStatusLabel)
        mainLayout.addStretch(1)
        mainLayout.addSpacing(10)
        mainLayout.addWidget(buttonBox)
        self.setLayout(mainLayout)

        self.setWindowTitle("Loopback")

    def start(self):
        self.startButton.setEnabled(False)

        QApplication.setOverrideCursor(Qt.WaitCursor)

        self.bytesWritten = 0
        self.bytesReceived = 0

        while not self.tcpServer.isListening() and not self.tcpServer.listen():
            ret = QMessageBox.critical(
                self,
                "Loopback",
                "Unable to start the test: %s." % self.tcpServer.errorString(),
                QMessageBox.Retry | QMessageBox.Cancel,
            )
            if ret == QMessageBox.Cancel:
                return

        self.serverStatusLabel.setText("Listening")
        self.clientStatusLabel.setText("Connecting")

        self.tcpClient.connectToHost(QHostAddress(QHostAddress.LocalHost),
                                     self.tcpServer.serverPort())

    def acceptConnection(self):
        self.tcpServerConnection = self.tcpServer.nextPendingConnection()
        self.tcpServerConnection.readyRead.connect(self.updateServerProgress)
        self.tcpServerConnection.error.connect(self.displayError)

        self.serverStatusLabel.setText("Accepted connection")
        self.tcpServer.close()

    def startTransfer(self):
        self.bytesToWrite = Dialog.TotalBytes - self.tcpClient.write(
            QByteArray(Dialog.PayloadSize, "@"))
        self.clientStatusLabel.setText("Connected")

    def updateServerProgress(self):
        self.bytesReceived += self.tcpServerConnection.bytesAvailable()
        self.tcpServerConnection.readAll()

        self.serverProgressBar.setMaximum(Dialog.TotalBytes)
        self.serverProgressBar.setValue(self.bytesReceived)
        self.serverStatusLabel.setText("Received %dMB" % (self.bytesReceived /
                                                          (1024 * 1024)))

        if self.bytesReceived == Dialog.TotalBytes:
            self.tcpServerConnection.close()
            self.startButton.setEnabled(True)
            QApplication.restoreOverrideCursor()

    def updateClientProgress(self, numBytes):
        self.bytesWritten += numBytes
        if self.bytesToWrite > 0:
            self.bytesToWrite -= self.tcpClient.write(
                QByteArray(min(self.bytesToWrite, Dialog.PayloadSize), "@"))

        self.clientProgressBar.setMaximum(Dialog.TotalBytes)
        self.clientProgressBar.setValue(self.bytesWritten)
        self.clientStatusLabel.setText("Sent %dMB" % (self.bytesWritten /
                                                      (1024 * 1024)))

    def displayError(self, socketError):
        if socketError == QTcpSocket.RemoteHostClosedError:
            return

        QMessageBox.information(
            self,
            "Network error",
            "The following error occured: %s." % self.tcpClient.errorString(),
        )

        self.tcpClient.close()
        self.tcpServer.close()
        self.clientProgressBar.reset()
        self.serverProgressBar.reset()
        self.clientStatusLabel.setText("Client ready")
        self.serverStatusLabel.setText("Server ready")
        self.startButton.setEnabled(True)
        QApplication.restoreOverrideCursor()
예제 #32
0
class Voltmeter(QtWidgets.QMainWindow, Ui_MainWindow):
    VOLTMETER_PORT = 5000

    def __init__(self, parent=None):
        super(Voltmeter, self).__init__(parent)
        self.setupUi(self)
        self.needle = QwtDialSimpleNeedle(QwtDialSimpleNeedle.Arrow)
        self.Dial.setNeedle(self.needle)
        self.Dial.setValue(1.5)
        self.lcdNumber.display(1.5)
        self.actionQuit.triggered.connect(self.quit)
        self.connect_pb.clicked.connect(self.connect)
        self.calib = 3.3 / 256
        self.client_socket = QTcpSocket(self)
        self.connected = False

    def connect(self):
        if self.connected:
            self.client_socket.close()
            self.connect_pb.setChecked(False)
            self.connect_pb.setText("Connect to Voltmeter")
            return
        print("Connecting")
        server_ip = str(self.ip_address_text.text())

        port = self.VOLTMETER_PORT
        print("Server IP: ", server_ip)
        if server_ip.find('xxx') != -1:
            print("bad IP")
            QMessageBox.about(
                self, 'Bad Server IP', 'Please give a correct Server IP\n'
                'IP is ' + server_ip)
            self.connect_pb.setChecked(False)
            return
        else:
            print("Connecting to " + server_ip + ":", port)
            self.client_socket.connectToHost(server_ip, port)
            self.client_socket.waitForConnected(1000)

        if self.client_socket.state() != QTcpSocket.ConnectedState:
            QMessageBox.warning(
                self, 'Connection failed',
                'Please check IP address and port number\nIs the server running?'
            )
            self.connect_pb.setChecked(False)
            return

        print("Connection established")
        self.client_socket.readyRead.connect(self.treatMeas)
        self.connect_pb.setText("Connected")

    def treatMeas(self):
        # get new values and display them
        msg = self.client_socket.readAll()
        newValue = int(bytes(msg).decode())
        print("new value: ", newValue)
        response = 'ok\n'
        self.client_socket.write(bytes(response, encoding="ascii"))
        newVoltage = int(newValue) * self.calib
        print(newVoltage)
        self.lcdNumber.display(newVoltage)
        self.Dial.setValue(newVoltage)

    def quit(self):
        app.exit()
예제 #33
0
파일: 控制小车.py 프로젝트: weiryu/PyQt
class ControlCar(QWidget):

    HOST = '127.0.0.1'
    PORT = 8888

    def __init__(self, *args, **kwargs):
        super(ControlCar, self).__init__(*args, **kwargs)
        self._connCar = None
        # 加载UI文件
        uic.loadUi('carui.ui', self)
        self.resize(800, 600)
        # 绑定连接按钮信号
        self.buttonConnect.clicked.connect(self.doConnect)
        # 绑定拉动信号
        self.sliderForward.valueChanged.connect(self.doForward)
        self.sliderBackward.valueChanged.connect(self.doBackward)
        self.sliderLeft.valueChanged.connect(self.doLeft)
        self.sliderRight.valueChanged.connect(self.doRight)
        # 设置初始拉动条不能用
        self.sliderForward.setEnabled(False)
        self.sliderBackward.setEnabled(False)
        self.sliderLeft.setEnabled(False)
        self.sliderRight.setEnabled(False)

        # 定时器定时向图片服务器发送请求
        self._timer = QTimer(self, timeout=self.doGetImage)

    def _clearConn(self):
        """清理连接"""
        if self._connCar:
            self._connCar.close()
            self._connCar.deleteLater()
            del self._connCar
            self._connCar = None

    def closeEvent(self, event):
        """窗口关闭事件"""
        self._timer.stop()
        self._clearConn()
        super(ControlCar, self).closeEvent(event)

    def doConnect(self):
        """连接服务器"""
        self.buttonConnect.setEnabled(False)
        self._timer.stop()
        self._clearConn()
        self.browserResult.append('正在连接服务器')
        # 连接控制小车的服务器
        self._connCar = QTcpSocket(self)
        self._connCar.connected.connect(self.onConnected)  # 绑定连接成功信号
        self._connCar.disconnected.connect(self.onDisconnected)  # 绑定连接丢失信号
        self._connCar.readyRead.connect(self.onReadyRead)  # 准备读取信号
        self._connCar.error.connect(self.onError)  # 连接错误信号
        self._connCar.connectToHost(self.HOST, self.PORT)

    def onConnected(self):
        """连接成功"""
        self.buttonConnect.setEnabled(False)  # 按钮不可用
        # 设置初始拉动条可用
        self.sliderForward.setEnabled(True)
        self.sliderBackward.setEnabled(True)
        self.sliderLeft.setEnabled(True)
        self.sliderRight.setEnabled(True)
        self.browserResult.append('连接成功')  # 记录日志
        # 开启获取摄像头图片定时器
        self._timer.start(200)

    def onDisconnected(self):
        """丢失连接"""
        self._timer.stop()
        self.buttonConnect.setEnabled(True)  # 按钮可用
        # 设置初始拉动条不可用
        self.sliderForward.setEnabled(False)
        self.sliderBackward.setEnabled(False)
        self.sliderLeft.setEnabled(False)
        self.sliderRight.setEnabled(False)
        # 把数据设置为最小值
        self.sliderForward.setValue(self.sliderForward.minimum())
        self.sliderBackward.setValue(self.sliderBackward.minimum())
        self.sliderLeft.setValue(self.sliderLeft.minimum())
        self.sliderRight.setValue(self.sliderRight.minimum())
        self.browserResult.append('丢失连接')  # 记录日志

    def onReadyRead(self):
        """接收到数据"""
        while self._connCar.bytesAvailable() > 0:
            try:
                data = self._connCar.readAll().data()
                if data and data.find(b'JFIF') > -1:
                    self.qlabel.setPixmap(  # 图片
                        QPixmap.fromImage(QImage.fromData(data)))
                else:
                    self.browserResult.append('接收到数据: ' + data.decode())
            except Exception as e:
                self.browserResult.append('解析数据错误: ' + str(e))

    def onError(self, _):
        """连接报错"""
        self._timer.stop()
        self.buttonConnect.setEnabled(True)  # 按钮可用
        self.browserResult.append('连接服务器错误: ' + self._connCar.errorString())

    def doForward(self, value):
        """向前"""
        # 发送的内容为  F:1 类似的
        self.sendData('F:', str(value))

    def doBackward(self, value):
        """向后"""
        # 发送的内容为  B:1 类似的
        self.sendData('B:', str(value))

    def doLeft(self, value):
        """向左"""
        # 发送的内容为  L:1 类似的
        self.sendData('L:', str(value))

    def doRight(self, value):
        """向右"""
        # 发送的内容为  R:1 类似的
        self.sendData('R:', str(value))

    def doGetImage(self):
        # 请求图片
        self.sendData('getimage', '')

    def sendData(self, ver, data):
        """发送数据"""
        if not self._connCar or not self._connCar.isWritable():
            return self.browserResult.append('服务器未连接或不可写入数据')
        self._connCar.write(ver.encode() + str(data).encode() + b'\n')
예제 #34
0
class Client(QDialog):
    def __init__(self, parent=None):
        super(Client, self).__init__(parent)

        self.networkSession = None
        self.blockSize = 0
        self.currentFortune = ""

        hostLabel = QLabel("&Server name:")
        portLabel = QLabel("S&erver port:")

        self.hostCombo = QComboBox()
        self.hostCombo.setEditable(True)

        name = QHostInfo.localHostName()
        if name != "":
            self.hostCombo.addItem(name)

            domain = QHostInfo.localDomainName()
            if domain != "":
                self.hostCombo.addItem(name + "." + domain)

        if name != "localhost":
            self.hostCombo.addItem("localhost")

        ipAddressesList = QNetworkInterface.allAddresses()

        for ipAddress in ipAddressesList:
            if not ipAddress.isLoopback():
                self.hostCombo.addItem(ipAddress.toString())

        for ipAddress in ipAddressesList:
            if ipAddress.isLoopback():
                self.hostCombo.addItem(ipAddress.toString())

        self.portLineEdit = QLineEdit()
        self.portLineEdit.setValidator(QIntValidator(1, 65535, self))

        hostLabel.setBuddy(self.hostCombo)
        portLabel.setBuddy(self.portLineEdit)

        self.statusLabel = QLabel("This examples requires that you run " "the Fortune Server example as well.")

        self.getFortuneButton = QPushButton("Get Fortune")
        self.getFortuneButton.setDefault(True)
        self.getFortuneButton.setEnabled(False)

        quitButton = QPushButton("Quit")

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole)

        self.tcpSocket = QTcpSocket(self)

        self.hostCombo.editTextChanged.connect(self.enableGetFortuneButton)
        self.portLineEdit.textChanged.connect(self.enableGetFortuneButton)
        self.getFortuneButton.clicked.connect(self.requestNewFortune)
        quitButton.clicked.connect(self.close)
        self.tcpSocket.readyRead.connect(self.readFortune)
        self.tcpSocket.error.connect(self.displayError)

        mainLayout = QGridLayout()
        mainLayout.addWidget(hostLabel, 0, 0)
        mainLayout.addWidget(self.hostCombo, 0, 1)
        mainLayout.addWidget(portLabel, 1, 0)
        mainLayout.addWidget(self.portLineEdit, 1, 1)
        mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2)
        mainLayout.addWidget(buttonBox, 3, 0, 1, 2)
        self.setLayout(mainLayout)

        self.setWindowTitle("Fortune Client")
        self.portLineEdit.setFocus()

        manager = QNetworkConfigurationManager()
        if manager.capabilities() & QNetworkConfigurationManager.NetworkSessionRequired:
            settings = QSettings(QSettings.UserScope, "QtProject")
            settings.beginGroup("QtNetwork")
            id = settings.value("DefaultNetworkConfiguration")
            settings.endGroup()

            config = manager.configurationFromIdentifier(id)
            if config.state() & QNetworkConfiguration.Discovered == 0:
                config = manager.defaultConfiguration()

            self.networkSession = QNetworkSession(config, self)
            self.networkSession.opened.connect(self.sessionOpened)

            self.getFortuneButton.setEnabled(False)
            self.statusLabel.setText("Opening network session.")
            self.networkSession.open()

    def requestNewFortune(self):
        self.getFortuneButton.setEnabled(False)
        self.blockSize = 0
        self.tcpSocket.abort()
        self.tcpSocket.connectToHost(self.hostCombo.currentText(), int(self.portLineEdit.text()))

    def readFortune(self):
        instr = QDataStream(self.tcpSocket)
        instr.setVersion(QDataStream.Qt_4_0)

        if self.blockSize == 0:
            if self.tcpSocket.bytesAvailable() < 2:
                return

            self.blockSize = instr.readUInt16()

        if self.tcpSocket.bytesAvailable() < self.blockSize:
            return

        nextFortune = instr.readQString()
        if nextFortune == self.currentFortune:
            QTimer.singleShot(0, self.requestNewFortune)
            return

        self.currentFortune = nextFortune
        self.statusLabel.setText(self.currentFortune)
        self.getFortuneButton.setEnabled(True)

    def displayError(self, socketError):
        if socketError == QAbstractSocket.RemoteHostClosedError:
            pass
        elif socketError == QAbstractSocket.HostNotFoundError:
            QMessageBox.information(
                self, "Fortune Client", "The host was not found. Please check the host name and " "port settings."
            )
        elif socketError == QAbstractSocket.ConnectionRefusedError:
            QMessageBox.information(
                self,
                "Fortune Client",
                "The connection was refused by the peer. Make sure the "
                "fortune server is running, and check that the host name "
                "and port settings are correct.",
            )
        else:
            QMessageBox.information(
                self, "Fortune Client", "The following error occurred: %s." % self.tcpSocket.errorString()
            )

        self.getFortuneButton.setEnabled(True)

    def enableGetFortuneButton(self):
        self.getFortuneButton.setEnabled(
            (self.networkSession is None or self.networkSession.isOpen())
            and self.hostCombo.currentText() != ""
            and self.portLineEdit.text() != ""
        )

    def sessionOpened(self):
        config = self.networkSession.configuration()

        if config.type() == QNetworkConfiguration.UserChoice:
            id = self.networkSession.sessionProperty("UserChoiceConfiguration")
        else:
            id = config.identifier()

        settings = QSettings(QSettings.UserScope, "QtProject")
        settings.beginGroup("QtNetwork")
        settings.setValue("DefaultNetworkConfiguration", id)
        settings.endGroup()

        self.statusLabel.setText("This examples requires that you run the " "Fortune Server example as well.")

        self.enableGetFortuneButton()
예제 #35
0
class VNA(QMainWindow, Ui_VNA):
  graphs = ['open', 'short', 'load', 'dut', 'smith', 'imp', 'swr', 'gamma', 'rl', 'gain_short', 'gain_open']

  def __init__(self):
    super(VNA, self).__init__()
    self.setupUi(self)
    # IP address validator
    rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')
    self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
    # state variables
    self.idle = True
    self.reading = False
    self.auto = False
    # sweep parameters
    self.sweep_start = 10
    self.sweep_stop = 60000
    self.sweep_size = 6000
    # buffer and offset for the incoming samples
    self.buffer = bytearray(16 * 32768)
    self.offset = 0
    self.data = np.frombuffer(self.buffer, np.complex64)
    # create measurements
    self.open = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.short = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.load = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.dut = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.mode = 'open'
    # create figures
    self.tabs = {}
    for i in range(len(self.graphs)):
      layout = getattr(self, '%sLayout' % self.graphs[i])
      self.tabs[i] = FigureTab(layout, self.open, self.short, self.load, self.dut)
    # configure widgets
    self.rateValue.addItems(['10000', '5000', '1000', '500', '100', '50', '10', '5', '1'])
    self.rateValue.lineEdit().setReadOnly(True)
    self.rateValue.lineEdit().setAlignment(Qt.AlignRight)
    for i in range(self.rateValue.count()):
      self.rateValue.setItemData(i, Qt.AlignRight, Qt.TextAlignmentRole)
    self.set_enabled(False)
    # read settings
    settings = QSettings('vna.ini', QSettings.IniFormat)
    self.read_cfg_settings(settings)
    # create TCP socket
    self.socket = QTcpSocket(self)
    self.socket.connected.connect(self.connected)
    self.socket.readyRead.connect(self.read_data)
    self.socket.error.connect(self.display_error)
    # connect signals from widgets
    self.connectButton.clicked.connect(self.start)
    self.writeButton.clicked.connect(self.write_cfg)
    self.readButton.clicked.connect(self.read_cfg)
    self.openSweep.clicked.connect(partial(self.sweep, 'open'))
    self.shortSweep.clicked.connect(partial(self.sweep, 'short'))
    self.loadSweep.clicked.connect(partial(self.sweep, 'load'))
    self.singleSweep.clicked.connect(partial(self.sweep, 'dut'))
    self.autoSweep.clicked.connect(self.sweep_auto)
    self.stopSweep.clicked.connect(self.cancel)
    self.csvButton.clicked.connect(self.write_csv)
    self.s1pButton.clicked.connect(self.write_s1p)
    self.s2pshortButton.clicked.connect(self.write_s2p_short)
    self.s2popenButton.clicked.connect(self.write_s2p_open)
    self.startValue.valueChanged.connect(self.set_start)
    self.stopValue.valueChanged.connect(self.set_stop)
    self.sizeValue.valueChanged.connect(self.set_size)
    self.rateValue.currentIndexChanged.connect(self.set_rate)
    self.corrValue.valueChanged.connect(self.set_corr)
    self.levelValue.valueChanged.connect(self.set_level)
    self.tabWidget.currentChanged.connect(self.update_tab)
    # create timers
    self.startTimer = QTimer(self)
    self.startTimer.timeout.connect(self.timeout)
    self.sweepTimer = QTimer(self)
    self.sweepTimer.timeout.connect(self.sweep_timeout)

  def set_enabled(self, enabled):
    widgets = [self.corrValue, self.rateValue, self.levelValue, self.sizeValue, self.stopValue, self.startValue, self.openSweep, self.shortSweep, self.loadSweep, self.singleSweep, self.autoSweep]
    for entry in widgets:
      entry.setEnabled(enabled)

  def start(self):
    if self.idle:
      self.connectButton.setEnabled(False)
      self.socket.connectToHost(self.addrValue.text(), 1001)
      self.startTimer.start(5000)
    else:
      self.stop()

  def stop(self):
    self.idle = True
    self.cancel()
    self.socket.abort()
    self.connectButton.setText('Connect')
    self.connectButton.setEnabled(True)
    self.set_enabled(False)

  def timeout(self):
    self.display_error('timeout')

  def connected(self):
    self.startTimer.stop()
    self.idle = False
    self.set_rate(self.rateValue.currentIndex())
    self.set_corr(self.corrValue.value())
    self.set_level(self.levelValue.value())
    self.set_gpio(1)
    self.connectButton.setText('Disconnect')
    self.connectButton.setEnabled(True)
    self.set_enabled(True)

  def read_data(self):
    while(self.socket.bytesAvailable() > 0):
      if not self.reading:
        self.socket.readAll()
        return
      size = self.socket.bytesAvailable()
      self.progressBar.setValue((self.offset + size) / 16)
      limit = 16 * self.sweep_size
      if self.offset + size < limit:
        self.buffer[self.offset:self.offset + size] = self.socket.read(size)
        self.offset += size
      else:
        self.buffer[self.offset:limit] = self.socket.read(limit - self.offset)
        adc1 = self.data[0::2]
        adc2 = self.data[1::2]
        attr = getattr(self, self.mode)
        start = self.sweep_start
        stop = self.sweep_stop
        size = self.sweep_size
        attr.freq = np.linspace(start, stop, size)
        attr.data = adc1[0:size].copy()
        self.update_tab()
        self.reading = False
        if not self.auto:
          self.progressBar.setValue(0)
          self.set_enabled(True)

  def display_error(self, socketError):
    self.startTimer.stop()
    if socketError == 'timeout':
      QMessageBox.information(self, 'VNA', 'Error: connection timeout.')
    else:
      QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString())
    self.stop()

  def set_start(self, value):
    self.sweep_start = value

  def set_stop(self, value):
    self.sweep_stop = value

  def set_size(self, value):
    self.sweep_size = value

  def set_rate(self, value):
    if self.idle: return
    rate = [5, 10, 50, 100, 500, 1000, 5000, 10000, 50000][value]
    self.socket.write(struct.pack('<I', 3<<28 | int(rate)))

  def set_corr(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 4<<28 | int(value)))

  def set_level(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 5<<28 | int(32766 * np.power(10.0, value / 20.0))))
    self.socket.write(struct.pack('<I', 6<<28 | int(0)))

  def set_gpio(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 7<<28 | int(value)))

  def sweep(self, mode):
    if self.idle: return
    self.set_enabled(False)
    self.mode = mode
    self.offset = 0
    self.reading = True
    self.socket.write(struct.pack('<I', 0<<28 | int(self.sweep_start * 1000)))
    self.socket.write(struct.pack('<I', 1<<28 | int(self.sweep_stop * 1000)))
    self.socket.write(struct.pack('<I', 2<<28 | int(self.sweep_size)))
    self.socket.write(struct.pack('<I', 8<<28))
    self.progressBar.setMinimum(0)
    self.progressBar.setMaximum(self.sweep_size)
    self.progressBar.setValue(0)

  def cancel(self):
    self.sweepTimer.stop()
    self.auto = False
    self.reading = False
    self.socket.write(struct.pack('<I', 9<<28))
    self.progressBar.setValue(0)
    self.set_enabled(True)

  def sweep_auto(self):
    self.auto = True
    self.sweepTimer.start(100)

  def sweep_timeout(self):
    if not self.reading:
      self.sweep('dut')

  def update_tab(self):
    index = self.tabWidget.currentIndex()
    self.tabs[index].update(self.graphs[index])

  def write_cfg(self):
    dialog = QFileDialog(self, 'Write configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.selectFile('vna.ini')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.write_cfg_settings(settings)

  def read_cfg(self):
    dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.selectFile('vna.ini')
    dialog.setAcceptMode(QFileDialog.AcceptOpen)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.read_cfg_settings(settings)
      window.update_tab()

  def write_cfg_settings(self, settings):
    settings.setValue('addr', self.addrValue.text())
    settings.setValue('rate', self.rateValue.currentIndex())
    settings.setValue('corr', self.corrValue.value())
    settings.setValue('level', self.levelValue.value())
    settings.setValue('open_start', int(self.open.freq[0]))
    settings.setValue('open_stop', int(self.open.freq[-1]))
    settings.setValue('open_size', self.open.freq.size)
    settings.setValue('short_start', int(self.short.freq[0]))
    settings.setValue('short_stop', int(self.short.freq[-1]))
    settings.setValue('short_size', self.short.freq.size)
    settings.setValue('load_start', int(self.load.freq[0]))
    settings.setValue('load_stop', int(self.load.freq[-1]))
    settings.setValue('load_size', self.load.freq.size)
    settings.setValue('dut_start', int(self.dut.freq[0]))
    settings.setValue('dut_stop', int(self.dut.freq[-1]))
    settings.setValue('dut_size', self.dut.freq.size)
    for i in range(len(FigureTab.cursors)):
      settings.setValue('cursor_%d' % i, FigureTab.cursors[i])
    data = self.open.data
    for i in range(self.open.freq.size):
      settings.setValue('open_real_%d' % i, float(data.real[i]))
      settings.setValue('open_imag_%d' % i, float(data.imag[i]))
    data = self.short.data
    for i in range(self.short.freq.size):
      settings.setValue('short_real_%d' % i, float(data.real[i]))
      settings.setValue('short_imag_%d' % i, float(data.imag[i]))
    data = self.load.data
    for i in range(self.load.freq.size):
      settings.setValue('load_real_%d' % i, float(data.real[i]))
      settings.setValue('load_imag_%d' % i, float(data.imag[i]))
    data = self.dut.data
    for i in range(self.dut.freq.size):
      settings.setValue('dut_real_%d' % i, float(data.real[i]))
      settings.setValue('dut_imag_%d' % i, float(data.imag[i]))

  def read_cfg_settings(self, settings):
    self.addrValue.setText(settings.value('addr', '192.168.1.100'))
    self.rateValue.setCurrentIndex(settings.value('rate', 0, type = int))
    self.corrValue.setValue(settings.value('corr', 0, type = int))
    self.levelValue.setValue(settings.value('level', 0, type = int))
    open_start = settings.value('open_start', 10, type = int)
    open_stop = settings.value('open_stop', 60000, type = int)
    open_size = settings.value('open_size', 6000, type = int)
    short_start = settings.value('short_start', 10, type = int)
    short_stop = settings.value('short_stop', 60000, type = int)
    short_size = settings.value('short_size', 6000, type = int)
    load_start = settings.value('load_start', 10, type = int)
    load_stop = settings.value('load_stop', 60000, type = int)
    load_size = settings.value('load_size', 6000, type = int)
    dut_start = settings.value('dut_start', 10, type = int)
    dut_stop = settings.value('dut_stop', 60000, type = int)
    dut_size = settings.value('dut_size', 6000, type = int)
    self.startValue.setValue(dut_start)
    self.stopValue.setValue(dut_stop)
    self.sizeValue.setValue(dut_size)
    for i in range(len(FigureTab.cursors)):
      FigureTab.cursors[i] = settings.value('cursor_%d' % i, FigureTab.cursors[i], type = int)
    self.open.freq = np.linspace(open_start, open_stop, open_size)
    self.open.data = np.zeros(open_size, np.complex64)
    for i in range(open_size):
      real = settings.value('open_real_%d' % i, 0.0, type = float)
      imag = settings.value('open_imag_%d' % i, 0.0, type = float)
      self.open.data[i] = real + 1.0j * imag
    self.short.freq = np.linspace(short_start, short_stop, short_size)
    self.short.data = np.zeros(short_size, np.complex64)
    for i in range(short_size):
      real = settings.value('short_real_%d' % i, 0.0, type = float)
      imag = settings.value('short_imag_%d' % i, 0.0, type = float)
      self.short.data[i] = real + 1.0j * imag
    self.load.freq = np.linspace(load_start, load_stop, load_size)
    self.load.data = np.zeros(load_size, np.complex64)
    for i in range(load_size):
      real = settings.value('load_real_%d' % i, 0.0, type = float)
      imag = settings.value('load_imag_%d' % i, 0.0, type = float)
      self.load.data[i] = real + 1.0j * imag
    self.dut.freq = np.linspace(dut_start, dut_stop, dut_size)
    self.dut.data = np.zeros(dut_size, np.complex64)
    for i in range(dut_size):
      real = settings.value('dut_real_%d' % i, 0.0, type = float)
      imag = settings.value('dut_imag_%d' % i, 0.0, type = float)
      self.dut.data[i] = real + 1.0j * imag

  def write_csv(self):
    dialog = QFileDialog(self, 'Write csv file', '.', '*.csv')
    dialog.setDefaultSuffix('csv')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      f = self.dut.freq
      o = np.interp(f, self.open.freq, self.open.data, period = self.open.period)
      s = np.interp(f, self.short.freq, self.short.data, period = self.short.period)
      l = np.interp(f, self.load.freq, self.load.data, period = self.load.period)
      d = self.dut.data
      fh.write('frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n')
      for i in range(f.size):
        fh.write('0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (f[i] * 1000, o.real[i], o.imag[i], s.real[i], s.imag[i], l.real[i], l.imag[i], d.real[i], d.imag[i]))
      fh.close()

  def write_s1p(self):
    dialog = QFileDialog(self, 'Write s1p file', '.', '*.s1p')
    dialog.setDefaultSuffix('s1p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      freq = self.dut.freq
      gamma = self.gamma(freq)
      fh.write('# GHz S MA R 50\n')
      for i in range(freq.size):
        fh.write('0.0%.8d   %8.6f %7.2f\n' % (freq[i] * 1000, np.absolute(gamma[i]), np.angle(gamma[i], deg = True)))
      fh.close()

  def write_s2p(self, gain):
    dialog = QFileDialog(self, 'Write s2p file', '.', '*.s2p')
    dialog.setDefaultSuffix('s2p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      freq = self.dut.freq
      gamma = self.gamma(freq)
      fh.write('# GHz S MA R 50\n')
      for i in range(freq.size):
        fh.write('0.0%.8d   %8.6f %7.2f   %8.6f %7.2f   0.000000    0.00   0.000000    0.00\n' % (freq[i] * 1000, np.absolute(gamma[i]), np.angle(gamma[i], deg = True), np.absolute(gain[i]), np.angle(gain[i], deg = True)))
      fh.close()

  def write_s2p_short(self):
    self.write_s2p(self.gain_short(self.dut.freq))

  def write_s2p_open(self):
    self.write_s2p(self.gain_open(self.dut.freq))
예제 #36
0
class PulsedNMR(QMainWindow, Ui_PulsedNMR):
  rates = {0:25.0e3, 1:50.0e3, 2:250.0e3, 3:500.0e3, 4:2500.0e3}
  def __init__(self):
    super(PulsedNMR, self).__init__()
    self.setupUi(self)
    self.rateValue.addItems(['25', '50', '250', '500', '2500'])
    # IP address validator
    rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')
    self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
    # state variable
    self.idle = True
    # number of samples to show on the plot
    self.size = 50000
    # buffer and offset for the incoming samples
    self.buffer = bytearray(8 * self.size)
    self.offset = 0
    # create figure
    figure = Figure()
    figure.set_facecolor('none')
    self.axes = figure.add_subplot(111)
    self.canvas = FigureCanvas(figure)
    self.plotLayout.addWidget(self.canvas)
    # create navigation toolbar
    self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
    # remove subplots action
    actions = self.toolbar.actions()
    self.toolbar.removeAction(actions[7])
    self.plotLayout.addWidget(self.toolbar)
    # create TCP socket
    self.socket = QTcpSocket(self)
    self.socket.connected.connect(self.connected)
    self.socket.readyRead.connect(self.read_data)
    self.socket.error.connect(self.display_error)
    # connect signals from buttons and boxes
    self.startButton.clicked.connect(self.start)
    self.freqValue.valueChanged.connect(self.set_freq)
    self.awidthValue.valueChanged.connect(self.set_awidth)
    self.deltaValue.valueChanged.connect(self.set_delta)
    self.rateValue.currentIndexChanged.connect(self.set_rate)
    # set rate
    self.rateValue.setCurrentIndex(2)
    # create timer for the repetitions
    self.timer = QTimer(self)
    self.timer.timeout.connect(self.fire)

  def start(self):
    if self.idle:
      self.startButton.setEnabled(False)
      self.socket.connectToHost(self.addrValue.text(), 1001)
    else:
      self.idle = True
      self.timer.stop()
      self.socket.close()
      self.offset = 0
      self.startButton.setText('Start')
      self.startButton.setEnabled(True)

  def connected(self):
    self.idle = False
    self.set_freq(self.freqValue.value())
    self.set_rate(self.rateValue.currentIndex())
    self.set_awidth(self.awidthValue.value())
    self.fire()
    self.timer.start(self.deltaValue.value())
    self.startButton.setText('Stop')
    self.startButton.setEnabled(True)

  def read_data(self):
    size = self.socket.bytesAvailable()
    if self.offset + size < 8 * self.size:
      self.buffer[self.offset:self.offset + size] = self.socket.read(size)
      self.offset += size
    else:
      self.buffer[self.offset:8 * self.size] = self.socket.read(8 * self.size - self.offset)
      self.offset = 0
      # plot the signal envelope
      data = np.frombuffer(self.buffer, np.complex64)
      self.curve.set_ydata(np.abs(data))
      self.canvas.draw()

  def display_error(self, socketError):
    if socketError == QAbstractSocket.RemoteHostClosedError:
      pass
    else:
      QMessageBox.information(self, 'PulsedNMR', 'Error: %s.' % self.socket.errorString())
    self.startButton.setText('Start')
    self.startButton.setEnabled(True)

  def set_freq(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 0<<28 | int(1.0e6 * value)))

  def set_rate(self, index):
    # time axis
    rate = float(PulsedNMR.rates[index])
    time = np.linspace(0.0, (self.size - 1) * 1000.0 / rate, self.size)
    # reset toolbar
    self.toolbar.home()
    self.toolbar._views.clear()
    self.toolbar._positions.clear()
    # reset plot
    self.axes.clear()
    self.axes.grid()
    # plot zeros and get store the returned Line2D object
    self.curve, = self.axes.plot(time, np.zeros(self.size))
    x1, x2, y1, y2 = self.axes.axis()
    # set y axis limits
    self.axes.axis((x1, x2, -0.1, 0.4))
    self.axes.set_xlabel('time, ms')
    self.canvas.draw()
    # set repetition time
    minimum = self.size / rate * 2000.0
    if minimum < 100.0: minimum = 100.0
    self.deltaValue.setMinimum(minimum)
    self.deltaValue.setValue(minimum)
    if self.idle: return
    self.socket.write(struct.pack('<I', 1<<28 | index))

  def set_awidth(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 2<<28 | int(1.0e1 * value)))

  def set_delta(self, value):
    if self.idle: return
    self.timer.stop()
    self.timer.start(value)

  def fire(self):
    if self.idle: return
    self.socket.write(struct.pack('<I', 3<<28))
예제 #37
0
파일: pulsed_nmr.py 프로젝트: vnegnev/ocra
class PulsedNMR(QMainWindow, Ui_PulsedNMR):
    rates = {0: 25.0e3, 1: 50.0e3, 2: 250.0e3, 3: 500.0e3, 4: 2500.0e3}

    def __init__(self):
        super(PulsedNMR, self).__init__()
        self.setupUi(self)
        self.rateValue.addItems(['25', '50', '250', '500', '2500'])
        # IP address validator
        rx = QRegExp(
            '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'
        )
        self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
        # state variable
        self.idle = True
        # number of samples to show on the plot
        self.size = 50000
        # buffer and offset for the incoming samples
        self.buffer = bytearray(8 * self.size)
        self.offset = 0
        self.data = np.frombuffer(self.buffer, np.complex64)
        # create figure
        figure = Figure()
        figure.set_facecolor('none')
        self.axes = figure.add_subplot(111)
        self.canvas = FigureCanvas(figure)
        self.plotLayout.addWidget(self.canvas)
        # create navigation toolbar
        self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
        # remove subplots action
        actions = self.toolbar.actions()
        self.toolbar.removeAction(actions[7])
        self.plotLayout.addWidget(self.toolbar)
        # create TCP socket
        self.socket = QTcpSocket(self)
        self.socket.connected.connect(self.connected)
        self.socket.readyRead.connect(self.read_data)
        self.socket.error.connect(self.display_error)
        # connect signals from buttons and boxes
        self.startButton.clicked.connect(self.start)
        self.freqValue.valueChanged.connect(self.set_freq)
        self.awidthValue.valueChanged.connect(self.set_awidth)
        self.deltaValue.valueChanged.connect(self.set_delta)
        self.rateValue.currentIndexChanged.connect(self.set_rate)
        # set rate
        self.rateValue.setCurrentIndex(2)
        # create timer for the repetitions
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.fire)

    def start(self):
        if self.idle:
            self.startButton.setEnabled(False)
            self.socket.connectToHost(self.addrValue.text(), 1001)
        else:
            self.idle = True
            self.timer.stop()
            self.socket.close()
            self.offset = 0
            self.startButton.setText('Start')
            self.startButton.setEnabled(True)

    def connected(self):
        self.idle = False
        self.set_freq(self.freqValue.value())
        self.set_rate(self.rateValue.currentIndex())
        self.set_awidth(self.awidthValue.value())
        self.fire()
        self.timer.start(self.deltaValue.value())
        self.startButton.setText('Stop')
        self.startButton.setEnabled(True)

    def read_data(self):
        size = self.socket.bytesAvailable()
        if self.offset + size < 8 * self.size:
            self.buffer[self.offset:self.offset +
                        size] = self.socket.read(size)
            self.offset += size
        else:
            self.buffer[self.offset:8 *
                        self.size] = self.socket.read(8 * self.size -
                                                      self.offset)
            self.offset = 0
            # plot the signal envelope
            self.curve.set_ydata(np.real(self.data))
            self.canvas.draw()

    def display_error(self, socketError):
        if socketError == QAbstractSocket.RemoteHostClosedError:
            pass
        else:
            QMessageBox.information(self, 'PulsedNMR',
                                    'Error: %s.' % self.socket.errorString())
        self.startButton.setText('Start')
        self.startButton.setEnabled(True)

    def set_freq(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 0 << 28 | int(1.0e6 * value)))

    def set_rate(self, index):
        # time axis
        rate = float(PulsedNMR.rates[index])
        time = np.linspace(0.0, (self.size - 1) * 1000.0 / rate, self.size)
        # reset toolbar
        self.toolbar.home()
        self.toolbar._views.clear()
        self.toolbar._positions.clear()
        # reset plot
        self.axes.clear()
        self.axes.grid()
        # plot zeros and get store the returned Line2D object
        self.curve, = self.axes.plot(time, np.zeros(self.size))
        x1, x2, y1, y2 = self.axes.axis()
        # set y axis limits
        self.axes.axis((x1, x2, -0.1, 0.4))
        self.axes.set_xlabel('time, ms')
        self.canvas.draw()
        # set repetition time
        minimum = self.size / rate * 2000.0
        if minimum < 100.0: minimum = 100.0
        self.deltaValue.setMinimum(minimum)
        self.deltaValue.setValue(minimum)
        if self.idle: return
        self.socket.write(struct.pack('<I', 1 << 28 | index))

    def set_awidth(self, value):
        if self.idle: return
        self.socket.write(struct.pack('<I', 2 << 28 | int(1.0e1 * value)))

    def set_delta(self, value):
        if self.idle: return
        self.timer.stop()
        self.timer.start(value)

    def fire(self):
        if self.idle: return
        self.socket.write(struct.pack('<I', 3 << 28))
예제 #38
0
class VNA(QMainWindow, Ui_VNA):
  graphs = ['open', 'short', 'load', 'dut', 'smith', 'imp', 'swr', 'gamma', 'rl', 'gain_short', 'gain_open']

  def __init__(self):
    super(VNA, self).__init__()
    self.setupUi(self)
    # IP address validator
    rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')
    self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
    # state variables
    self.idle = True
    self.reading = False
    self.auto = False
    # sweep parameters
    self.sweep_start = 10
    self.sweep_stop = 60000
    self.sweep_size = 6000
    # buffer and offset for the incoming samples
    self.buffer = bytearray(16 * 32768)
    self.offset = 0
    self.data = np.frombuffer(self.buffer, np.complex64)
    # create measurements
    self.open = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.short = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.load = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.dut = Measurement(self.sweep_start, self.sweep_stop, self.sweep_size)
    self.mode = 'open'
    # create figures
    self.tabs = {}
    for i in range(len(self.graphs)):
      layout = getattr(self, '%sLayout' % self.graphs[i])
      self.tabs[i] = FigureTab(layout, self)
    # configure widgets
    self.rateValue.addItems(['10000', '5000', '1000', '500', '100', '50', '10', '5', '1'])
    self.rateValue.lineEdit().setReadOnly(True)
    self.rateValue.lineEdit().setAlignment(Qt.AlignRight)
    for i in range(self.rateValue.count()):
      self.rateValue.setItemData(i, Qt.AlignRight, Qt.TextAlignmentRole)
    self.set_enabled(False)
    self.stopSweep.setEnabled(False)
    # read settings
    settings = QSettings('vna.ini', QSettings.IniFormat)
    self.read_cfg_settings(settings)
    # create TCP socket
    self.socket = QTcpSocket(self)
    self.socket.connected.connect(self.connected)
    self.socket.readyRead.connect(self.read_data)
    self.socket.error.connect(self.display_error)
    # connect signals from widgets
    self.connectButton.clicked.connect(self.start)
    self.writeButton.clicked.connect(self.write_cfg)
    self.readButton.clicked.connect(self.read_cfg)
    self.openSweep.clicked.connect(partial(self.sweep, 'open'))
    self.shortSweep.clicked.connect(partial(self.sweep, 'short'))
    self.loadSweep.clicked.connect(partial(self.sweep, 'load'))
    self.singleSweep.clicked.connect(partial(self.sweep, 'dut'))
    self.autoSweep.clicked.connect(self.sweep_auto)
    self.stopSweep.clicked.connect(self.cancel)
    self.csvButton.clicked.connect(self.write_csv)
    self.s1pButton.clicked.connect(self.write_s1p)
    self.s2pshortButton.clicked.connect(self.write_s2p_short)
    self.s2popenButton.clicked.connect(self.write_s2p_open)
    self.startValue.valueChanged.connect(self.set_start)
    self.stopValue.valueChanged.connect(self.set_stop)
    self.sizeValue.valueChanged.connect(self.set_size)
    self.rateValue.currentIndexChanged.connect(self.set_rate)
    self.corrValue.valueChanged.connect(self.set_corr)
    self.phase1Value.valueChanged.connect(self.set_phase1)
    self.phase2Value.valueChanged.connect(self.set_phase2)
    self.level1Value.valueChanged.connect(self.set_level1)
    self.level2Value.valueChanged.connect(self.set_level2)
    self.tabWidget.currentChanged.connect(self.update_tab)
    # create timers
    self.startTimer = QTimer(self)
    self.startTimer.timeout.connect(self.timeout)
    self.sweepTimer = QTimer(self)
    self.sweepTimer.timeout.connect(self.sweep_timeout)

  def set_enabled(self, enabled):
    widgets = [self.rateValue, self.level1Value, self.level2Value, self.corrValue, self.phase1Value, self.phase2Value, self.startValue, self.stopValue, self.sizeValue, self.openSweep, self.shortSweep, self.loadSweep, self.singleSweep, self.autoSweep]
    for entry in widgets:
      entry.setEnabled(enabled)

  def start(self):
    if self.idle:
      self.connectButton.setEnabled(False)
      self.socket.connectToHost(self.addrValue.text(), 1001)
      self.startTimer.start(5000)
    else:
      self.stop()

  def stop(self):
    self.idle = True
    self.cancel()
    self.socket.abort()
    self.connectButton.setText('Connect')
    self.connectButton.setEnabled(True)
    self.set_enabled(False)
    self.stopSweep.setEnabled(False)

  def timeout(self):
    self.display_error('timeout')

  def connected(self):
    self.startTimer.stop()
    self.idle = False
    self.set_rate(self.rateValue.currentIndex())
    self.set_corr(self.corrValue.value())
    self.set_phase1(self.phase1Value.value())
    self.set_phase2(self.phase2Value.value())
    self.set_level1(self.level1Value.value())
    self.set_level2(self.level2Value.value())
    self.set_gpio(1)
    self.connectButton.setText('Disconnect')
    self.connectButton.setEnabled(True)
    self.set_enabled(True)
    self.stopSweep.setEnabled(True)

  def read_data(self):
    while(self.socket.bytesAvailable() > 0):
      if not self.reading:
        self.socket.readAll()
        return
      size = self.socket.bytesAvailable()
      self.progressBar.setValue((self.offset + size) / 16)
      limit = 16 * self.sweep_size
      if self.offset + size < limit:
        self.buffer[self.offset:self.offset + size] = self.socket.read(size)
        self.offset += size
      else:
        self.buffer[self.offset:limit] = self.socket.read(limit - self.offset)
        adc1 = self.data[0::2]
        adc2 = self.data[1::2]
        attr = getattr(self, self.mode)
        start = self.sweep_start
        stop = self.sweep_stop
        size = self.sweep_size
        attr.freq = np.linspace(start, stop, size)
        attr.data = adc1[0:size].copy()
        self.update_tab()
        self.reading = False
        if not self.auto:
          self.progressBar.setValue(0)
          self.set_enabled(True)

  def display_error(self, socketError):
    self.startTimer.stop()
    if socketError == 'timeout':
      QMessageBox.information(self, 'VNA', 'Error: connection timeout.')
    else:
      QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString())
    self.stop()

  def set_start(self, value):
    self.sweep_start = value

  def set_stop(self, value):
    self.sweep_stop = value

  def set_size(self, value):
    self.sweep_size = value

  def set_rate(self, value):
    if self.idle: return
    rate = [5, 10, 50, 100, 500, 1000, 5000, 10000, 50000][value]
    self.socket.write(struct.pack('<I', 3<<28 | int(rate)))

  def set_corr(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 4<<28 | int(value)))

  def set_phase1(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 5<<28 | int(value)))

  def set_phase2(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 6<<28 | int(value)))

  def set_level1(self, value):
    if self.idle: return
    data = 0 if value == -90 else int(32766 * np.power(10.0, value / 20.0))
    self.socket.write(struct.pack('<I', 7<<28 | int(data)))

  def set_level2(self, value):
    if self.idle: return
    data = 0 if value == -90 else int(32766 * np.power(10.0, value / 20.0))
    self.socket.write(struct.pack('<I', 8<<28 | int(data)))

  def set_gpio(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 9<<28 | int(value)))

  def sweep(self, mode):
    if self.idle: return
    self.set_enabled(False)
    self.mode = mode
    self.offset = 0
    self.reading = True
    self.socket.write(struct.pack('<I', 0<<28 | int(self.sweep_start * 1000)))
    self.socket.write(struct.pack('<I', 1<<28 | int(self.sweep_stop * 1000)))
    self.socket.write(struct.pack('<I', 2<<28 | int(self.sweep_size)))
    self.socket.write(struct.pack('<I', 10<<28))
    self.progressBar.setMinimum(0)
    self.progressBar.setMaximum(self.sweep_size)
    self.progressBar.setValue(0)

  def cancel(self):
    self.sweepTimer.stop()
    self.auto = False
    self.reading = False
    self.socket.write(struct.pack('<I', 11<<28))
    self.progressBar.setValue(0)
    self.set_enabled(True)

  def sweep_auto(self):
    self.auto = True
    self.sweepTimer.start(100)

  def sweep_timeout(self):
    if not self.reading:
      self.sweep('dut')

  def update_tab(self):
    index = self.tabWidget.currentIndex()
    self.tabs[index].update(self.graphs[index])

  def interp(self, freq, meas):
    real = np.interp(freq, meas.freq, meas.data.real, period = meas.period)
    imag = np.interp(freq, meas.freq, meas.data.imag, period = meas.period)
    return real + 1j * imag

  def gain_short(self, freq):
    short = self.interp(freq, self.short)
    dut = self.interp(freq, self.dut)
    return np.divide(dut, short)

  def gain_open(self, freq):
    open = self.interp(freq, self.open)
    dut = self.interp(freq, self.dut)
    return np.divide(dut, open)

  def impedance(self, freq):
    open = self.interp(freq, self.open)
    short = self.interp(freq, self.short)
    load = self.interp(freq, self.load)
    dut = self.interp(freq, self.dut)
    z = np.divide(50.0 * (open - load) * (dut - short), (load - short) * (open - dut))
    z = np.asarray(z)
    z.real[z.real < 1.0e-2] = 9.99e-3
    return z

  def gamma(self, freq):
    z = self.impedance(freq)
    return np.divide(z - 50.0, z + 50.0)

  def swr(self, freq):
    magnitude = np.absolute(self.gamma(freq))
    swr = np.divide(1.0 + magnitude, 1.0 - magnitude)
    return np.clip(swr, 1.0, 99.99)

  def write_cfg(self):
    dialog = QFileDialog(self, 'Write configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.selectFile('vna.ini')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.write_cfg_settings(settings)

  def read_cfg(self):
    dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.selectFile('vna.ini')
    dialog.setAcceptMode(QFileDialog.AcceptOpen)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.read_cfg_settings(settings)
      window.update_tab()

  def write_cfg_settings(self, settings):
    settings.setValue('addr', self.addrValue.text())
    settings.setValue('rate', self.rateValue.currentIndex())
    settings.setValue('corr', self.corrValue.value())
    settings.setValue('phase_1', self.phase1Value.value())
    settings.setValue('phase_2', self.phase2Value.value())
    settings.setValue('level_1', self.level1Value.value())
    settings.setValue('level_2', self.level2Value.value())
    settings.setValue('open_start', int(self.open.freq[0]))
    settings.setValue('open_stop', int(self.open.freq[-1]))
    settings.setValue('open_size', self.open.freq.size)
    settings.setValue('short_start', int(self.short.freq[0]))
    settings.setValue('short_stop', int(self.short.freq[-1]))
    settings.setValue('short_size', self.short.freq.size)
    settings.setValue('load_start', int(self.load.freq[0]))
    settings.setValue('load_stop', int(self.load.freq[-1]))
    settings.setValue('load_size', self.load.freq.size)
    settings.setValue('dut_start', int(self.dut.freq[0]))
    settings.setValue('dut_stop', int(self.dut.freq[-1]))
    settings.setValue('dut_size', self.dut.freq.size)
    for i in range(len(FigureTab.cursors)):
      settings.setValue('cursor_%d' % i, FigureTab.cursors[i])
    data = self.open.data
    for i in range(self.open.freq.size):
      settings.setValue('open_real_%d' % i, float(data.real[i]))
      settings.setValue('open_imag_%d' % i, float(data.imag[i]))
    data = self.short.data
    for i in range(self.short.freq.size):
      settings.setValue('short_real_%d' % i, float(data.real[i]))
      settings.setValue('short_imag_%d' % i, float(data.imag[i]))
    data = self.load.data
    for i in range(self.load.freq.size):
      settings.setValue('load_real_%d' % i, float(data.real[i]))
      settings.setValue('load_imag_%d' % i, float(data.imag[i]))
    data = self.dut.data
    for i in range(self.dut.freq.size):
      settings.setValue('dut_real_%d' % i, float(data.real[i]))
      settings.setValue('dut_imag_%d' % i, float(data.imag[i]))

  def read_cfg_settings(self, settings):
    self.addrValue.setText(settings.value('addr', '192.168.1.100'))
    self.rateValue.setCurrentIndex(settings.value('rate', 0, type = int))
    self.corrValue.setValue(settings.value('corr', 0, type = int))
    self.phase1Value.setValue(settings.value('phase_1', 0, type = int))
    self.phase2Value.setValue(settings.value('phase_2', 0, type = int))
    self.level1Value.setValue(settings.value('level_1', 0, type = int))
    self.level2Value.setValue(settings.value('level_2', -90, type = int))
    open_start = settings.value('open_start', 10, type = int)
    open_stop = settings.value('open_stop', 60000, type = int)
    open_size = settings.value('open_size', 6000, type = int)
    short_start = settings.value('short_start', 10, type = int)
    short_stop = settings.value('short_stop', 60000, type = int)
    short_size = settings.value('short_size', 6000, type = int)
    load_start = settings.value('load_start', 10, type = int)
    load_stop = settings.value('load_stop', 60000, type = int)
    load_size = settings.value('load_size', 6000, type = int)
    dut_start = settings.value('dut_start', 10, type = int)
    dut_stop = settings.value('dut_stop', 60000, type = int)
    dut_size = settings.value('dut_size', 6000, type = int)
    self.startValue.setValue(dut_start)
    self.stopValue.setValue(dut_stop)
    self.sizeValue.setValue(dut_size)
    for i in range(len(FigureTab.cursors)):
      FigureTab.cursors[i] = settings.value('cursor_%d' % i, FigureTab.cursors[i], type = int)
    self.open.freq = np.linspace(open_start, open_stop, open_size)
    self.open.data = np.zeros(open_size, np.complex64)
    for i in range(open_size):
      real = settings.value('open_real_%d' % i, 0.0, type = float)
      imag = settings.value('open_imag_%d' % i, 0.0, type = float)
      self.open.data[i] = real + 1.0j * imag
    self.short.freq = np.linspace(short_start, short_stop, short_size)
    self.short.data = np.zeros(short_size, np.complex64)
    for i in range(short_size):
      real = settings.value('short_real_%d' % i, 0.0, type = float)
      imag = settings.value('short_imag_%d' % i, 0.0, type = float)
      self.short.data[i] = real + 1.0j * imag
    self.load.freq = np.linspace(load_start, load_stop, load_size)
    self.load.data = np.zeros(load_size, np.complex64)
    for i in range(load_size):
      real = settings.value('load_real_%d' % i, 0.0, type = float)
      imag = settings.value('load_imag_%d' % i, 0.0, type = float)
      self.load.data[i] = real + 1.0j * imag
    self.dut.freq = np.linspace(dut_start, dut_stop, dut_size)
    self.dut.data = np.zeros(dut_size, np.complex64)
    for i in range(dut_size):
      real = settings.value('dut_real_%d' % i, 0.0, type = float)
      imag = settings.value('dut_imag_%d' % i, 0.0, type = float)
      self.dut.data[i] = real + 1.0j * imag

  def write_csv(self):
    dialog = QFileDialog(self, 'Write csv file', '.', '*.csv')
    dialog.setDefaultSuffix('csv')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      f = self.dut.freq
      o = self.interp(f, self.open)
      s = self.interp(f, self.short)
      l = self.interp(f, self.load)
      d = self.dut.data
      fh.write('frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n')
      for i in range(f.size):
        fh.write('0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (f[i] * 1000, o.real[i], o.imag[i], s.real[i], s.imag[i], l.real[i], l.imag[i], d.real[i], d.imag[i]))
      fh.close()

  def write_s1p(self):
    dialog = QFileDialog(self, 'Write s1p file', '.', '*.s1p')
    dialog.setDefaultSuffix('s1p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      freq = self.dut.freq
      gamma = self.gamma(freq)
      fh.write('# GHz S MA R 50\n')
      for i in range(freq.size):
        fh.write('0.0%.8d   %8.6f %7.2f\n' % (freq[i] * 1000, np.absolute(gamma[i]), np.angle(gamma[i], deg = True)))
      fh.close()

  def write_s2p(self, gain):
    dialog = QFileDialog(self, 'Write s2p file', '.', '*.s2p')
    dialog.setDefaultSuffix('s2p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      freq = self.dut.freq
      gamma = self.gamma(freq)
      fh.write('# GHz S MA R 50\n')
      for i in range(freq.size):
        fh.write('0.0%.8d   %8.6f %7.2f   %8.6f %7.2f   0.000000    0.00   0.000000    0.00\n' % (freq[i] * 1000, np.absolute(gamma[i]), np.angle(gamma[i], deg = True), np.absolute(gain[i]), np.angle(gain[i], deg = True)))
      fh.close()

  def write_s2p_short(self):
    self.write_s2p(self.gain_short(self.dut.freq))

  def write_s2p_open(self):
    self.write_s2p(self.gain_open(self.dut.freq))
예제 #39
0
class RedirectedIORunWrapper():
    """Wrapper to run a script with redirected IO"""
    def __init__(self):
        self.__socket = None
        self.__redirected = False
        self.__procuuid = None

    def redirected(self):
        """True if streams are redirected"""
        return self.__redirected

    def main(self):
        """Run wrapper driver"""
        if '--' not in sys.argv:
            print("Unexpected arguments", file=sys.stderr)
            return 1

        self.__procuuid, host, port, args = self.parseArgs()
        if self.__procuuid is None or host is None or port is None:
            print("Not enough arguments", file=sys.stderr)
            return 1

        remoteAddress = self.resolveHost(host)
        self.connect(remoteAddress, port)
        sendJSONCommand(self.__socket, METHOD_PROC_ID_INFO, self.__procuuid,
                        None)

        try:
            waitForIDEMessage(self.__socket, METHOD_PROLOGUE_CONTINUE,
                              WAIT_CONTINUE_TIMEOUT)
        except Exception as exc:
            print(str(exc), file=sys.stderr)
            return 1

        # Setup redirections
        stdoutOld = sys.stdout
        stderrOld = sys.stderr
        sys.stdout = OutStreamRedirector(self.__socket, True, self.__procuuid)
        sys.stderr = OutStreamRedirector(self.__socket, False, self.__procuuid)
        self.__redirected = True

        # Run the script
        retCode = 0
        try:
            self.__runScript(args)
        except SystemExit as exc:
            if CLIENT_DEBUG:
                print(traceback.format_exc(), file=sys.__stderr__)
            if exc.code is None:
                retCode = 0
            elif isinstance(exc.code, int):
                retCode = exc.code
            else:
                retCode = 1
                print(str(exc.code), file=sys.stderr)
        except KeyboardInterrupt as exc:
            if CLIENT_DEBUG:
                print(traceback.format_exc(), file=sys.__stderr__)
            retCode = 1
            print(traceback.format_exc(), file=sys.stderr)
        except Exception as exc:
            if CLIENT_DEBUG:
                print(traceback.format_exc(), file=sys.__stderr__)
            retCode = 1
            print(traceback.format_exc(), file=sys.stderr)
        except:
            if CLIENT_DEBUG:
                print(traceback.format_exc(), file=sys.__stderr__)
            retCode = 1
            print(traceback.format_exc(), file=sys.stderr)

        sys.stderr = stderrOld
        sys.stdout = stdoutOld
        self.__redirected = False

        # Send the return code back
        try:
            sendJSONCommand(self.__socket, METHOD_EPILOGUE_EXIT_CODE,
                            self.__procuuid, {'exitCode': retCode})
        except Exception as exc:
            print(str(exc), file=sys.stderr)
            self.close()
            return 1

        self.close()
        return 0

    def connect(self, remoteAddress, port):
        """Establishes a connection with the IDE"""
        self.__socket = QTcpSocket()
        if remoteAddress is None:
            self.__socket.connectToHost(QHostAddress.LocalHost, port)
        else:
            self.__socket.connectToHost(remoteAddress, port)
        if not self.__socket.waitForConnected(1000):
            raise Exception('Cannot connect to the IDE')
        self.__socket.setSocketOption(QAbstractSocket.KeepAliveOption, 1)
        self.__socket.setSocketOption(QAbstractSocket.LowDelayOption, 1)
        self.__socket.disconnected.connect(self.__onDisconnected)

    def __onDisconnected(self):
        """IDE dropped the socket"""
        sys.exit(0)

    def __runScript(self, arguments):
        """Runs the python script"""
        try:
            # In Py 2.x, the builtins were in __builtin__
            builtins = sys.modules['__builtin__']
        except KeyError:
            # In Py 3.x, they're in builtins
            builtins = sys.modules['builtins']

        fileName = arguments[0]

        oldMainMod = sys.modules['__main__']
        mainMod = imp.new_module('__main__')
        sys.modules['__main__'] = mainMod
        mainMod.__file__ = fileName
        mainMod.__builtins__ = builtins

        # Set sys.argv properly.
        oldArgv = sys.argv
        sys.argv = arguments

        # Without this imports of what is located at the script directory do
        # not work
        normCWD = os.path.normpath(os.getcwd())
        normScriptDir = os.path.normpath(os.path.dirname(fileName))
        sys.path.insert(0, os.getcwd())
        if normCWD != normScriptDir:
            sys.path.insert(0, os.path.dirname(fileName))

        with open(fileName, 'rb') as fileToRead:
            source = fileToRead.read()

        # We have the source.  `compile` still needs the last line to be clean,
        # so make sure it is, then compile a code object from it.
        if not source or source[-1] != b'\n':
            source += b'\n'

        code = compile(source, fileName, "exec")
        exec(code, mainMod.__dict__)

        # Restore the old __main__
        sys.modules['__main__'] = oldMainMod

        # Restore the old argv and path
        sys.argv = oldArgv

    def close(self):
        """Closes the connection if so"""
        try:
            if self.__socket:
                # Wait exit needed because otherwise IDE may get socket
                # disconnected before it has a chance to read the script
                # exit code. Wait for the explicit command to exit guarantees
                # that all the data will be received.
                waitForIDEMessage(self.__socket, METHOD_EPILOGUE_EXIT,
                                  WAIT_EXIT_COMMAND_TIMEOUT)
        finally:
            if self.__socket:
                self.__socket.close()
                self.__socket = None

    def input(self, prompt, echo):
        """Implements 'input' using the redirected input"""
        sendJSONCommand(self.__socket, METHOD_STDIN, self.__procuuid, {
            'prompt': prompt,
            'echo': echo
        })
        params = waitForIDEMessage(self.__socket, METHOD_STDIN,
                                   60 * 60 * 24 * 7)
        return params['input']

    @staticmethod
    def resolveHost(host):
        """Resolves a hostname to an IP address"""
        try:
            host, _ = host.split("@@")
            family = socket.AF_INET6
        except ValueError:
            # version = 'v4'
            family = socket.AF_INET
        return socket.getaddrinfo(host, None, family,
                                  socket.SOCK_STREAM)[0][4][0]

    @staticmethod
    def parseArgs():
        """Parses the arguments"""
        host = None
        port = None
        procuuid = None
        args = sys.argv[1:]

        while args[0]:
            if args[0] in ['--host']:
                host = args[1]
                del args[0]
                del args[0]
            elif args[0] in ['--port']:
                port = int(args[1])
                del args[0]
                del args[0]
            elif args[0] in ['--procuuid']:
                procuuid = args[1]
                del args[0]
                del args[0]
            elif args[0] == '--':
                del args[0]
                break

        return procuuid, host, port, args
예제 #40
0
class JsonRpcTcpClient(QObject):
    def __init__(self, request_handler_instance):
        QObject.__init__(self)
        self.socket = QTcpSocket(self)
        self.connectionAttempts = 1
        self.socket.readyRead.connect(self.onData)
        self.socket.error.connect(self.onSocketError)
        self.request_handler_instance = request_handler_instance
        self.nextid = 1
        self.callbacks_result = {}
        self.callbacks_error = {}
        self.buffer = b''

    def connect(self, host, port):
        self.host = host
        self.port = port
        self.socket.connectToHost(host, port)

    @QtCore.pyqtSlot(QAbstractSocket.SocketError)
    def onSocketError(self, error):
        if (error == QAbstractSocket.ConnectionRefusedError):
            self.socket.connectToHost(self.host, self.port)
            self.connectionAttempts += 1
            #self._logger.info("reconnecting to JSONRPC server {}".format(self.connectionAttempts))
        else:
            raise RuntimeError(
                "Connection error to JSON RPC server: {} ({})".format(
                    self.socket.errorString(), error))

    def close(self):
        self.socket.close()

    def parseRequest(self, request):
        try:
            m = getattr(self.request_handler_instance, request["method"])
            if "params" in request and len(request["params"]) > 0:
                result = m(*request["params"])
            else:
                result = m()

            # we do not only have a notification, but a request which awaits a response
            if "id" in request:
                responseObject = {
                    "id": request["id"],
                    "result": result,
                    "jsonrpc": "2.0"
                }
                self.socket.write(json.dumps(responseObject))
        except AttributeError:
            if "id" in request:
                responseObject = {
                    "id": request["id"],
                    "error": "no such method",
                    "jsonrpc": "2.0"
                }
                self.socket.write(json.dumps(responseObject))

    def parseResponse(self, response):
        if "error" in response:
            self._logger.error("response error {}".format(response))
            if "id" in response:
                if response["id"] in self.callbacks_error:
                    self.callbacks_error[response["id"]](response["error"])
        elif "result" in response:
            if "id" in response:
                if response["id"] in self.callbacks_result:
                    self.callbacks_result[response["id"]](response["result"])
        if "id" in response:
            self.callbacks_error.pop(response["id"], None)
            self.callbacks_result.pop(response["id"], None)

    @QtCore.pyqtSlot()
    def onData(self):
        newData = b''
        while self.socket.bytesAvailable():
            newData += bytes(self.socket.readAll())

        # this seems to be a new notification, which invalidates our buffer. This may happen on malformed JSON data
        if newData.startswith(b"{\"jsonrpc\":\"2.0\""):
            if len(self.buffer) > 0:
                self._logger.error(
                    "parse error: discarding old possibly malformed buffer data {}"
                    .format(self.buffer))
            self.buffer = newData
        else:
            self.buffer += newData
        self.buffer = self.processBuffer(self.buffer.strip())

    #from https://github.com/joncol/jcon-cpp/blob/master/src/jcon/json_rpc_endpoint.cpp#L107
    def processBuffer(self, buf):
        if len(buf) == 0:
            return b''
        if not buf.startswith(b'{'):
            self._logger.error(
                "parse error: buffer expected to start {{: {}".format(buf))
            return b''
        in_string = False
        brace_nesting_level = 0
        for i, c in enumerate(buf):
            if c == ord('"'):
                in_string = not in_string

            if not in_string:
                if c == ord('{'):
                    brace_nesting_level += 1
                if c == ord('}'):
                    brace_nesting_level -= 1
                    if brace_nesting_level < 0:
                        self._logger.error(
                            "parse error: brace_nesting_level < 0: {}".format(
                                buf))
                        return b''
                    if brace_nesting_level == 0:
                        complete_json_buf = buf[:i + 1]
                        remaining_buf = buf[i + 1:]
                        try:
                            request = json.loads(complete_json_buf)
                        except ValueError:
                            self._logger.error(
                                "json.loads failed for {}".format(
                                    complete_json_buf))
                            return b''
                        print("JsonRpcTcpClient received: {}".format(request))
                        # is this a request?
                        if "method" in request:
                            self.parseRequest(request)
                        # this is only a response
                        else:
                            self.parseResponse(request)
                        return self.processBuffer(remaining_buf.strip())
        return buf

    def call(self, method, args=[], callback_result=None, callback_error=None):
        if self.socket.state() != QAbstractSocket.ConnectedState:
            raise RuntimeError("Not connected to the JSONRPC server.")
        rpcObject = {"method": method, "params": args, "jsonrpc": "2.0"}
        if callback_result:
            rpcObject["id"] = self.nextid
            self.callbacks_result[self.nextid] = callback_result
            if callback_error:
                self.callbacks_error[self.nextid] = callback_error
            self.nextid += 1
        self._logger.debug("sending JSONRPC object {}".format(rpcObject))
        self.socket.write(json.dumps(rpcObject).encode("utf-8") + b'\n')
예제 #41
0
class Dialog(QDialog):
    TotalBytes = 50 * 1024 * 1024
    PayloadSize = 65536

    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)

        self.tcpServer = QTcpServer()
        self.tcpClient = QTcpSocket()
        self.bytesToWrite = 0
        self.bytesWritten = 0
        self.bytesReceived = 0

        self.clientProgressBar = QProgressBar()
        self.clientStatusLabel = QLabel("Client ready")
        self.serverProgressBar = QProgressBar()
        self.serverStatusLabel = QLabel("Server ready")

        self.startButton = QPushButton("&Start")
        self.quitButton = QPushButton("&Quit")

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.startButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(self.quitButton, QDialogButtonBox.RejectRole)

        self.startButton.clicked.connect(self.start)
        self.quitButton.clicked.connect(self.close)
        self.tcpServer.newConnection.connect(self.acceptConnection)
        self.tcpClient.connected.connect(self.startTransfer)
        self.tcpClient.bytesWritten.connect(self.updateClientProgress)
        self.tcpClient.error.connect(self.displayError)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.clientProgressBar)
        mainLayout.addWidget(self.clientStatusLabel)
        mainLayout.addWidget(self.serverProgressBar)
        mainLayout.addWidget(self.serverStatusLabel)
        mainLayout.addStretch(1)
        mainLayout.addSpacing(10)
        mainLayout.addWidget(buttonBox)
        self.setLayout(mainLayout)

        self.setWindowTitle("Loopback")

    def start(self):
        self.startButton.setEnabled(False)

        QApplication.setOverrideCursor(Qt.WaitCursor)

        self.bytesWritten = 0
        self.bytesReceived = 0

        while not self.tcpServer.isListening() and not self.tcpServer.listen():
            ret = QMessageBox.critical(self, "Loopback",
                    "Unable to start the test: %s." % self.tcpServer.errorString(),
                    QMessageBox.Retry | QMessageBox.Cancel)
            if ret == QMessageBox.Cancel:
                return

        self.serverStatusLabel.setText("Listening")
        self.clientStatusLabel.setText("Connecting")

        self.tcpClient.connectToHost(QHostAddress(QHostAddress.LocalHost), self.tcpServer.serverPort())

    def acceptConnection(self):
        self.tcpServerConnection = self.tcpServer.nextPendingConnection()
        self.tcpServerConnection.readyRead.connect(self.updateServerProgress)
        self.tcpServerConnection.error.connect(self.displayError)

        self.serverStatusLabel.setText("Accepted connection")
        self.tcpServer.close()

    def startTransfer(self):
        self.bytesToWrite = Dialog.TotalBytes - self.tcpClient.write(QByteArray(Dialog.PayloadSize, '@'))
        self.clientStatusLabel.setText("Connected")

    def updateServerProgress(self):
        self.bytesReceived += self.tcpServerConnection.bytesAvailable()
        self.tcpServerConnection.readAll()

        self.serverProgressBar.setMaximum(Dialog.TotalBytes)
        self.serverProgressBar.setValue(self.bytesReceived)
        self.serverStatusLabel.setText("Received %dMB" % (self.bytesReceived / (1024 * 1024)))

        if self.bytesReceived == Dialog.TotalBytes:
            self.tcpServerConnection.close()
            self.startButton.setEnabled(True)
            QApplication.restoreOverrideCursor()

    def updateClientProgress(self, numBytes):
        self.bytesWritten += numBytes
        if self.bytesToWrite > 0:
            self.bytesToWrite -= self.tcpClient.write(QByteArray(
                                        min(self.bytesToWrite, Dialog.PayloadSize), '@'))

        self.clientProgressBar.setMaximum(Dialog.TotalBytes)
        self.clientProgressBar.setValue(self.bytesWritten)
        self.clientStatusLabel.setText("Sent %dMB" % (self.bytesWritten / (1024 * 1024)))

    def displayError(self, socketError):
        if socketError == QTcpSocket.RemoteHostClosedError:
            return

        QMessageBox.information(self, "Network error",
                "The following error occured: %s." % self.tcpClient.errorString())

        self.tcpClient.close()
        self.tcpServer.close()
        self.clientProgressBar.reset()
        self.serverProgressBar.reset()
        self.clientStatusLabel.setText("Client ready")
        self.serverStatusLabel.setText("Server ready")
        self.startButton.setEnabled(True)
        QApplication.restoreOverrideCursor()
예제 #42
-1
class Client(QDialog):
    def __init__(self):
        super().__init__()
        self.tcpSocket = QTcpSocket(self)
        self.blockSize = 0
        self.makeRequest()
        self.tcpSocket.waitForConnected(1000)
        # send any message you like it could come from a widget text.
        self.tcpSocket.write(b'hello')
        self.tcpSocket.readyRead.connect(self.dealCommunication)
        self.tcpSocket.error.connect(self.displayError)

    def makeRequest(self):
        HOST = '127.0.0.1'
        PORT = 8000
        self.tcpSocket.connectToHost(HOST, PORT, QIODevice.ReadWrite)

    def dealCommunication(self):
        instr = QDataStream(self.tcpSocket)
        instr.setVersion(QDataStream.Qt_5_0)
        if self.blockSize == 0:
            if self.tcpSocket.bytesAvailable() < 2:
                return
            self.blockSize = instr.readUInt16()
        if self.tcpSocket.bytesAvailable() < self.blockSize:
            return
        # Print response to terminal, we could use it anywhere else we wanted.
        print(str(instr.readString(), encoding='ascii'))

    def displayError(self, socketError):
        if socketError == QAbstractSocket.RemoteHostClosedError:
            pass
        else:
            print(self, "The following error occurred: %s." % self.tcpSocket.errorString())