7 Module implementing the device interface class for RP2040 based boards |
7 Module implementing the device interface class for RP2040 based boards |
8 (e.g. Raspberry Pi Pico). |
8 (e.g. Raspberry Pi Pico). |
9 """ |
9 """ |
10 |
10 |
11 import ast |
11 import ast |
|
12 import binascii |
12 import json |
13 import json |
13 |
14 |
14 from PyQt6.QtCore import QUrl, pyqtSlot |
15 from PyQt6.QtCore import QUrl, pyqtSlot |
15 from PyQt6.QtNetwork import QNetworkRequest |
16 from PyQt6.QtNetwork import QNetworkRequest |
16 from PyQt6.QtWidgets import QDialog, QMenu |
17 from PyQt6.QtWidgets import QDialog, QMenu |
45 |
46 |
46 self.__createRP2040Menu() |
47 self.__createRP2040Menu() |
47 |
48 |
48 self.__statusTranslations = { |
49 self.__statusTranslations = { |
49 "picow": { |
50 "picow": { |
50 -3: self.tr('wrong password'), |
51 -3: self.tr('authentication failed'), |
51 -2: self.tr('no access point found'), |
52 -2: self.tr('no matching access point found'), |
52 -1: self.tr('connection failed'), |
53 -1: self.tr('connection failed'), |
53 0: self.tr('idle'), |
54 0: self.tr('idle'), |
54 1: self.tr('connecting'), |
55 1: self.tr('connecting'), |
55 2: self.tr('getting IP address'), |
56 2: self.tr('connected, waiting for IP address'), |
56 3: self.tr('connection successful'), |
57 3: self.tr('connected'), |
57 }, |
58 }, |
58 "pimoroni": { |
59 "pimoroni": { |
59 # TODO: not yet implemented |
60 # TODO: not yet implemented |
60 }, |
61 }, |
|
62 } |
|
63 self.__securityTranslations = { |
|
64 0: self.tr("open", "open WiFi network"), |
|
65 1: "WEP", |
|
66 2: "WPA", |
|
67 3: "WPA2", |
|
68 4: "WPA/WPA2", |
|
69 5: "WPA2 (CCMP)", |
|
70 6: "WPA3", |
|
71 7: "WPA2/WPA3" |
61 } |
72 } |
62 |
73 |
63 def setButtons(self): |
74 def setButtons(self): |
64 """ |
75 """ |
65 Public method to enable the supported action buttons. |
76 Public method to enable the supported action buttons. |
579 if err: |
590 if err: |
580 return False, err |
591 return False, err |
581 |
592 |
582 return out.decode("utf-8").strip() == "True", "" |
593 return out.decode("utf-8").strip() == "True", "" |
583 |
594 |
|
595 def checkInternet(self): |
|
596 """ |
|
597 Public method to check, if the internet can be reached. |
|
598 |
|
599 @return tuple containing a flag indicating reachability and an error string |
|
600 @rtype tuple of (bool, str) |
|
601 """ |
|
602 if self._deviceData["wifi_type"] == "picow": |
|
603 command = """ |
|
604 def check_internet(): |
|
605 import network |
|
606 import socket |
|
607 |
|
608 wifi = network.WLAN(network.STA_IF) |
|
609 if wifi.isconnected(): |
|
610 s = socket.socket() |
|
611 try: |
|
612 s.connect(socket.getaddrinfo('google.com', 80)[0][-1]) |
|
613 s.close() |
|
614 print(True) |
|
615 except: |
|
616 print(False) |
|
617 else: |
|
618 print(False) |
|
619 |
|
620 check_internet() |
|
621 del check_internet |
|
622 """ |
|
623 elif self._deviceData["wifi_type"] == "pimoroni": |
|
624 # TODO: not yet implemented |
|
625 pass |
|
626 else: |
|
627 return super().checkInternet() |
|
628 |
|
629 out, err = self._interface.execute(command) |
|
630 if err: |
|
631 return False, err |
|
632 |
|
633 return out.decode("utf-8").strip() == "True", "" |
|
634 |
|
635 def scanNetworks(self): |
|
636 """ |
|
637 Public method to scan for available WiFi networks. |
|
638 |
|
639 @return tuple containing the list of available networks as a tuple of 'Name', |
|
640 'MAC-Address', 'channel', 'RSSI' and 'security' and an error string |
|
641 @rtype tuple of (list of tuple of (str, str, int, int, str), str) |
|
642 """ |
|
643 if self._deviceData["wifi_type"] == "picow": |
|
644 command = """ |
|
645 def scan_networks(): |
|
646 import network |
|
647 |
|
648 wifi = network.WLAN(network.STA_IF) |
|
649 active = wifi.active() |
|
650 if not active: |
|
651 wifi.active(True) |
|
652 network_list = wifi.scan() |
|
653 if not active: |
|
654 wifi.active(False) |
|
655 print(network_list) |
|
656 |
|
657 scan_networks() |
|
658 del scan_networks |
|
659 """ |
|
660 elif self._deviceData["wifi_type"] == "pimoroni": |
|
661 # TODO: not yet implemented |
|
662 pass |
|
663 else: |
|
664 return super().checkInternet() |
|
665 |
|
666 out, err = self._interface.execute(command, timeout=15000) |
|
667 if err: |
|
668 return [], err |
|
669 |
|
670 networksList = ast.literal_eval(out.decode("utf-8")) |
|
671 networks = [] |
|
672 for network in networksList: |
|
673 if network[0]: |
|
674 ssid = network[0].decode("utf-8") |
|
675 mac = binascii.hexlify(network[1], ":").decode("utf-8") |
|
676 channel = network[2] |
|
677 rssi = network[3] |
|
678 try: |
|
679 security = self.__securityTranslations[network[4]] |
|
680 except KeyError: |
|
681 security = self.tr("unknown ({0})").format(network[4]) |
|
682 networks.append((ssid, mac, channel, rssi, security)) |
|
683 |
|
684 return networks, "" |
|
685 |
|
686 ############################################################################ |
|
687 ## RP2 only methods below |
|
688 ############################################################################ |
|
689 |
584 @pyqtSlot() |
690 @pyqtSlot() |
585 def __setCountry(self): |
691 def __setCountry(self): |
586 """ |
692 """ |
587 Private slot to configure the country of the connected RP2040 device. |
693 Private slot to configure the country of the connected RP2040 device. |
588 |
694 |