70 9: self.tr("AP failed"), |
70 9: self.tr("AP failed"), |
71 }, |
71 }, |
72 } |
72 } |
73 # TODO: must be specific (picow, pimoroni) |
73 # TODO: must be specific (picow, pimoroni) |
74 self.__securityTranslations = { |
74 self.__securityTranslations = { |
75 0: self.tr("open", "open WiFi network"), |
75 "picow": { |
76 1: "WEP", |
76 0: self.tr("open", "open WiFi network"), |
77 2: "WPA", |
77 1: "WEP", |
78 3: "WPA2", |
78 2: "WPA", |
79 4: "WPA/WPA2", |
79 3: "WPA2", |
80 5: "WPA2 (CCMP)", |
80 4: "WPA/WPA2", |
81 6: "WPA3", |
81 5: "WPA2 (CCMP)", |
82 7: "WPA2/WPA3", |
82 6: "WPA3", |
|
83 7: "WPA2/WPA3", |
|
84 }, |
|
85 "pimoroni": { |
|
86 2: "WPA", |
|
87 4: "WPA2 (CCMP)", |
|
88 5: "WEP", |
|
89 7: self.tr("open", "open WiFi network"), |
|
90 8: self.tr("automatic"), |
|
91 }, |
83 } |
92 } |
84 |
93 |
85 def setButtons(self): |
94 def setButtons(self): |
86 """ |
95 """ |
87 Public method to enable the supported action buttons. |
96 Public method to enable the supported action buttons. |
446 """ |
459 """ |
447 out, err = self._interface.execute( |
460 out, err = self._interface.execute( |
448 command, mode=self._submitMode, timeout=10000 |
461 command, mode=self._submitMode, timeout=10000 |
449 ) |
462 ) |
450 if err: |
463 if err: |
451 if not err.startswith("Timeout "): |
464 if not err.startswith(b"Timeout "): |
452 raise OSError(self._shortError(err)) |
465 raise OSError(self._shortError(err)) |
453 else: |
466 else: |
454 return False # pimoroni firmware loaded but no pico wireless present |
467 return False # pimoroni firmware loaded but no pico wireless present |
455 return ast.literal_eval(out.decode("utf-8")) |
468 return ast.literal_eval(out.decode("utf-8")) |
456 |
469 |
530 'mac': ubinascii.hexlify(pw.get_mac_address(), ':').decode(), |
542 'mac': ubinascii.hexlify(pw.get_mac_address(), ':').decode(), |
531 } |
543 } |
532 if station['connected']: |
544 if station['connected']: |
533 station.update({ |
545 station.update({ |
534 'ap_ssid': pw.get_current_ssid(), |
546 'ap_ssid': pw.get_current_ssid(), |
535 'ap_bssid': binascii.hexlify(pw.get_current_bssid(), ':'), |
547 'ap_bssid': ubinascii.hexlify(pw.get_current_bssid(), ':'), |
536 'ap_rssi': pw.get_current_rssi(), |
548 'ap_rssi': pw.get_current_rssi(), |
537 'ap_security': pw.get_current_encryption_type(), |
549 'ap_security': pw.get_current_encryption_type(), |
538 }) |
550 }) |
539 print(ujson.dumps(station)) |
551 print(ujson.dumps(station)) |
540 |
552 |
544 'status': pw.get_connection_status(), |
556 'status': pw.get_connection_status(), |
545 'mac': ubinascii.hexlify(pw.get_mac_address(), ':').decode(), |
557 'mac': ubinascii.hexlify(pw.get_mac_address(), ':').decode(), |
546 } |
558 } |
547 if ap['active']: |
559 if ap['active']: |
548 ap['essid'] = pw.get_current_ssid() |
560 ap['essid'] = pw.get_current_ssid() |
|
561 ap['ifconfig'] = ( |
|
562 ip_str(pw.get_ip_address()), |
|
563 ip_str(pw.get_subnet_mask()), |
|
564 ip_str(pw.get_gateway_ip()), |
|
565 '0.0.0.0' |
|
566 ) |
549 print(ujson.dumps(ap)) |
567 print(ujson.dumps(ap)) |
550 |
568 |
551 overall = { |
569 overall = { |
552 'active': pw.get_connection_status() != 0 |
570 'active': pw.get_connection_status() != 0 |
553 } |
571 } |
565 |
583 |
566 stationStr, apStr, overallStr = out.decode("utf-8").splitlines() |
584 stationStr, apStr, overallStr = out.decode("utf-8").splitlines() |
567 station = json.loads(stationStr) |
585 station = json.loads(stationStr) |
568 ap = json.loads(apStr) |
586 ap = json.loads(apStr) |
569 overall = json.loads(overallStr) |
587 overall = json.loads(overallStr) |
570 try: |
588 if "status" in station: |
571 station["status"] = self.__statusTranslations[ |
589 # translate the numerical status to a string |
572 self._deviceData["wifi_type"] |
590 try: |
573 ][station["status"]] |
591 station["status"] = self.__statusTranslations[ |
574 except KeyError: |
592 self._deviceData["wifi_type"] |
575 station["status"] = str(station["status"]) |
593 ][station["status"]] |
576 try: |
594 except KeyError: |
577 ap["status"] = self.__statusTranslations[self._deviceData["wifi_type"]][ |
595 station["status"] = str(station["status"]) |
578 ap["status"] |
596 if "status" in station: |
579 ] |
597 # translate the numerical status to a string |
580 except KeyError: |
598 try: |
581 ap["status"] = str(ap["status"]) |
599 ap["status"] = self.__statusTranslations[self._deviceData["wifi_type"]][ |
|
600 ap["status"] |
|
601 ] |
|
602 except KeyError: |
|
603 ap["status"] = str(ap["status"]) |
|
604 if "ap_security" in station: |
|
605 # translate the numerical AP security to a string |
|
606 try: |
|
607 station["ap_security"] = self.__securityTranslations[ |
|
608 self._deviceData["wifi_type"] |
|
609 ][station["ap_security"]] |
|
610 except KeyError: |
|
611 station["ap_security"] = self.tr("unknown ({0})").format( |
|
612 station["ap_security"] |
|
613 ) |
582 return station, ap, overall |
614 return station, ap, overall |
583 |
615 |
584 def connectWifi(self, ssid, password): |
616 def connectWifi(self, ssid, password): |
585 """ |
617 """ |
586 Public method to connect a device to a WiFi network. |
618 Public method to connect a device to a WiFi network. |
622 repr(ssid), |
654 repr(ssid), |
623 repr(password if password else ""), |
655 repr(password if password else ""), |
624 repr(country if country else "XX"), |
656 repr(country if country else "XX"), |
625 ) |
657 ) |
626 elif self._deviceData["wifi_type"] == "pimoroni": |
658 elif self._deviceData["wifi_type"] == "pimoroni": |
627 # TODO: not yet implemented |
659 command = """ |
628 pass |
660 def connect_wifi(ssid, password): |
|
661 import picowireless as pw |
|
662 import ujson |
|
663 from time import sleep |
|
664 |
|
665 pw.init() |
|
666 if bool(password): |
|
667 pw.wifi_set_passphrase(ssid, password) |
|
668 else: |
|
669 pw.wifi_set_network(ssid) |
|
670 |
|
671 max_wait = 140 |
|
672 while max_wait: |
|
673 if pw.get_connection_status() == 3: |
|
674 break |
|
675 max_wait -= 1 |
|
676 sleep(0.1) |
|
677 status = pw.get_connection_status() |
|
678 if status == 3: |
|
679 pw.set_led(0, 64, 0) |
|
680 else: |
|
681 pw.set_led(64, 0, 0) |
|
682 print(ujson.dumps({{'connected': status == 3, 'status': status}})) |
|
683 |
|
684 connect_wifi({0}, {1}) |
|
685 del connect_wifi |
|
686 """.format( |
|
687 repr(ssid), |
|
688 repr(password if password else ""), |
|
689 ) |
629 else: |
690 else: |
630 return super().connectWifi(ssid, password) |
691 return super().connectWifi(ssid, password) |
631 |
692 |
632 with EricOverrideCursor(): |
693 with EricOverrideCursor(): |
633 out, err = self._interface.execute( |
694 out, err = self._interface.execute( |
670 |
731 |
671 disconnect_wifi() |
732 disconnect_wifi() |
672 del disconnect_wifi |
733 del disconnect_wifi |
673 """ |
734 """ |
674 elif self._deviceData["wifi_type"] == "pimoroni": |
735 elif self._deviceData["wifi_type"] == "pimoroni": |
675 # TODO: not yet implemented |
736 command = """ |
676 pass |
737 def disconnect_wifi(): |
|
738 import picowireless as pw |
|
739 from time import sleep |
|
740 |
|
741 pw.disconnect() |
|
742 sleep(0.1) |
|
743 print(pw.get_connection_status() != 3) |
|
744 pw.set_led(0, 0, 0) |
|
745 |
|
746 disconnect_wifi() |
|
747 del disconnect_wifi |
|
748 """ |
677 else: |
749 else: |
678 return super().disconnectWifi() |
750 return super().disconnectWifi() |
679 |
751 |
680 out, err = self._interface.execute(command, mode=self._submitMode) |
752 out, err = self._interface.execute(command, mode=self._submitMode) |
681 if err: |
753 if err: |
726 else: |
798 else: |
727 secrets = "WIFI_SSID = {0}\nWIFI_KEY = {1}\n".format( |
799 secrets = "WIFI_SSID = {0}\nWIFI_KEY = {1}\n".format( |
728 repr(ssid), |
800 repr(ssid), |
729 repr(password) if password else '""', |
801 repr(password) if password else '""', |
730 ) |
802 ) |
731 wifiConnectFile = "mpyWiFiConnect.py" |
803 if self._deviceData["wifi_type"] == "pimoroni": |
|
804 wifiConnectFile = "pimoroniWiFiConnect.py" |
|
805 else: |
|
806 wifiConnectFile = "mpyWiFiConnect.py" |
732 try: |
807 try: |
733 # write secrets file |
808 # write secrets file |
734 self.putData("/secrets.py", secrets.encode("utf-8")) |
809 self.putData("/secrets.py", secrets.encode("utf-8")) |
735 # copy auto-connect file |
810 # copy auto-connect file |
736 self.put( |
811 self.put( |
788 |
863 |
789 check_internet() |
864 check_internet() |
790 del check_internet |
865 del check_internet |
791 """ |
866 """ |
792 elif self._deviceData["wifi_type"] == "pimoroni": |
867 elif self._deviceData["wifi_type"] == "pimoroni": |
793 # TODO: not yet implemented |
868 command = """ |
794 pass |
869 def check_internet(): |
|
870 import picowireless as pw |
|
871 |
|
872 if pw.get_connection_status() == 3: |
|
873 res = pw.ping((9, 9, 9, 9), 300) |
|
874 print(res >= 0) |
|
875 else: |
|
876 print(False) |
|
877 |
|
878 check_internet() |
|
879 del check_internet |
|
880 """ |
795 else: |
881 else: |
796 return super().checkInternet() |
882 return super().checkInternet() |
797 |
883 |
798 out, err = self._interface.execute(command, mode=self._submitMode) |
884 out, err = self._interface.execute( |
|
885 command, mode=self._submitMode, timeout=10000 |
|
886 ) |
799 if err: |
887 if err: |
800 return False, err |
888 return False, err |
801 |
889 |
802 return out.decode("utf-8").strip() == "True", "" |
890 return out.decode("utf-8").strip() == "True", "" |
803 |
891 |
832 """.format( |
920 """.format( |
833 repr(country if country else "XX") |
921 repr(country if country else "XX") |
834 ) |
922 ) |
835 |
923 |
836 elif self._deviceData["wifi_type"] == "pimoroni": |
924 elif self._deviceData["wifi_type"] == "pimoroni": |
837 # TODO: not yet implemented |
925 command = """ |
838 pass |
926 def scan_networks(): |
|
927 import picowireless as pw |
|
928 |
|
929 network_list = [] |
|
930 pw.init() |
|
931 pw.start_scan_networks() |
|
932 networks = pw.get_scan_networks() |
|
933 for n in range(networks): |
|
934 network_list.append(( |
|
935 pw.get_ssid_networks(n), |
|
936 pw.get_bssid_networks(n), |
|
937 pw.get_channel_networks(n), |
|
938 pw.get_rssi_networks(n), |
|
939 pw.get_enc_type_networks(n), |
|
940 )) |
|
941 print(network_list) |
|
942 |
|
943 scan_networks() |
|
944 del scan_networks |
|
945 """ |
839 else: |
946 else: |
840 return super().scanNetworks() |
947 return super().scanNetworks() |
841 |
948 |
842 out, err = self._interface.execute( |
949 out, err = self._interface.execute( |
843 command, mode=self._submitMode, timeout=15000 |
950 command, mode=self._submitMode, timeout=15000 |
847 |
954 |
848 networksList = ast.literal_eval(out.decode("utf-8")) |
955 networksList = ast.literal_eval(out.decode("utf-8")) |
849 networks = [] |
956 networks = [] |
850 for network in networksList: |
957 for network in networksList: |
851 if network[0]: |
958 if network[0]: |
852 ssid = network[0].decode("utf-8") |
959 ssid = ( |
853 mac = binascii.hexlify(network[1], ":").decode("utf-8") |
960 network[0].decode("utf-8") |
|
961 if isinstance(network[0], bytes) |
|
962 else network[0] |
|
963 ) |
|
964 mac = ( |
|
965 binascii.hexlify(network[1], ":").decode("utf-8") |
|
966 if network[1] is not None |
|
967 else "" |
|
968 ) |
854 channel = network[2] |
969 channel = network[2] |
855 rssi = network[3] |
970 rssi = network[3] |
856 try: |
971 try: |
857 security = self.__securityTranslations[network[4]] |
972 security = self.__securityTranslations[ |
|
973 self._deviceData["wifi_type"] |
|
974 ][network[4]] |
858 except KeyError: |
975 except KeyError: |
859 security = self.tr("unknown ({0})").format(network[4]) |
976 security = self.tr("unknown ({0})").format(network[4]) |
860 networks.append((ssid, mac, channel, rssi, security)) |
977 networks.append((ssid, mac, channel, rssi, security)) |
861 |
978 |
862 return networks, "" |
979 return networks, "" |
892 del deactivate |
1009 del deactivate |
893 """.format( |
1010 """.format( |
894 interface |
1011 interface |
895 ) |
1012 ) |
896 elif self._deviceData["wifi_type"] == "pimoroni": |
1013 elif self._deviceData["wifi_type"] == "pimoroni": |
897 # TODO: not yet implemented |
1014 command = """ |
898 pass |
1015 def deactivate(): |
|
1016 import picowireless as pw |
|
1017 |
|
1018 pw.init() |
|
1019 print(True) |
|
1020 |
|
1021 deactivate() |
|
1022 del deactivate |
|
1023 """ |
899 else: |
1024 else: |
900 return super().deactivateInterface(interface) |
1025 return super().deactivateInterface(interface) |
901 |
1026 |
902 out, err = self._interface.execute(command, mode=self._submitMode) |
1027 out, err = self._interface.execute(command, mode=self._submitMode) |
903 if err: |
1028 if err: |
953 repr(password), |
1078 repr(password), |
954 ifconfig, |
1079 ifconfig, |
955 repr(country if country else "XX"), |
1080 repr(country if country else "XX"), |
956 ) |
1081 ) |
957 elif self._deviceData["wifi_type"] == "pimoroni": |
1082 elif self._deviceData["wifi_type"] == "pimoroni": |
958 # TODO: not yet implemented |
1083 # AP is fixed at channel 6 |
959 pass |
1084 command = """ |
|
1085 def start_ap(ssid, password): |
|
1086 import picowireless as pw |
|
1087 |
|
1088 pw.init() |
|
1089 if bool(password): |
|
1090 res = pw.wifi_set_ap_passphrase(ssid, password, 6) |
|
1091 else: |
|
1092 res = pw.wifi_set_ap_network(ssid, 6) |
|
1093 status = pw.get_connection_status() |
|
1094 if status in (7, 8): |
|
1095 pw.set_led(0, 64, 0) |
|
1096 else: |
|
1097 pw.set_led(64, 0, 0) |
|
1098 print(res >= 0) |
|
1099 |
|
1100 start_ap({0}, {1}) |
|
1101 del start_ap |
|
1102 """.format( |
|
1103 repr(ssid), |
|
1104 repr(password if password else ""), |
|
1105 ) |
960 else: |
1106 else: |
961 return super().startAccessPoint(ssid, security=security, password=password) |
1107 return super().startAccessPoint(ssid, security=security, password=password) |
962 |
1108 |
963 out, err = self._interface.execute( |
1109 out, err = self._interface.execute( |
964 command, mode=self._submitMode, timeout=15000 |
1110 command, mode=self._submitMode, timeout=15000 |
973 Public method to stop the access point interface. |
1119 Public method to stop the access point interface. |
974 |
1120 |
975 @return tuple containg a flag indicating success and an error message |
1121 @return tuple containg a flag indicating success and an error message |
976 @rtype tuple of (bool, str) |
1122 @rtype tuple of (bool, str) |
977 """ |
1123 """ |
978 if self._deviceData["wifi_type"] == "picow": |
1124 if self._deviceData["wifi_type"] in ("picow", "pimoroni"): |
979 return self.deactivateInterface("AP") |
1125 return self.deactivateInterface("AP") |
980 elif self._deviceData["wifi_type"] == "pimoroni": |
|
981 # TODO: not yet implemented |
|
982 pass |
|
983 else: |
1126 else: |
984 return super().stopAccessPoint() |
1127 return super().stopAccessPoint() |
985 |
1128 |
986 def getConnectedClients(self): |
1129 def getConnectedClients(self): |
987 """ |
1130 """ |
1002 |
1145 |
1003 get_stations() |
1146 get_stations() |
1004 del get_stations |
1147 del get_stations |
1005 """ |
1148 """ |
1006 elif self._deviceData["wifi_type"] == "pimoroni": |
1149 elif self._deviceData["wifi_type"] == "pimoroni": |
1007 # TODO: not yet implemented |
1150 return ( |
1008 pass |
1151 [], |
|
1152 self.tr( |
|
1153 "Showing connected clients is not supported for 'pico wireless'." |
|
1154 ), |
|
1155 ) |
1009 else: |
1156 else: |
1010 return super().checkInternet() |
1157 return super().checkInternet() |
1011 |
1158 |
1012 out, err = self._interface.execute( |
1159 out, err = self._interface.execute( |
1013 command, mode=self._submitMode, timeout=10000 |
1160 command, mode=self._submitMode, timeout=10000 |