56 1: self.tr("connecting"), |
56 1: self.tr("connecting"), |
57 2: self.tr("connected, waiting for IP address"), |
57 2: self.tr("connected, waiting for IP address"), |
58 3: self.tr("connected"), |
58 3: self.tr("connected"), |
59 }, |
59 }, |
60 "pimoroni": { |
60 "pimoroni": { |
61 # TODO: not yet implemented |
61 0: self.tr("idle"), |
|
62 1: self.tr("no matching access point found"), |
|
63 2: self.tr("network scan completed"), |
|
64 3: self.tr("connected"), |
|
65 4: self.tr("connection failed"), |
|
66 5: self.tr("connection lost"), |
|
67 6: self.tr("disconnected"), |
|
68 7: self.tr("AP listening"), |
|
69 8: self.tr("AP connected"), |
|
70 9: self.tr("AP failed"), |
62 }, |
71 }, |
63 } |
72 } |
|
73 # TODO: must be specific (picow, pimoroni) |
64 self.__securityTranslations = { |
74 self.__securityTranslations = { |
65 0: self.tr("open", "open WiFi network"), |
75 0: self.tr("open", "open WiFi network"), |
66 1: "WEP", |
76 1: "WEP", |
67 2: "WPA", |
77 2: "WPA", |
68 3: "WPA2", |
78 3: "WPA2", |
165 self.tr("Activate Bootloader"), self.__activateBootloader |
175 self.tr("Activate Bootloader"), self.__activateBootloader |
166 ) |
176 ) |
167 self.__flashMpyAct = self.__rp2040Menu.addAction( |
177 self.__flashMpyAct = self.__rp2040Menu.addAction( |
168 self.tr("Flash MicroPython Firmware"), self.__flashPython |
178 self.tr("Flash MicroPython Firmware"), self.__flashPython |
169 ) |
179 ) |
|
180 self.__rp2040Menu.addSeparator() |
|
181 self.__resetAct = self.__rp2040Menu.addAction( |
|
182 self.tr("Reset Device"), self.__resetDevice |
|
183 ) |
170 |
184 |
171 def addDeviceMenuEntries(self, menu): |
185 def addDeviceMenuEntries(self, menu): |
172 """ |
186 """ |
173 Public method to add device specific entries to the given menu. |
187 Public method to add device specific entries to the given menu. |
174 |
188 |
179 linkConnected = self.microPython.isLinkConnected() |
193 linkConnected = self.microPython.isLinkConnected() |
180 |
194 |
181 self.__showMpyAct.setEnabled(connected) |
195 self.__showMpyAct.setEnabled(connected) |
182 self.__bootloaderAct.setEnabled(connected) |
196 self.__bootloaderAct.setEnabled(connected) |
183 self.__flashMpyAct.setEnabled(not linkConnected) |
197 self.__flashMpyAct.setEnabled(not linkConnected) |
|
198 self.__resetAct.setEnabled(connected) |
184 |
199 |
185 menu.addMenu(self.__rp2040Menu) |
200 menu.addMenu(self.__rp2040Menu) |
186 |
201 |
187 def hasFlashMenuEntry(self): |
202 def hasFlashMenuEntry(self): |
188 """ |
203 """ |
211 if self.microPython.isConnected(): |
226 if self.microPython.isConnected(): |
212 self.microPython.deviceInterface().execute( |
227 self.microPython.deviceInterface().execute( |
213 [ |
228 [ |
214 "import machine", |
229 "import machine", |
215 "machine.bootloader()", |
230 "machine.bootloader()", |
216 ] |
231 ], |
|
232 mode=self._submitMode, |
217 ) |
233 ) |
218 # simulate pressing the disconnect button |
234 # simulate pressing the disconnect button |
219 self.microPython.on_connectButton_clicked() |
235 self.microPython.on_connectButton_clicked() |
220 |
236 |
221 @pyqtSlot() |
237 @pyqtSlot() |
300 None, |
316 None, |
301 self.tr("MicroPython Version"), |
317 self.tr("MicroPython Version"), |
302 msg, |
318 msg, |
303 ) |
319 ) |
304 |
320 |
|
321 @pyqtSlot() |
|
322 def __resetDevice(self): |
|
323 """ |
|
324 Private slot to reset the connected device. |
|
325 """ |
|
326 self.microPython.deviceInterface().execute( |
|
327 "import machine\nmachine.reset()\n", mode=self._submitMode |
|
328 ) |
|
329 |
305 def getDocumentationUrl(self): |
330 def getDocumentationUrl(self): |
306 """ |
331 """ |
307 Public method to get the device documentation URL. |
332 Public method to get the device documentation URL. |
308 |
333 |
309 @return documentation URL of the device |
334 @return documentation URL of the device |
395 @return tuple containing a flag indicating the availability of WiFi |
420 @return tuple containing a flag indicating the availability of WiFi |
396 and the WiFi type (picow or pimoroni) |
421 and the WiFi type (picow or pimoroni) |
397 @rtype tuple of (bool, str) |
422 @rtype tuple of (bool, str) |
398 @exception OSError raised to indicate an issue with the device |
423 @exception OSError raised to indicate an issue with the device |
399 """ |
424 """ |
|
425 # picowireless: |
|
426 # It seems to take up to 20 sec to detect, that no Pico Wireless Pack is |
|
427 # attached. Therefore the command will timeout before. |
400 command = """ |
428 command = """ |
401 def has_wifi(): |
429 def has_wifi(): |
402 try: |
430 try: |
403 import network |
431 import network |
404 if hasattr(network, 'WLAN'): |
432 if hasattr(network, 'WLAN'): |
405 return True, 'picow' |
433 return True, 'picow' |
406 except ImportError: |
434 except ImportError: |
407 try: |
435 try: |
408 import picowireless |
436 import picowireless |
409 if picowireless.get_fw_version() != '': |
437 picowireless.init() |
410 return True, 'pimoroni' |
438 return True, 'pimoroni' |
411 except ImportError: |
439 except ImportError: |
412 pass |
440 pass |
413 |
441 |
414 return False, '' |
442 return False, '' |
415 |
443 |
418 """ |
446 """ |
419 out, err = self._interface.execute( |
447 out, err = self._interface.execute( |
420 command, mode=self._submitMode, timeout=10000 |
448 command, mode=self._submitMode, timeout=10000 |
421 ) |
449 ) |
422 if err: |
450 if err: |
423 raise OSError(self._shortError(err)) |
451 if not err.startswith("Timeout "): |
|
452 raise OSError(self._shortError(err)) |
|
453 else: |
|
454 return False # pimoroni firmware loaded but no pico wireless present |
424 return ast.literal_eval(out.decode("utf-8")) |
455 return ast.literal_eval(out.decode("utf-8")) |
425 |
456 |
426 def getWifiData(self): |
457 def getWifiData(self): |
427 """ |
458 """ |
428 Public method to get data related to the current WiFi status. |
459 Public method to get data related to the current WiFi status. |
475 wifi_status() |
506 wifi_status() |
476 del wifi_status |
507 del wifi_status |
477 """ |
508 """ |
478 elif self._deviceData["wifi_type"] == "pimoroni": |
509 elif self._deviceData["wifi_type"] == "pimoroni": |
479 # TODO: not yet implemented |
510 # TODO: not yet implemented |
480 pass |
511 command = """ |
|
512 def wifi_status(): |
|
513 import picowireless as pw |
|
514 import ubinascii |
|
515 import ujson |
|
516 |
|
517 def ip_str(ip): |
|
518 return '.'.join(str(i) for i in ip) |
|
519 |
|
520 station = { |
|
521 'active': pw.get_connection_status() not in (0, 7, 8, 9), |
|
522 'connected': pw.get_connection_status() == 3, |
|
523 'status': pw.get_connection_status(), |
|
524 'ifconfig': ( |
|
525 ip_str(pw.get_ip_address()), |
|
526 ip_str(pw.get_subnet_mask()), |
|
527 ip_str(pw.get_gateway_ip()), |
|
528 '0.0.0.0' |
|
529 ), |
|
530 'mac': ubinascii.hexlify(pw.get_mac_address(), ':').decode(), |
|
531 } |
|
532 if station['connected']: |
|
533 station.update({ |
|
534 'ap_ssid': pw.get_current_ssid(), |
|
535 'ap_bssid': binascii.hexlify(pw.get_current_bssid(), ':'), |
|
536 'ap_rssi': pw.get_current_rssi(), |
|
537 'ap_security': pw.get_current_encryption_type(), |
|
538 }) |
|
539 print(ujson.dumps(station)) |
|
540 |
|
541 ap = { |
|
542 'active': pw.get_connection_status() in (7, 8, 9), |
|
543 'connected': pw.get_connection_status() == 8, |
|
544 'status': pw.get_connection_status(), |
|
545 'mac': ubinascii.hexlify(pw.get_mac_address(), ':').decode(), |
|
546 } |
|
547 if ap['active']: |
|
548 ap['essid'] = pw.get_current_ssid() |
|
549 print(ujson.dumps(ap)) |
|
550 |
|
551 overall = { |
|
552 'active': pw.get_connection_status() != 0 |
|
553 } |
|
554 print(ujson.dumps(overall)) |
|
555 |
|
556 wifi_status() |
|
557 del wifi_status |
|
558 """ |
481 else: |
559 else: |
482 return super().getWifiData() |
560 return super().getWifiData() |
483 |
561 |
484 out, err = self._interface.execute(command, mode=self._submitMode) |
562 out, err = self._interface.execute(command, mode=self._submitMode) |
485 if err: |
563 if err: |