504 @rtype tuple of (bool, str) |
505 @rtype tuple of (bool, str) |
505 """ |
506 """ |
506 if self._deviceData["wifi_type"] == "picow": |
507 if self._deviceData["wifi_type"] == "picow": |
507 country = Preferences.getMicroPython("WifiCountry").upper() |
508 country = Preferences.getMicroPython("WifiCountry").upper() |
508 command = """ |
509 command = """ |
509 def connect_wifi(ssid, password): |
510 def connect_wifi(ssid, password, country): |
510 import network |
511 import network |
511 import rp2 |
512 import rp2 |
512 import ujson |
513 import ujson |
513 from time import sleep |
514 from time import sleep |
514 |
515 |
515 rp2.country({2}) |
516 rp2.country(country) |
516 |
517 |
517 wifi = network.WLAN(network.STA_IF) |
518 wifi = network.WLAN(network.STA_IF) |
518 wifi.active(False) |
519 wifi.active(False) |
519 wifi.active(True) |
520 wifi.active(True) |
520 wifi.connect(ssid, password) |
521 wifi.connect(ssid, password) |
525 max_wait -= 1 |
526 max_wait -= 1 |
526 sleep(0.1) |
527 sleep(0.1) |
527 status = wifi.status() |
528 status = wifi.status() |
528 print(ujson.dumps({{'connected': wifi.isconnected(), 'status': status}})) |
529 print(ujson.dumps({{'connected': wifi.isconnected(), 'status': status}})) |
529 |
530 |
530 connect_wifi({0}, {1}) |
531 connect_wifi({0}, {1}, {2}) |
531 del connect_wifi |
532 del connect_wifi |
532 """.format( |
533 """.format( |
533 repr(ssid), |
534 repr(ssid), |
534 repr(password if password else ""), |
535 repr(password if password else ""), |
535 repr(country if country else "XX"), |
536 repr(country if country else "XX"), |
589 out, err = self._interface.execute(command) |
590 out, err = self._interface.execute(command) |
590 if err: |
591 if err: |
591 return False, err |
592 return False, err |
592 |
593 |
593 return out.decode("utf-8").strip() == "True", "" |
594 return out.decode("utf-8").strip() == "True", "" |
|
595 |
|
596 def writeCredentials(self, ssid, password): |
|
597 """ |
|
598 Public method to write the given credentials to the connected device and modify |
|
599 the start script to connect automatically. |
|
600 |
|
601 @param ssid SSID of the network to connect to |
|
602 @type str |
|
603 @param password password needed to authenticate |
|
604 @type str |
|
605 @return tuple containing a flag indicating success and an error message |
|
606 @rtype tuple of (bool, str) |
|
607 """ |
|
608 command = """ |
|
609 def modify_boot(): |
|
610 add = True |
|
611 try: |
|
612 with open('/boot.py', 'r') as f: |
|
613 for ln in f.readlines(): |
|
614 if 'wifi_connect' in ln: |
|
615 add = False |
|
616 break |
|
617 except: |
|
618 pass |
|
619 if add: |
|
620 with open('/boot.py', 'a') as f: |
|
621 f.write('\\nimport wifi_connect\\n') |
|
622 print(True) |
|
623 |
|
624 modify_boot() |
|
625 del modify_boot |
|
626 """ |
|
627 |
|
628 if self._deviceData["wifi_type"] == "picow": |
|
629 country = Preferences.getMicroPython("WifiCountry").upper() |
|
630 secrets = "WIFI_SSID = {0}\nWIFI_KEY = {1}\nWIFI_COUNTRY={2}".format( |
|
631 repr(ssid), |
|
632 repr(password) if password else '""', |
|
633 repr(country) if country else '""' |
|
634 ) |
|
635 wifiConnectFile = "picowWiFiConnect.py" |
|
636 else: |
|
637 secrets = "WIFI_SSID = {0}\nWIFI_KEY = {1}\n".format( |
|
638 repr(ssid), |
|
639 repr(password) if password else '""', |
|
640 ) |
|
641 wifiConnectFile = "mpyWiFiConnect.py" |
|
642 try: |
|
643 # write secrets file |
|
644 self.putData("/secrets.py", secrets.encode("utf-8")) |
|
645 # copy auto-connect file |
|
646 self.put( |
|
647 os.path.join( |
|
648 os.path.dirname(__file__), "MCUScripts", wifiConnectFile |
|
649 ), |
|
650 "/wifi_connect.py", |
|
651 ) |
|
652 except OSError as err: |
|
653 return False, str(err) |
|
654 |
|
655 # modify boot.py |
|
656 out, err = self._interface.execute(command) |
|
657 if err: |
|
658 return False, err |
|
659 |
|
660 return out.decode("utf-8").strip() == "True", "" |
|
661 |
|
662 def removeCredentials(self): |
|
663 """ |
|
664 Public method to remove the saved credentials from the connected device. |
|
665 |
|
666 @return tuple containing a flag indicating success and an error message |
|
667 @rtype tuple of (bool, str) |
|
668 """ |
|
669 try: |
|
670 self.rm("/secrets.py") |
|
671 except OSError as err: |
|
672 return False, str(err) |
|
673 |
|
674 return True, "" |
594 |
675 |
595 def checkInternet(self): |
676 def checkInternet(self): |
596 """ |
677 """ |
597 Public method to check, if the internet can be reached. |
678 Public method to check, if the internet can be reached. |
598 |
679 |
639 @return tuple containing the list of available networks as a tuple of 'Name', |
720 @return tuple containing the list of available networks as a tuple of 'Name', |
640 'MAC-Address', 'channel', 'RSSI' and 'security' and an error string |
721 'MAC-Address', 'channel', 'RSSI' and 'security' and an error string |
641 @rtype tuple of (list of tuple of (str, str, int, int, str), str) |
722 @rtype tuple of (list of tuple of (str, str, int, int, str), str) |
642 """ |
723 """ |
643 if self._deviceData["wifi_type"] == "picow": |
724 if self._deviceData["wifi_type"] == "picow": |
|
725 country = Preferences.getMicroPython("WifiCountry").upper() |
644 command = """ |
726 command = """ |
645 def scan_networks(): |
727 def scan_networks(): |
646 import network |
728 import network |
|
729 import rp2 |
|
730 |
|
731 rp2.country({0}) |
647 |
732 |
648 wifi = network.WLAN(network.STA_IF) |
733 wifi = network.WLAN(network.STA_IF) |
649 active = wifi.active() |
734 active = wifi.active() |
650 if not active: |
735 if not active: |
651 wifi.active(True) |
736 wifi.active(True) |
723 if err: |
809 if err: |
724 return False, err |
810 return False, err |
725 else: |
811 else: |
726 return out.decode("utf-8").strip() == "True", "" |
812 return out.decode("utf-8").strip() == "True", "" |
727 |
813 |
728 def startAccessPoint(self): |
814 def startAccessPoint(self, ssid, security=None, password=None): |
729 """ |
815 """ |
730 Public method to start the access point interface. |
816 Public method to start the access point interface. |
731 |
817 |
|
818 @param ssid SSID of the access point |
|
819 @type str |
|
820 @param security security method (defaults to None) |
|
821 @type int (optional) |
|
822 @param password password (defaults to None) |
|
823 @type str (optional) |
732 @return tuple containing a flag indicating success and an error message |
824 @return tuple containing a flag indicating success and an error message |
733 @rtype tuple of (bool, str) |
825 @rtype tuple of (bool, str) |
734 """ |
826 """ |
|
827 if security is None or password is None: |
|
828 security = 0 |
|
829 password = "" |
|
830 |
|
831 if self._deviceData["wifi_type"] == "picow": |
|
832 country = Preferences.getMicroPython("WifiCountry").upper() |
|
833 if security: |
|
834 security = 4 # Pico W supports just WPA/WPA2 |
|
835 command = """ |
|
836 def start_ap(): |
|
837 import network |
|
838 import rp2 |
|
839 from time import sleep |
|
840 |
|
841 rp2.country({3}) |
|
842 |
|
843 ap = network.WLAN(network.AP_IF) |
|
844 ap.config(ssid={0}, security={1}, password={2}) |
|
845 ap.active(True) |
|
846 sleep(0.1) |
|
847 print(ap.isconnected()) |
|
848 |
|
849 start_ap() |
|
850 del start_ap |
|
851 """.format(repr(ssid), security, repr(password), repr(country if country else "XX")) |
|
852 elif self._deviceData["wifi_type"] == "pimoroni": |
|
853 # TODO: not yet implemented |
|
854 pass |
|
855 else: |
|
856 return super().startAccessPoint(ssid, security=security, password=password) |
|
857 |
|
858 out, err = self._interface.execute(command, timeout=15000) |
|
859 if err: |
|
860 return False, err |
|
861 else: |
|
862 return out.decode("utf-8").strip() == "True", "" |
735 |
863 |
736 def stopAccessPoint(self): |
864 def stopAccessPoint(self): |
737 """ |
865 """ |
738 Public method to stop the access point interface. |
866 Public method to stop the access point interface. |
739 |
867 |
746 # TODO: not yet implemented |
874 # TODO: not yet implemented |
747 pass |
875 pass |
748 else: |
876 else: |
749 return super().stopAccessPoint() |
877 return super().stopAccessPoint() |
750 |
878 |
|
879 def getConnectedClients(self): |
|
880 """ |
|
881 Public method to get a list of connected clients. |
|
882 |
|
883 @return a tuple containing a list of tuples containing the client MAC-Address |
|
884 and the RSSI (if supported and available) and an error message |
|
885 @rtype tuple of ([(bytes, int)], str) |
|
886 """ |
|
887 if self._deviceData["wifi_type"] == "picow": |
|
888 command = """ |
|
889 def get_stations(): |
|
890 import network |
|
891 |
|
892 ap = network.WLAN(network.AP_IF) |
|
893 stations = ap.status('stations') |
|
894 print(stations) |
|
895 |
|
896 get_stations() |
|
897 del get_stations |
|
898 """ |
|
899 elif self._deviceData["wifi_type"] == "pimoroni": |
|
900 # TODO: not yet implemented |
|
901 pass |
|
902 else: |
|
903 return super().checkInternet() |
|
904 |
|
905 out, err = self._interface.execute(command, timeout=10000) |
|
906 if err: |
|
907 return [], err |
|
908 |
|
909 clientsList = ast.literal_eval(out.decode("utf-8")) |
|
910 return clientsList, "" |
|
911 |
751 ############################################################################ |
912 ############################################################################ |
752 ## RP2 only methods below |
913 ## RP2 only methods below |
753 ############################################################################ |
914 ############################################################################ |
754 |
915 |
755 @pyqtSlot() |
916 @pyqtSlot() |
772 rp2.country({0}) |
933 rp2.country({0}) |
773 """.format(repr(country)) |
934 """.format(repr(country)) |
774 |
935 |
775 out, err = self._interface.execute(command) |
936 out, err = self._interface.execute(command) |
776 if err: |
937 if err: |
777 self._showError("rp2.country()", err) |
938 self.microPython.showError("rp2.country()", err) |
778 |
939 |
779 |
940 |
780 def createDevice(microPythonWidget, deviceType, vid, pid, boardName, serialNumber): |
941 def createDevice(microPythonWidget, deviceType, vid, pid, boardName, serialNumber): |
781 """ |
942 """ |
782 Function to instantiate a MicroPython device object. |
943 Function to instantiate a MicroPython device object. |