diff -r 1a09700229e7 -r 9854647c8c5c src/eric7/MicroPython/MicroPythonDevices.py --- a/src/eric7/MicroPython/MicroPythonDevices.py Sun Feb 12 18:11:20 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,836 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2019 - 2023 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing some utility functions and the MicroPythonDevice base -class. -""" - -import contextlib -import copy -import importlib -import logging -import os - -from PyQt6.QtCore import QCoreApplication, QObject, pyqtSlot -from PyQt6.QtSerialPort import QSerialPortInfo -from PyQt6.QtWidgets import QInputDialog - -from eric7 import Preferences -from eric7.EricGui import EricPixmapCache -from eric7.EricWidgets import EricMessageBox -from eric7.EricWidgets.EricApplication import ericApp - -SupportedBoards = { - "esp": { - "ids": [ - (0x0403, 0x6001), # M5Stack ESP32 device"), - (0x0403, 0x6001), # FT232/FT245 (XinaBox CW01, CW02) - (0x0403, 0x6010), # FT2232C/D/L/HL/Q (ESP-WROVER-KIT) - (0x0403, 0x6011), # FT4232 - (0x0403, 0x6014), # FT232H - (0x0403, 0x6015), # Sparkfun ESP32 - (0x0403, 0x601C), # FT4222H - (0x10C4, 0xEA60), # CP210x - (0x1A86, 0x55D4), # CH343 - (0x1A86, 0x7523), # HL-340, CH340 - ], - "description": "ESP32, ESP8266", - "icon": "esp32Device", - "port_description": "", - }, - "circuitpython": { - "ids": [ - (0x0483, 0x572A), # STMicroelectronics NUCLEO-F446RE - CPy - (0x04D8, 0xE799), # Cytron Maker Zero SAMD21 - (0x04D8, 0xEA2A), # BHDynamics DynaLoRa_USB - (0x04D8, 0xEAD1), # BH Dynamics DynOSSAT-EDU-EPS-v1.0 - (0x04D8, 0xEAD2), # BH Dynamics DynOSSAT-EDU-OBC-v1.0 - (0x04D8, 0xEC44), # maholli PyCubed - (0x04D8, 0xEC63), # Kevin Neubauer CircuitBrains Basic - (0x04D8, 0xEC64), # Kevin Neubauer CircuitBrains Deluxe - (0x04D8, 0xEC72), # XinaBox CC03 - (0x04D8, 0xEC75), # XinaBox CS11 - (0x04D8, 0xED5F), # Itaca Innovation uChip CircuitPython - (0x04D8, 0xED94), # maholli kicksat-sprite - (0x04D8, 0xEDB3), # Capable Robot Programmable USB Hub - (0x04D8, 0xEDBE), # maholli SAM32 - (0x04D8, 0xEE8C), # J&J Studios LLC datum-Distance - (0x04D8, 0xEE8D), # J&J Studios LLC datum-IMU - (0x04D8, 0xEE8E), # J&J Studios LLC datum-Light - (0x04D8, 0xEE8F), # J&J Studios LLC datum-Weather - (0x04D8, 0xEF67), # senseBox MCU - (0x054C, 0x0BC2), # Sony Spresense - (0x1209, 0x2017), # Benjamin Shockley Mini SAM M4 - (0x1209, 0x3141), # CrumpSpace CrumpS2 - (0x1209, 0x3252), # Targett Module Clip w/Wroom - (0x1209, 0x3253), # Targett Module Clip w/Wrover - (0x1209, 0x4203), # 42. Keebs Frood - (0x1209, 0x4D43), # Robotics Masters Robo HAT MM1 M4 - (0x1209, 0x4DDD), # ODT CP Sapling - (0x1209, 0x4DDE), # ODT CP Sapling M0 w/ SPI Flash - (0x1209, 0x4DDF), # ODT CP Sapling Rev B - (0x1209, 0x4DF0), # Oak Dev Tech Pixelwing ESP32S2 - (0x1209, 0x4DF1), # Oak Dev Tech BREAD2040 - (0x1209, 0x4DF2), # Oak Dev Tech CAST AWAY RP2040 - (0x1209, 0x5A52), # ZRichard RP2.65-F - (0x1209, 0x5BF0), # Foosn Fomu - (0x1209, 0x7150), # Electronic Cats Hunter Cat NFC - (0x1209, 0x7382), # Invector Labs AB iLabs Challenger 840 - (0x1209, 0x805A), # Electronic Cats BastBLE - (0x1209, 0x8CAE), # takayoshiotake Octave RP2040 - (0x1209, 0xA182), # Solder Party RP2040 Stamp - (0x1209, 0xB182), # Solder Party BBQ20 Keyboard - (0x1209, 0xBAB0), # Electronic Cats Bast WiFi - (0x1209, 0xBAB1), # Electronic Cats Meow Meow - (0x1209, 0xBAB2), # Electronic Cats CatWAN USBStick - (0x1209, 0xBAB3), # Electronic Cats Bast Pro Mini M0 - (0x1209, 0xBAB6), # Electronic Cats Escornabot Makech - (0x1209, 0xBAB8), # Electronic Cats NFC Copy Cat - (0x1209, 0xC051), # Betrusted Simmel - (0x1209, 0xCB74), # 0xCB Helios - (0x1209, 0xD10D), # Diodes Delight Piunora - (0x1209, 0xD1B5), # Radomir Dopieralski PewPew LCD - (0x1209, 0xE3E3), # StackRduino M0 PRO - (0x1209, 0xEF00), # 2231puppy E-Fidget - (0x1209, 0xF123), # Electrolama minik - (0x1209, 0xF500), # Silicognition LLC M4-Shim - (0x1209, 0xF502), # Silicognition LLC RP2040-Shim - (0x16D0, 0x08C6), # Pimoroni Keybow 2040 - (0x16D0, 0x08C7), # Pimoroni Tiny 2040 (8MB) - (0x16D0, 0x08C8), # Pimoroni PicoSystem - (0x16D0, 0x10ED), # Mechwild PillBug - (0x1915, 0xB001), # Makerdiary Pitaya Go - (0x192F, 0xB1B2), # WarmBit BluePixel nRF52840 - (0x1B4F, 0x0015), # SparkFun RedBoard Turbo Board - (0x1B4F, 0x0016), # SparkFun SAMD51 Thing+ - (0x1B4F, 0x0017), # SparkFun LUMIDrive Board - (0x1B4F, 0x0020), # SparkFun MicroMod SAMD51 Processor - (0x1B4F, 0x0021), # SparkFun MicroMod nRF52840 Processor - (0x1B4F, 0x0024), # SparkFun MicroMod RP2040 Processor - (0x1B4F, 0x0025), # SparkFun Thing Plus RP2040 - (0x1B4F, 0x0026), # SparkFun Pro Micro RP2040 - (0x1B4F, 0x0027), # SparkFun STM32 MicroMod Processor - (0x1B4F, 0x0028), # SparkFun Thing Plus - STM32 - (0x1B4F, 0x002E), # PJRC/Sparkfun Teensy MicroMod - (0x1B4F, 0x5289), # SparkFun SFE_nRF52840_Mini - (0x1B4F, 0x8D22), # SparkFun SAMD21 Mini Breakout - (0x1B4F, 0x8D23), # SparkFun SAMD21 Dev Breakout - (0x1B4F, 0x8D24), # SparkFun Qwiic Micro - (0x1D50, 0x60E8), # Radomir Dopieralski PewPew M4 - (0x1D50, 0x6152), # nrf52.jpconstantineau.com BlueMicro833 - (0x1D50, 0x6153), # JPConstantineau PyKey18 - (0x1D50, 0x6153), # JPConstantineau PyKey44 - (0x1D50, 0x6153), # JPConstantineau PyKey60 - (0x1D50, 0x6153), # JPConstantineau PyKey87 - (0x1D50, 0x6154), # JPConstantineau EncoderPad RP2040 - (0x1D50, 0x6161), # nrf52.jpconstantineau.com BlueMicro840 - (0x2019, 0x7103), # Benjamin Shockley Fig Pi - (0x2341, 0x8053), # Arduino MKR1300 - (0x2341, 0x8057), # Arduino Nano 33 IoT - (0x2341, 0x805A), # Arduino Arduino_Nano_33_BLE - (0x2341, 0x824D), # Arduino Zero - (0x2786, 0x9207), # Switch Sc. BLE-SS dev board Multi Sensor - (0x2786, 0x920D), # Switch Sc. SSCI ISP1807 Dev Board - (0x2786, 0x920F), # Switch Sc. SSCI ISP1807 Micro Board - (0x2886, 0x002F), # Seeed Seeeduino XIAO - (0x2886, 0x0042), # Seeed Seeeduino XIAO RP2040 - (0x2886, 0x0045), # Seeed XIAO nRF52840 Sense - (0x2886, 0x802D), # Seeed Seeeduino Wio Terminal - (0x2886, 0x802F), # Seeed Seeeduino XIAO KB - (0x2886, 0xF001), # Makerdiary nRF52840 M.2 Developer Kit - (0x2886, 0xF002), # Makerdiary M60 Keyboard - (0x2B04, 0xC00C), # Particle Argon - (0x2B04, 0xC00D), # Particle Boron - (0x2B04, 0xC00E), # Particle Xenon - (0x2E8A, 0x1000), # Cytron Maker Pi RP2040 - (0x2E8A, 0x1002), # Pimoroni Pico LiPo (4MB) - (0x2E8A, 0x1003), # Pimoroni Pico LiPo (16MB) - (0x2E8A, 0x1005), # Melopero Shake RP2040 - (0x2E8A, 0x1006), # Invector Labs Challenger RP2040 WiFi - (0x2E8A, 0x1008), # Pimoroni PGA2040 - (0x2E8A, 0x1009), # Pimoroni Interstate 75 - (0x2E8A, 0x100A), # Pimoroni Plasma 2040 - (0x2E8A, 0x100B), # Invector Labs Challenger RP2040 LTE - (0x2E8A, 0x100D), # Invector Labs Challenger NB RP2040 WiFi - (0x2E8A, 0x100E), # Raspberry Pi Zero - (0x2E8A, 0x100F), # Cytron Maker Nano RP2040 - (0x2E8A, 0x1012), # Raspberry Pi Compute Module 4 IO Board - (0x2E8A, 0x1013), # Raspberry Pi 4B - (0x2E8A, 0x1014), # Raspberry Pi Compute Module 4 - (0x2E8A, 0x1015), # Raspberry Pi Zero 2W - (0x2E8A, 0x1016), # Pimoroni Tiny 2040 (2MB) - (0x2E8A, 0x1019), # Pimoroni Motor 2040 - (0x2E8A, 0x101A), # Pimoroni Servo 2040 - (0x2E8A, 0x101B), # Pimoroni Badger 2040 - (0x2E8A, 0x101E), # Raspberry Pi Zero W - (0x2E8A, 0x101F), # Waveshare Electronics RP2040-Zero - (0x2E8A, 0x1023), # Invector Labs Challenger RP2040 LoRa - (0x2E8A, 0x1026), # ELECFREAKS Pico:ed - (0x2E8A, 0x1027), # WIZnet W5100S-EVB-Pico - (0x2E8A, 0x1029), # WIZnet W5500-EVB-Pico - (0x2E8A, 0x102C), # Invector Labs Challenger RP2040 WiFi/BLE - (0x2E8A, 0x102D), # Invector Labs Challenger RP2040 SD/RTC - (0x2E8A, 0x102E), # VCC-GND Studio YD-RP2040 - (0x2E8A, 0x1032), # Invector Labs Challenger RP2040 SubGHz - (0x2E8A, 0x1039), # Waveshare Electronics Waveshare RP2040-LCD-1.28 - (0x2E8A, 0x1048), # nullbits Bit-C PRO - (0x303A, 0x7001), # Espressif ESP32-S2-HMI-DevKit-1 - (0x303A, 0x7003), # Espressif ESP32-S3-DevKitC-1 - (0x303A, 0x7003), # Espressif ESP32-S3-DevKitC-1-N32R8 - (0x303A, 0x7003), # Espressif ESP32-S3-DevKitC-1-N8 - (0x303A, 0x7003), # Espressif ESP32-S3-DevKitC-1-N8R2 - (0x303A, 0x7003), # Espressif ESP32-S3-DevKitC-1-N8R8 - (0x303A, 0x7003), # Espressif ESP32-S3-DevKitC-1-nopsram - (0x303A, 0x7005), # Espressif ESP32-S3-Box-2.5 - (0x303A, 0x7007), # Espressif ESP32-S3-DevKitM-1-N8 - (0x303A, 0x7009), # Espressif ESP32-S2-DevKitC-1-N4 - (0x303A, 0x7009), # Espressif ESP32-S2-DevKitC-1-N4R2 - (0x303A, 0x7009), # Espressif ESP32-S2-DevKitC-1-N8R2 - (0x303A, 0x700B), # Espressif ESP32-S3-USB-OTG-N8 - (0x303A, 0x700D), # Espressif ESP32-S3-Box-Lite - (0x303A, 0x700F), # Espressif ESP32-S3-EYE - (0x303A, 0x8002), # UnexpectedMaker TinyS2 - (0x303A, 0x8007), # LILYGO TTGO T8 ESP32-S2 - (0x303A, 0x800D), # Gravitech Cucumber RS - (0x303A, 0x80A1), # Gravitech Cucumber R - (0x303A, 0x80A4), # Gravitech Cucumber M - (0x303A, 0x80A7), # Gravitech Cucumber MS - (0x303A, 0x80AA), # Espressif Franzininho WIFI w/Wroom - (0x303A, 0x80AD), # Espressif Franzininho WIFI w/Wrover - (0x303A, 0x80AF), # Artisense Reference Design RD00 - (0x303A, 0x80B2), # Muselab nanoESP32-S2 w/Wrover - (0x303A, 0x80B5), # UnexpectedMaker FeatherS2 Neo - (0x303A, 0x80B7), # MORPHEANS MORPHESP-240 - (0x303A, 0x80C3), # Lolin S2 Mini - (0x303A, 0x80C6), # Lolin S2 Pico - (0x303A, 0x80D1), # UnexpectedMaker TinyS3 - (0x303A, 0x80D4), # UnexpectedMaker ProS3 - (0x303A, 0x80D7), # UnexpectedMaker FeatherS3 - (0x303A, 0x80D9), # FutureKeys HexKy_S2 - (0x303A, 0x80E0), # BananaPi BPI-Leaf-S3 - (0x303A, 0x80E6), # BananaPi BPI-Bit-S2 - (0x303A, 0x80E8), # HiiBot IoTs2 - (0x303A, 0x80EA), # LILYGO TTGO T8 ESP32-S2-WROOM - (0x303A, 0x80ED), # LILYGO TTGO T8 ESP32-S2 - (0x303A, 0x80F9), # Cytron Maker Feather AIoT S3 - (0x303A, 0x80FC), # Espressif MixGo CE - (0x303A, 0x80FD), # Espressif MixGo CE - (0x303A, 0x810A), # Waveshare Electronics ESP32-S2-Pico - (0x303A, 0x810C), # Waveshare Electronics ESP32-S2-Pico-LCD - (0x303A, 0x8111), # Smart Bee Designs Bee-S3 - (0x303A, 0x8114), # Smart Bee Designs Bee-Motion-S3 - (0x303A, 0x8117), # WEMOS LOLIN S3 16MB Flash 8MB PSRAM - (0x303A, 0x812C), # BananaPi BPI-PicoW-S3 - (0x30A4, 0x0002), # Blues Inc. Swan R5 - (0x3171, 0x0101), # 8086.net Commander - (0x31E2, 0x2001), # BDMICRO LLC VINA-D21 - (0x31E2, 0x2011), # BDMICRO LLC VINA-D51 - (0x31E2, 0x2021), # BDMICRO LLC VINA-D51 - (0x32BD, 0x3001), # Alorium Tech. AloriumTech Evo M51 - (0x4097, 0x0001), # TG-Boards Datalore IP M4 - (0x612B, 0x80A7), # Ai-Thinker ESP 12k NodeMCU - (0x239A, None), # Any Adafruit Boards - ], - "description": "CircuitPython", - "icon": "circuitPythonDevice", - "port_description": "", - }, - "bbc_microbit": { - "ids": [ - (0x0D28, 0x0204), # micro:bit - ], - "description": "BBC micro:bit", - "icon": "microbitDevice", - "port_description": "BBC micro:bit CMSIS-DAP", - }, - "calliope": { - "ids": [ - (0x0D28, 0x0204), # Calliope mini - ], - "description": "Calliope mini", - "icon": "calliope_mini", - "port_description": "DAPLink CMSIS-DAP", - }, - "pyboard": { - "ids": [ - (0xF055, 0x9800), # Pyboard in CDC mode - (0xF055, 0x9801), # Pyboard in CDC+HID mode - (0xF055, 0x9802), # Pyboard in CDC+MSC mode - ], - "description": "PyBoard", - "icon": "micropython48", - "port_description": "Pyboard", - }, - "rp2040": { - "ids": [ - (0x2E8A, 0x0005), # Raspberry Pi Pico - ], - "description": QCoreApplication.translate("MicroPythonDevice", "RP2040 based"), - "icon": "rp2040Device", - "port_description": "", - }, - "teensy": { - "ids": [ - (0xF055, 0x9802), # Pyboard in CDC+MSC mode - ], - "description": "Teensy", - "icon": "micropython48", - "port_description": "Teensy", - }, - "generic": { - # only manually configured devices use this - "ids": [], - "description": QCoreApplication.translate("MicroPythonDevice", "Generic Board"), - "icon": "micropython48", - "port_description": "", - }, -} - -IgnoredBoards = ( - (0x8086, 0x9C3D), - (0x8086, None), -) - -FirmwareGithubUrls = { - "micropython": "https://github.com/micropython/micropython/releases/latest", - "circuitpython": "https://github.com/adafruit/circuitpython/releases/latest", - "pimoroni_pico": "https://github.com/pimoroni/pimoroni-pico/releases/latest", - "microbit_v1": "https://github.com/bbcmicrobit/micropython/releases/latest", - "microbit_v2": ( - "https://github.com/microbit-foundation/micropython-microbit-v2/releases/latest" - ), -} - - -def getSupportedDevices(): - """ - Function to get a list of supported MicroPython devices. - - @return set of tuples with the board type and description - @rtype set of tuples of (str, str) - """ - boards = [] - for board in SupportedBoards: - boards.append((board, SupportedBoards[board]["description"])) - return boards - - -def getFoundDevices(): - """ - Function to check the serial ports for supported MicroPython devices. - - @return tuple containing a list of tuples with the board type, the port - description, a description, the serial port it is connected at, the - VID and PID for known device types, a list of tuples with VID, PID - and description for unknown devices and a list of tuples with VID, - PID, description and port name for ports with missing VID or PID - @rtype tuple of (list of tuples of (str, str, str, str, int, int), - list of tuples of (int, int, str), - list of tuples of (int, int, str, str) - """ - foundDevices = [] - unknownDevices = [] - unknownPorts = [] - - manualDevices = {} - for deviceDict in Preferences.getMicroPython("ManualDevices"): - manualDevices[(deviceDict["vid"], deviceDict["pid"])] = deviceDict - - availablePorts = QSerialPortInfo.availablePorts() - for port in availablePorts: - if port.hasVendorIdentifier() and port.hasProductIdentifier(): - supported = False - vid = port.vendorIdentifier() - pid = port.productIdentifier() - - for board in SupportedBoards: - if (vid, pid) in SupportedBoards[board]["ids"] or ( - vid, - None, - ) in SupportedBoards[board]["ids"]: - if board in ("bbc_microbit", "calliope") and ( - port.description().strip() - != SupportedBoards[board]["port_description"] - ): - # both boards have the same VID and PID - # try to differentiate based on port description - continue - elif board in ("pyboard", "teensy") and ( - not port.description().startswith( - SupportedBoards[board]["port_description"] - ) - ): - # both boards have the same VID and PID - # try to differentiate based on port description - continue - foundDevices.append( - ( - board, - port.description(), - SupportedBoards[board]["description"], - port.portName(), - vid, - pid, - port.serialNumber(), - ) - ) - supported = True - if not supported and (vid, pid) in manualDevices: - # check the locally added ones next - board = manualDevices[(vid, pid)]["type"] - foundDevices.append( - ( - board, - port.description(), - SupportedBoards[board]["description"], - port.portName(), - vid, - pid, - port.serialNumber(), - ) - ) - supported = True - if not supported: - if vid and pid: - if (vid, pid) not in IgnoredBoards and ( - vid, - None, - ) not in IgnoredBoards: - unknownDevices.append((vid, pid, port.description())) - logging.debug( - "Unknown device: (0x%04x:0x%04x %s)", - vid, - pid, - port.description(), - ) - else: - # either VID or PID or both not detected - desc = port.description() - if not desc: - desc = QCoreApplication.translate( - "MicroPythonDevice", "Unknown Device" - ) - unknownPorts.append((vid, pid, desc, port.portName())) - - elif bool(port.portName()) and Preferences.getMicroPython( - "EnableManualDeviceSelection" - ): - # no VID and/or PID available (e.g. in Linux container of ChromeOS) - desc = port.description() - if not desc: - desc = QCoreApplication.translate("MicroPythonDevice", "Unknown Device") - unknownPorts.append((0, 0, desc, port.portName())) - - return foundDevices, unknownDevices, unknownPorts - - -def getDeviceIcon(boardName, iconFormat=True): - """ - Function to get the icon for the given board. - - @param boardName name of the board - @type str - @param iconFormat flag indicating to get an icon or a pixmap - @type bool - @return icon for the board (iconFormat == True) or - a pixmap (iconFormat == False) - @rtype QIcon or QPixmap - """ - iconName = ( - SupportedBoards[boardName]["icon"] - if boardName in SupportedBoards - else - # return a generic MicroPython icon - "micropython48" - ) - - if iconFormat: - return EricPixmapCache.getIcon(iconName) - else: - return EricPixmapCache.getPixmap(iconName) - - -def getDevice(deviceType, microPythonWidget, vid, pid, boardName="", serialNumber=""): - """ - Public method to instantiate a specific MicroPython device interface. - - @param deviceType type of the device interface - @type str - @param microPythonWidget reference to the main MicroPython widget - @type MicroPythonWidget - @param vid vendor ID (only used for deviceType 'generic') - @type int - @param pid product ID (only used for deviceType 'generic') - @type int - @param boardName name of the board (defaults to "") - @type str (optional) - @param serialNumber serial number of the board (defaults to "") - @type str (optional) - @return instantiated device interface - @rtype MicroPythonDevice - """ - deviceMapping = { - "bbc_microbit": ".MicrobitDevices", - "calliope": ".MicrobitDevices", - "circuitpython": ".CircuitPythonDevices", - "esp": ".EspDevices", - "generic": ".GenericMicroPythonDevices", - "pyboard": ".PyBoardDevices", - "rp2040": ".RP2040Devices", - "teensy": ".TeensyDevices", - } - - with contextlib.suppress(KeyError): - mod = importlib.import_module(deviceMapping[deviceType], __package__) - if mod: - return mod.createDevice( - microPythonWidget, deviceType, vid, pid, boardName, serialNumber - ) - - # nothing specific requested or specific one failed or is not supported yet - return MicroPythonDevice(microPythonWidget, deviceType) - - -class MicroPythonDevice(QObject): - """ - Base class for the more specific MicroPython devices. - """ - - def __init__(self, microPythonWidget, deviceType, parent=None): - """ - Constructor - - @param microPythonWidget reference to the main MicroPython widget - @type MicroPythonWidget - @param deviceType device type assigned to this device interface - @type str - @param parent reference to the parent object - @type QObject - """ - super().__init__(parent) - - self._deviceType = deviceType - self.microPython = microPythonWidget - self._deviceData = {} # dictionary with essential device data - - def setConnected(self, connected): - """ - Public method to set the connection state. - - Note: This method can be overwritten to perform actions upon connect - or disconnect of the device. - - @param connected connection state - @type bool - """ - self._deviceData = {} - - if connected: - with contextlib.suppress(OSError): - self._deviceData = self.microPython.commandsInterface().getDeviceData() - - def getDeviceType(self): - """ - Public method to get the device type. - - @return type of the device - @rtype str - """ - return self._deviceType - - def getDeviceData(self): - """ - Public method to get a copy of the determined device data. - - @return dictionary containing the essential device data - @rtype dict - """ - return copy.deepcopy(self._deviceData) - - def checkDeviceData(self): - """ - Public method to check the validity of the device data determined during - connecting the device. - - @return flag indicating valid device data - @rtype bool - """ - if bool(self._deviceData): - return True - else: - EricMessageBox.critical( - None, - self.tr("Show MicroPython Versions"), - self.tr( - """<p>The device data is not available. Try to connect to the""" - """ device again. Aborting...</p>""" - ).format(self.getDeviceType()), - ) - return False - - def setButtons(self): - """ - Public method to enable the supported action buttons. - """ - self.microPython.setActionButtons( - open=False, save=False, run=False, repl=False, files=False, chart=False - ) - - def forceInterrupt(self): - """ - Public method to determine the need for an interrupt when opening the - serial connection. - - @return flag indicating an interrupt is needed - @rtype bool - """ - return True - - def deviceName(self): - """ - Public method to get the name of the device. - - @return name of the device - @rtype str - """ - return self.tr("Unsupported Device") - - def canStartRepl(self): - """ - Public method to determine, if a REPL can be started. - - @return tuple containing a flag indicating it is safe to start a REPL - and a reason why it cannot. - @rtype tuple of (bool, str) - """ - return False, self.tr("REPL is not supported by this device.") - - def setRepl(self, on): - """ - Public method to set the REPL status and dependent status. - - @param on flag indicating the active status - @type bool - """ - pass - - def canStartPlotter(self): - """ - Public method to determine, if a Plotter can be started. - - @return tuple containing a flag indicating it is safe to start a - Plotter and a reason why it cannot. - @rtype tuple of (bool, str) - """ - return False, self.tr("Plotter is not supported by this device.") - - def setPlotter(self, on): - """ - Public method to set the Plotter status and dependent status. - - @param on flag indicating the active status - @type bool - """ - pass - - def canRunScript(self): - """ - Public method to determine, if a script can be executed. - - @return tuple containing a flag indicating it is safe to start a - Plotter and a reason why it cannot. - @rtype tuple of (bool, str) - """ - return False, self.tr("Running scripts is not supported by this device.") - - def runScript(self, script): - """ - Public method to run the given Python script. - - @param script script to be executed - @type str - """ - pass - - def canStartFileManager(self): - """ - Public method to determine, if a File Manager can be started. - - @return tuple containing a flag indicating it is safe to start a - File Manager and a reason why it cannot. - @rtype tuple of (bool, str) - """ - return False, self.tr("File Manager is not supported by this device.") - - def setFileManager(self, on): - """ - Public method to set the File Manager status and dependent status. - - @param on flag indicating the active status - @type bool - """ - pass - - def supportsLocalFileAccess(self): - """ - Public method to indicate file access via a local directory. - - @return flag indicating file access via local directory - @rtype bool - """ - return False # default - - def getWorkspace(self): - """ - Public method to get the workspace directory. - - @return workspace directory used for saving files - @rtype str - """ - return ( - Preferences.getMicroPython("MpyWorkspace") - or Preferences.getMultiProject("Workspace") - or os.path.expanduser("~") - ) - - def selectDeviceDirectory(self, deviceDirectories): - """ - Public method to select the device directory from a list of detected - ones. - - @param deviceDirectories list of directories to select from - @type list of str - @return selected directory or an empty string - @rtype str - """ - deviceDirectory, ok = QInputDialog.getItem( - None, - self.tr("Select Device Directory"), - self.tr("Select the directory for the connected device:"), - [""] + deviceDirectories, - 0, - False, - ) - if ok: - return deviceDirectory - else: - # user cancelled - return "" - - def sendCommands(self, commandsList): - """ - Public method to send a list of commands to the device. - - @param commandsList list of commands to be sent to the device - @type list of str - """ - rawOn = [ # sequence of commands to enter raw mode - b"\x02", # Ctrl-B: exit raw repl (just in case) - b"\r\x03\x03\x03", # Ctrl-C three times: interrupt any running - # program - b"\r\x01", # Ctrl-A: enter raw REPL - ] - newLine = [ - b'print("\\n")\r', - ] - commands = [c.encode("utf-8)") + b"\r" for c in commandsList] - commands.append(b"\r") - commands.append(b"\x04") - rawOff = [b"\x02", b"\x02"] - commandSequence = rawOn + newLine + commands + rawOff - self.microPython.commandsInterface().executeAsync(commandSequence) - - @pyqtSlot() - def handleDataFlood(self): - """ - Public slot handling a data floof from the device. - """ - pass - - def addDeviceMenuEntries(self, menu): - """ - Public method to add device specific entries to the given menu. - - @param menu reference to the context menu - @type QMenu - """ - pass - - def hasFlashMenuEntry(self): - """ - Public method to check, if the device has its own flash menu entry. - - @return flag indicating a specific flash menu entry - @rtype bool - """ - return False - - def hasTimeCommands(self): - """ - Public method to check, if the device supports time commands. - - The default returns True. - - @return flag indicating support for time commands - @rtype bool - """ - return True - - def hasDocumentationUrl(self): - """ - Public method to check, if the device has a configured documentation - URL. - - @return flag indicating a configured documentation URL - @rtype bool - """ - return bool(self.getDocumentationUrl()) - - def getDocumentationUrl(self): - """ - Public method to get the device documentation URL. - - @return documentation URL of the device - @rtype str - """ - return "" - - def hasFirmwareUrl(self): - """ - Public method to check, if the device has a configured firmware - download URL. - - @return flag indicating a configured firmware download URL - @rtype bool - """ - return bool(self.getFirmwareUrl()) - - def getFirmwareUrl(self): - """ - Public method to get the device firmware download URL. - - @return firmware download URL of the device - @rtype str - """ - return "" - - def downloadFirmware(self): - """ - Public method to download the device firmware. - """ - url = self.getFirmwareUrl() - if url: - ericApp().getObject("UserInterface").launchHelpViewer(url) - - def getDownloadMenuEntries(self): - """ - Public method to retrieve the entries for the downloads menu. - - @return list of tuples with menu text and URL to be opened for each - entry - @rtype list of tuple of (str, str) - """ - return []