src/eric7/MicroPython/Devices/RP2040Devices.py

branch
mpy_network
changeset 9836
902ec9a04ebe
parent 9835
b4b07de1b695
child 9838
d6b87ef03c13
equal deleted inserted replaced
9835:b4b07de1b695 9836:902ec9a04ebe
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.
431 import network 440 import network
432 if hasattr(network, 'WLAN'): 441 if hasattr(network, 'WLAN'):
433 return True, 'picow' 442 return True, 'picow'
434 except ImportError: 443 except ImportError:
435 try: 444 try:
436 import picowireless 445 import picowireless as pw
437 picowireless.init() 446 try:
438 return True, 'pimoroni' 447 if pw.get_fw_version() != '':
448 return True, 'pimoroni'
449 except RuntimeError:
450 picowireless.init()
451 return True, 'pimoroni'
439 except ImportError: 452 except ImportError:
440 pass 453 pass
441 454
442 return False, '' 455 return False, ''
443 456
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
505 518
506 wifi_status() 519 wifi_status()
507 del wifi_status 520 del wifi_status
508 """ 521 """
509 elif self._deviceData["wifi_type"] == "pimoroni": 522 elif self._deviceData["wifi_type"] == "pimoroni":
510 # TODO: not yet implemented
511 command = """ 523 command = """
512 def wifi_status(): 524 def wifi_status():
513 import picowireless as pw 525 import picowireless as pw
514 import ubinascii 526 import ubinascii
515 import ujson 527 import ujson
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(
776 851
777 wifi = network.WLAN(network.STA_IF) 852 wifi = network.WLAN(network.STA_IF)
778 if wifi.isconnected(): 853 if wifi.isconnected():
779 s = socket.socket() 854 s = socket.socket()
780 try: 855 try:
781 s.connect(socket.getaddrinfo('google.com', 80)[0][-1]) 856 s.connect(socket.getaddrinfo('quad9.net', 80)[0][-1])
782 s.close() 857 s.close()
783 print(True) 858 print(True)
784 except: 859 except:
785 print(False) 860 print(False)
786 else: 861 else:
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

eric ide

mercurial