diff --git a/scripts/microupload.py b/scripts/microupload.py index 0ee90bd..4f5594a 100644 --- a/scripts/microupload.py +++ b/scripts/microupload.py @@ -20,7 +20,8 @@ Options: -X --exclude=PATH Path to exclude, may be repeated. - -C --chdir=PATH Change current directory to path. + -C --chdir=PATH Change current directory to . + -D --delay=DELAY Wait for DELAY seconds before trying to upload files. -v --verbose Verbose output. """ @@ -46,6 +47,11 @@ def main(args: List[str]) -> None: opts = docopt(__doc__, argv=args) verbose = opts['--verbose'] root = opts['PATH'] + try: + delay = float(opts.get('--delay', 0.5)) + except ValueError: + delay = 0.5 + print("Got incorrect 'delay' value, defaulting to 0.5 seconds.", file=sys.stderr) chdir = opts['--chdir'] if chdir: @@ -57,7 +63,8 @@ def main(args: List[str]) -> None: files = Files(board) rel_root = os.path.relpath(root, os.getcwd()) - wait_for_board() + print('Waiting {} seconds before connecting to board...'.format(delay), file=sys.stderr) + wait_for_board(delay) if os.path.isdir(root): to_upload = [os.path.join(rel_root, x) @@ -116,9 +123,9 @@ def list_files(path: str, excluded: List[str]) -> Iterable[str]: yield os.path.relpath(os.path.join(root, f), path) -def wait_for_board() -> None: +def wait_for_board(delay: float = 0.5) -> None: """Wait for some ESP8266 devices to become ready for REPL commands.""" - time.sleep(0.5) + time.sleep(delay) def progress(msg: str, xs: Sequence[T]) -> Iterable[T]: diff --git a/src/main/kotlin/com/jetbrains/micropython/run/MicroUpload.kt b/src/main/kotlin/com/jetbrains/micropython/run/MicroUpload.kt index 8edeffe..ab13211 100644 --- a/src/main/kotlin/com/jetbrains/micropython/run/MicroUpload.kt +++ b/src/main/kotlin/com/jetbrains/micropython/run/MicroUpload.kt @@ -26,9 +26,11 @@ fun getMicroUploadCommand(path: String, module: Module): List? { .map { listOf("-X", it) } .flatten() .toList() - return listOf(pythonPath, "${MicroPythonFacet.scriptsPath}/microupload.py", "-C", rootDir.path) + - excludes + - listOf("-v", devicePath, path) + return listOf( + pythonPath, "${MicroPythonFacet.scriptsPath}/microupload.py", + "-C", rootDir.path, + "-D", facet.boardConnectionDelay.toString() + ) + excludes + listOf("-v", devicePath, path) } private fun getClosestRoot(file: VirtualFile, module: Module): VirtualFile? { diff --git a/src/main/kotlin/com/jetbrains/micropython/settings/MicroPythonDevicesConfiguration.kt b/src/main/kotlin/com/jetbrains/micropython/settings/MicroPythonDevicesConfiguration.kt index 602155d..32c4c67 100644 --- a/src/main/kotlin/com/jetbrains/micropython/settings/MicroPythonDevicesConfiguration.kt +++ b/src/main/kotlin/com/jetbrains/micropython/settings/MicroPythonDevicesConfiguration.kt @@ -21,6 +21,8 @@ class MicroPythonDevicesConfiguration : PersistentStateComponent, *>, module: Module, na MicroPythonDevicesConfiguration.getInstance(module.project).autoDetectDevicePath = value } + var boardConnectionDelay: Float + get() = MicroPythonDevicesConfiguration.getInstance(module.project).boardConnectionDelay + set(value) { + MicroPythonDevicesConfiguration.getInstance(module.project).boardConnectionDelay = value + } + fun getOrDetectDevicePathSynchronously(): String? = if (autoDetectDevicePath) detectDevicePathSynchronously(configuration.deviceProvider) diff --git a/src/main/kotlin/com/jetbrains/micropython/settings/MicroPythonSettingsPanel.kt b/src/main/kotlin/com/jetbrains/micropython/settings/MicroPythonSettingsPanel.kt index 439df0e..290ddb1 100644 --- a/src/main/kotlin/com/jetbrains/micropython/settings/MicroPythonSettingsPanel.kt +++ b/src/main/kotlin/com/jetbrains/micropython/settings/MicroPythonSettingsPanel.kt @@ -29,9 +29,7 @@ import com.intellij.util.ui.SwingHelper import com.intellij.util.ui.UIUtil import com.jetbrains.micropython.devices.MicroPythonDeviceProvider import java.awt.BorderLayout -import javax.swing.JButton -import javax.swing.JList -import javax.swing.JPanel +import javax.swing.* /** * @author vlan @@ -40,6 +38,9 @@ class MicroPythonSettingsPanel(private val module: Module) : JPanel() { private val deviceTypeCombo = ComboBox(MicroPythonDeviceProvider.providers.toTypedArray()) private val docsHyperlink = SwingHelper.createWebHyperlink("") private val devicePath = TextFieldWithBrowseButton() + + private val connectionDelayModel = SpinnerNumberModel(0.5F, 0.0F, 599.9F, 0.1F) + private val boardConnectionDelaySpinner = JSpinner(connectionDelayModel) private val autoDetectDevicePath = CheckBox("Auto-detect device path").apply { addActionListener { update() @@ -48,15 +49,15 @@ class MicroPythonSettingsPanel(private val module: Module) : JPanel() { private val devicePathPanel: JPanel by lazy { FormBuilder.createFormBuilder() - .addLabeledComponent("Device path:", JPanel(BorderLayout()).apply { - add(devicePath, BorderLayout.CENTER) - add(JButton("Detect").apply { - addActionListener { - devicePath.text = module.microPythonFacet?.detectDevicePathSynchronously(selectedProvider) ?: "" - } - }, BorderLayout.EAST) - }) - .panel + .addLabeledComponent("Device path:", JPanel(BorderLayout()).apply { + add(devicePath, BorderLayout.CENTER) + add(JButton("Detect").apply { + addActionListener { + devicePath.text = module.microPythonFacet?.detectDevicePathSynchronously(selectedProvider) ?: "" + } + }, BorderLayout.EAST) + }) + .panel } init { @@ -64,18 +65,21 @@ class MicroPythonSettingsPanel(private val module: Module) : JPanel() { border = IdeBorderFactory.createEmptyBorder(UIUtil.PANEL_SMALL_INSETS) val contentPanel = FormBuilder.createFormBuilder() - .addLabeledComponent("Device type:", deviceTypeCombo) - .addComponent(autoDetectDevicePath) - .addComponent(devicePathPanel) - .addComponent(docsHyperlink) - .panel + .addLabeledComponent("Device type:", deviceTypeCombo) + .addComponent(autoDetectDevicePath) + .addComponent(devicePathPanel) + .addLabeledComponent("Board detection delay (in seconds):", boardConnectionDelaySpinner) + .addComponent(docsHyperlink) + .panel add(contentPanel, BorderLayout.NORTH) deviceTypeCombo.apply { - renderer = object: SimpleListCellRenderer() { - override fun customize(list: JList, value: MicroPythonDeviceProvider?, - index: Int, selected: Boolean, hasFocus: Boolean) { + renderer = object : SimpleListCellRenderer() { + override fun customize( + list: JList, value: MicroPythonDeviceProvider?, + index: Int, selected: Boolean, hasFocus: Boolean + ) { text = value?.presentableName ?: return } } @@ -97,9 +101,10 @@ class MicroPythonSettingsPanel(private val module: Module) : JPanel() { } fun isModified(configuration: MicroPythonFacetConfiguration, facet: MicroPythonFacet): Boolean = - deviceTypeCombo.selectedItem != configuration.deviceProvider - || devicePath.text.nullize(true) != facet.devicePath - || autoDetectDevicePath.isSelected != facet.autoDetectDevicePath + deviceTypeCombo.selectedItem != configuration.deviceProvider + || devicePath.text.nullize(true) != facet.devicePath + || autoDetectDevicePath.isSelected != facet.autoDetectDevicePath + || boardConnectionDelaySpinner.value != facet.boardConnectionDelay fun getDisplayName(): String = "MicroPython" @@ -107,12 +112,14 @@ class MicroPythonSettingsPanel(private val module: Module) : JPanel() { configuration.deviceProvider = selectedProvider facet.devicePath = devicePath.text.nullize(true) facet.autoDetectDevicePath = autoDetectDevicePath.isSelected + facet.boardConnectionDelay = boardConnectionDelaySpinner.value as Float } fun reset(configuration: MicroPythonFacetConfiguration, facet: MicroPythonFacet) { deviceTypeCombo.selectedItem = configuration.deviceProvider devicePath.text = facet.devicePath ?: "" autoDetectDevicePath.isSelected = facet.autoDetectDevicePath + boardConnectionDelaySpinner.value = facet.boardConnectionDelay update() }