mirror of
https://github.com/pybricks/pybricks-api.git
synced 2026-09-13 01:56:55 +00:00
Compare commits
24
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37cdd2a83b | ||
|
|
a2d9c33eb5 | ||
|
|
6d0de1effa | ||
|
|
8e7fc53974 | ||
|
|
e456c8ef91 | ||
|
|
6500440031 | ||
|
|
8ec1b18629 | ||
|
|
26908040eb | ||
|
|
f67c98105a | ||
|
|
877391dea7 | ||
|
|
fb3446ad0d | ||
|
|
31256d70c1 | ||
|
|
f87e1b48ac | ||
|
|
6bcf6117c3 | ||
|
|
c77682f50d | ||
|
|
4c583a9d4e | ||
|
|
0688b8dded | ||
|
|
d1a4327751 | ||
|
|
4aec24a051 | ||
|
|
7bc995d0b6 | ||
|
|
725a07e6e1 | ||
|
|
d43bf94720 | ||
|
|
c6163fcc81 | ||
|
|
34992d5b20 |
@@ -0,0 +1,33 @@
|
||||
name: pybricks_jedi
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
if: github.ref_type != 'tag'
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.10"
|
||||
- run: pipx install poetry
|
||||
- run: poetry install
|
||||
working-directory: ./jedi
|
||||
- run: poetry run pytest -vv
|
||||
working-directory: ./jedi
|
||||
|
||||
publish:
|
||||
if: github.ref_type == 'tag' && startsWith(github.ref_name, 'pybricks_jedi/')
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.10"
|
||||
- run: pipx install poetry
|
||||
- run: poetry install
|
||||
- run: poetry build
|
||||
- run: poetry publish
|
||||
env:
|
||||
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_PYBRICKS_JEDI_TOKEN }}
|
||||
+2
-1
@@ -26,8 +26,9 @@ build/
|
||||
build-*/
|
||||
_build/
|
||||
|
||||
# Test failure outputs
|
||||
# Tests
|
||||
######################
|
||||
.pytest_cache/
|
||||
tests/*.exp
|
||||
tests/*.out
|
||||
|
||||
|
||||
Vendored
+9
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"python.pythonPath": "${workspaceFolder}/.venv",
|
||||
"python.autoComplete.extraPaths": ["jedi/src"],
|
||||
"python.formatting.provider": "black",
|
||||
"python.linting.pylintEnabled": false,
|
||||
"python.linting.flake8Enabled": true,
|
||||
@@ -10,6 +10,11 @@
|
||||
"editor.defaultFormatter": "ms-python.python"
|
||||
},
|
||||
"python.languageServer": "Pylance",
|
||||
"python.testing.pytestArgs": [
|
||||
"jedi/tests"
|
||||
],
|
||||
"python.testing.unittestEnabled": false,
|
||||
"python.testing.pytestEnabled": true,
|
||||
"files.associations": {"*.inc": "restructuredtext"},
|
||||
"restructuredtext.confPath": "${workspaceFolder}/doc/main",
|
||||
"spellright.language": [
|
||||
@@ -41,4 +46,7 @@
|
||||
"restructuredtext",
|
||||
],
|
||||
"rewrap.wrappingColumn": 78,
|
||||
"python.analysis.extraPaths": [
|
||||
"jedi/src"
|
||||
],
|
||||
}
|
||||
|
||||
@@ -2,6 +2,17 @@
|
||||
|
||||
<!-- refer to https://keepachangelog.com/en/1.0.0/ for guidance -->
|
||||
|
||||
## 3.2.0b1-r2 - 2022-06-24
|
||||
|
||||
### Changed
|
||||
- Moved remaining type hints from `.pyi` files to the python stub modules, and
|
||||
fixed numerous errors in the type hints throughout.
|
||||
|
||||
## 3.2.0b1-r1 - 2022-06-09
|
||||
|
||||
## Added
|
||||
- Added `__init__.py` to `pybricks` package.
|
||||
|
||||
## 3.2.0b1 - 2022-06-02
|
||||
|
||||
### Added
|
||||
|
||||
+2
-5
@@ -8,13 +8,10 @@ SPHINXPROJ = Pybricks
|
||||
SOURCEDIR = main
|
||||
BUILDDIR = "$(SOURCEDIR)"/build
|
||||
TAG = main
|
||||
ifeq ($(BETA),1)
|
||||
BETATAG = "-tbeta"
|
||||
endif
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(TAG) $(BETATAG) $(O)
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(TAG) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
@@ -25,4 +22,4 @@ diagrams:
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) -t $(TAG) $(BETATAG) $(O)
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) -t $(TAG) $(O)
|
||||
|
||||
+17
-1
@@ -27,6 +27,9 @@ from docutils import nodes
|
||||
from docutils.parsers.rst.directives import flag
|
||||
from docutils.parsers.rst import Directive
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.addnodes import pending_xref
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.util.nodes import make_refnode
|
||||
import toml
|
||||
|
||||
TOP_DIR = os.path.abspath(os.path.join("..", ".."))
|
||||
@@ -307,7 +310,16 @@ class AvailabilityDirective(Directive):
|
||||
]
|
||||
|
||||
|
||||
def on_missing_reference(app, env, node, contnode):
|
||||
def on_missing_reference(
|
||||
app: Sphinx, env: BuildEnvironment, node: pending_xref, contnode: nodes.Element
|
||||
) -> nodes.Element:
|
||||
# The Number type alias is on the Signals and Units page instead of on the
|
||||
# pybricks.parameters page so normal resolution doesn't work
|
||||
if node["reftype"] == "class" and node["reftarget"] == "Number":
|
||||
return make_refnode(
|
||||
app.builder, node["refdoc"], "signaltypes", "numbers", contnode
|
||||
)
|
||||
|
||||
# References with special characters can't exist, so we have to supress
|
||||
# warnings when Sphinx tries to cross reference units like deg/s. For
|
||||
# consistency, we also treat units without special characters this way.
|
||||
@@ -324,6 +336,10 @@ def on_missing_reference(app, env, node, contnode):
|
||||
"ms",
|
||||
"mNm",
|
||||
"Hz",
|
||||
"°C",
|
||||
"J",
|
||||
"Ω",
|
||||
"N",
|
||||
]:
|
||||
|
||||
# If they match on raw source, we are dealing with argument types.
|
||||
|
||||
+2
-3
@@ -25,9 +25,8 @@ latex_logo = "../common/images/pybricks-logo-large.png"
|
||||
if os.environ.get("READTHEDOCS", None) == "True":
|
||||
tags.add("main") # noqa F821
|
||||
|
||||
# On https://docs.pybricks.com/en/latest/, show features tagged as beta.
|
||||
if os.environ.get("READTHEDOCS_VERSION_NAME", None) == "latest":
|
||||
tags.add("beta") # noqa F821
|
||||
# HACK: this allows Number type alias to be imported by Sphinx
|
||||
os.environ["SPHINX_BUILD"] = "True"
|
||||
|
||||
# Addtional configuration of the IDE docs
|
||||
if "ide" in tags.tags: # noqa F821
|
||||
|
||||
+149
-155
@@ -6,256 +6,250 @@ Prime Hub / Inventor Hub
|
||||
.. figure:: ../../main/images/primeinventorhub.png
|
||||
:height: 15 em
|
||||
|
||||
.. only:: not beta
|
||||
|
||||
.. note:: Pybricks support for these hubs is currently in development.
|
||||
Please check back later!
|
||||
.. note:: Pybricks support for these hubs is in beta.
|
||||
Check the `installation instructions`_ to try it out.
|
||||
The following functions may change before the final release.
|
||||
|
||||
.. only:: beta
|
||||
.. class:: InventorHub
|
||||
|
||||
.. note:: Pybricks support for these hubs is in beta.
|
||||
Check the `installation instructions`_ to try it out.
|
||||
The following functions may change before the final release.
|
||||
This class is the same as the ``PrimeHub`` class, shown below. Both classes
|
||||
work on both hubs.
|
||||
|
||||
.. class:: InventorHub
|
||||
These hubs are completely identical. They use the same Pybricks firmware.
|
||||
|
||||
This class is the same as the ``PrimeHub`` class, shown below. Both classes
|
||||
work on both hubs.
|
||||
.. autoclass:: pybricks.hubs.PrimeHub
|
||||
:no-members:
|
||||
|
||||
These hubs are completely identical. They use the same Pybricks firmware.
|
||||
.. rubric:: Using the hub status light
|
||||
|
||||
.. autoclass:: pybricks.hubs.PrimeHub
|
||||
:no-members:
|
||||
.. figure:: ../../main/images/primehub_light_label.png
|
||||
:width: 22 em
|
||||
|
||||
.. rubric:: Using the hub status light
|
||||
.. automethod:: pybricks.hubs::PrimeHub.light.on
|
||||
|
||||
.. figure:: ../../main/images/primehub_light_label.png
|
||||
:width: 22 em
|
||||
.. automethod:: pybricks.hubs::PrimeHub.light.off
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.light.on
|
||||
.. automethod:: pybricks.hubs::PrimeHub.light.blink
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.light.off
|
||||
.. automethod:: pybricks.hubs::PrimeHub.light.animate
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.light.blink
|
||||
.. rubric:: Using the light matrix display
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.light.animate
|
||||
.. figure:: ../../main/images/primehub_display_label.png
|
||||
:width: 22 em
|
||||
|
||||
.. rubric:: Using the light matrix display
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.orientation
|
||||
|
||||
.. figure:: ../../main/images/primehub_display_label.png
|
||||
:width: 22 em
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.off
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.orientation
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.pixel
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.off
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.image
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.pixel
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.animate
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.image
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.number
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.animate
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.char
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.number
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.text
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.char
|
||||
.. rubric:: Using the buttons
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.display.text
|
||||
.. figure:: ../../main/images/primehub_buttons_label.png
|
||||
:width: 22 em
|
||||
|
||||
.. rubric:: Using the buttons
|
||||
.. automethod:: pybricks.hubs::PrimeHub.buttons.pressed
|
||||
|
||||
.. figure:: ../../main/images/primehub_buttons_label.png
|
||||
:width: 22 em
|
||||
.. rubric:: Using the IMU
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.buttons.pressed
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.up
|
||||
|
||||
.. rubric:: Using the IMU
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.tilt
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.up
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.acceleration
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.tilt
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.angular_velocity
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.acceleration
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.heading
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.angular_velocity
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.reset_heading
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.heading
|
||||
.. rubric:: Using the speaker
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.imu.reset_heading
|
||||
.. automethod:: pybricks.hubs::PrimeHub.speaker.volume
|
||||
|
||||
.. rubric:: Using the speaker
|
||||
.. automethod:: pybricks.hubs::PrimeHub.speaker.beep
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.speaker.volume
|
||||
.. automethod:: pybricks.hubs::PrimeHub.speaker.play_notes
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.speaker.beep
|
||||
.. rubric:: Using the battery
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.speaker.play_notes
|
||||
.. automethod:: pybricks.hubs::PrimeHub.battery.voltage
|
||||
|
||||
.. rubric:: Using the battery
|
||||
.. automethod:: pybricks.hubs::PrimeHub.battery.current
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.battery.voltage
|
||||
.. rubric:: Getting the charger status
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.battery.current
|
||||
.. automethod:: pybricks.hubs::PrimeHub.charger.connected
|
||||
|
||||
.. rubric:: Getting the charger status
|
||||
.. automethod:: pybricks.hubs::PrimeHub.charger.current
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.charger.connected
|
||||
.. automethod:: pybricks.hubs::PrimeHub.charger.status
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.charger.current
|
||||
.. rubric:: System control
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.charger.status
|
||||
.. automethod:: pybricks.hubs::PrimeHub.system.set_stop_button
|
||||
|
||||
.. rubric:: System control
|
||||
.. automethod:: pybricks.hubs::PrimeHub.system.name
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.system.set_stop_button
|
||||
.. automethod:: pybricks.hubs::PrimeHub.system.shutdown
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.system.name
|
||||
.. automethod:: pybricks.hubs::PrimeHub.system.reset_reason
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.system.shutdown
|
||||
.. note:: The examples below use the ``PrimeHub`` class. The examples work fine
|
||||
on both hubs because they are the identical. If you prefer, you can
|
||||
change this to ``InventorHub``.
|
||||
|
||||
.. automethod:: pybricks.hubs::PrimeHub.system.reset_reason
|
||||
Status light examples
|
||||
---------------------
|
||||
|
||||
.. note:: The examples below use the ``PrimeHub`` class. The examples work fine
|
||||
on both hubs because they are the identical. If you prefer, you can
|
||||
change this to ``InventorHub``.
|
||||
Turning the light on and off
|
||||
****************************
|
||||
|
||||
Status light examples
|
||||
---------------------
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/light_off.py
|
||||
|
||||
Turning the light on and off
|
||||
****************************
|
||||
Changing brightness and using custom colors
|
||||
*******************************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/light_off.py
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/light_hsv.py
|
||||
|
||||
Changing brightness and using custom colors
|
||||
*******************************************
|
||||
Making the light blink
|
||||
**********************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/light_hsv.py
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/light_blink.py
|
||||
|
||||
Making the light blink
|
||||
**********************
|
||||
Creating light animations
|
||||
*************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/light_blink.py
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/light_animate.py
|
||||
|
||||
Creating light animations
|
||||
*************************
|
||||
Matrix display examples
|
||||
-----------------------
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/light_animate.py
|
||||
Displaying images
|
||||
*****************
|
||||
|
||||
Matrix display examples
|
||||
-----------------------
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_image.py
|
||||
|
||||
Displaying images
|
||||
*****************
|
||||
Displaying numbers
|
||||
******************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_image.py
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_number.py
|
||||
|
||||
Displaying numbers
|
||||
******************
|
||||
Displaying text
|
||||
***************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_number.py
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_text.py
|
||||
|
||||
Displaying text
|
||||
***************
|
||||
Displaying individual pixels
|
||||
****************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_text.py
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_pixel.py
|
||||
|
||||
Displaying individual pixels
|
||||
****************************
|
||||
Changing the display orientation
|
||||
********************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_pixel.py
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_orientation.py
|
||||
|
||||
Changing the display orientation
|
||||
********************************
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_orientation_imu.py
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_orientation.py
|
||||
Making your own images
|
||||
**********************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_orientation_imu.py
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_matrix.py
|
||||
|
||||
Making your own images
|
||||
**********************
|
||||
Combining images to make expressions
|
||||
************************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_matrix.py
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_expression.py
|
||||
|
||||
Combining images to make expressions
|
||||
************************************
|
||||
Displaying animations
|
||||
*********************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_expression.py
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_animate.py
|
||||
|
||||
Displaying animations
|
||||
*********************
|
||||
Button examples
|
||||
---------------
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/display_animate.py
|
||||
Detecting button presses
|
||||
************************
|
||||
|
||||
Button examples
|
||||
---------------
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/button_main.py
|
||||
|
||||
Detecting button presses
|
||||
************************
|
||||
IMU examples
|
||||
---------------
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/button_main.py
|
||||
Testing which way is up
|
||||
********************************
|
||||
|
||||
IMU examples
|
||||
---------------
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/imu_up.py
|
||||
|
||||
Testing which way is up
|
||||
********************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/imu_up.py
|
||||
Reading the tilt value
|
||||
********************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/imu_tilt.py
|
||||
|
||||
Reading the tilt value
|
||||
********************************
|
||||
Using a custom hub orientation
|
||||
**************************************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/imu_tilt.py
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/imu_tilt_blast.py
|
||||
|
||||
Using a custom hub orientation
|
||||
**************************************************
|
||||
Reading acceleration and angular velocity vectors
|
||||
**************************************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/imu_tilt_blast.py
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/imu_read_vector.py
|
||||
|
||||
Reading acceleration and angular velocity vectors
|
||||
**************************************************
|
||||
Reading acceleration and angular velocity on one axis
|
||||
*****************************************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/imu_read_vector.py
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/imu_read_scalar.py
|
||||
|
||||
Reading acceleration and angular velocity on one axis
|
||||
*****************************************************
|
||||
System examples
|
||||
----------------------------------
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/imu_read_scalar.py
|
||||
Changing the stop button combination
|
||||
*****************************************
|
||||
|
||||
System examples
|
||||
----------------------------------
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/button_stop.py
|
||||
|
||||
Changing the stop button combination
|
||||
*****************************************
|
||||
Turning the hub off
|
||||
*****************************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/button_stop.py
|
||||
|
||||
Turning the hub off
|
||||
*****************************************
|
||||
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/system_shutdown.py
|
||||
.. literalinclude::
|
||||
../../../examples/pup/hub_primehub/system_shutdown.py
|
||||
|
||||
.. _installation instructions: https://pybricks.com/install/
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@ EV3 DC Motor
|
||||
.. figure:: ../../main/images/rcxmotor.png
|
||||
:width: 40 %
|
||||
|
||||
.. autoclass:: pybricks._common.DCMotor
|
||||
.. autoclass:: pybricks.iodevices.DCMotor
|
||||
:noindex:
|
||||
:no-members:
|
||||
|
||||
.. automethod:: pybricks._common.DCMotor.dc
|
||||
.. automethod:: pybricks.iodevices.DCMotor.dc
|
||||
:noindex:
|
||||
|
||||
.. automethod:: pybricks._common.DCMotor.stop
|
||||
.. automethod:: pybricks.iodevices.DCMotor.stop
|
||||
:noindex:
|
||||
|
||||
@@ -45,6 +45,12 @@ NXT Color Sensor
|
||||
|
||||
.. automethod:: pybricks.nxtdevices.ColorSensor.rgb
|
||||
|
||||
.. rubric:: Advanced color sensing
|
||||
|
||||
.. automethod:: pybricks.nxtdevices.ColorSensor.hsv
|
||||
|
||||
.. automethod:: pybricks.nxtdevices.ColorSensor.detectable_colors
|
||||
|
||||
.. rubric:: Built-in light
|
||||
|
||||
This sensor has a built-in light. You can make it red, green, blue, or turn
|
||||
|
||||
@@ -7,22 +7,8 @@ quantities. This page gives an overview of each quantity and its unit.
|
||||
Numbers
|
||||
~~~~~~~
|
||||
|
||||
.. class:: Number
|
||||
|
||||
Numbers can be represented as integers or floating point values:
|
||||
|
||||
* Integers (:class:`int <ubuiltins.int>`) are whole numbers
|
||||
like ``15`` or ``-123``.
|
||||
* Floating point values (:class:`float <ubuiltins.float>`) are decimal
|
||||
numbers like ``3.14`` or ``-123.45``.
|
||||
|
||||
If you see :class:`Number <Number>` as the argument type, both
|
||||
:class:`int <ubuiltins.int>` and :class:`float <ubuiltins.float>` may be used.
|
||||
|
||||
For example, :func:`wait(15) <pybricks.tools.wait>` and
|
||||
:func:`wait(15.75) <pybricks.tools.wait>` are both allowed. In most functions,
|
||||
however, your input value will be truncated to a whole number anyway. In this
|
||||
example, either command makes the program pause for just 15 milliseconds.
|
||||
.. autodata:: pybricks.parameters.Number
|
||||
:noindex:
|
||||
|
||||
Time
|
||||
~~~~~~
|
||||
|
||||
+2
-6
@@ -15,10 +15,6 @@ if "%TAG%" == "" (
|
||||
set TAG=main
|
||||
)
|
||||
|
||||
if "%BETA%" == "1" (
|
||||
set BETATAG=-tbeta
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
@@ -34,11 +30,11 @@ if errorlevel 9009 (
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -t %TAG% %BETATAG%
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -t %TAG%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -t %TAG% %BETATAG%
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -t %TAG%
|
||||
|
||||
:end
|
||||
popd
|
||||
|
||||
Generated
+370
@@ -0,0 +1,370 @@
|
||||
[[package]]
|
||||
name = "atomicwrites"
|
||||
version = "1.4.0"
|
||||
description = "Atomic file writes."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "attrs"
|
||||
version = "21.4.0"
|
||||
description = "Classes Without Boilerplate"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[package.extras]
|
||||
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"]
|
||||
docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
|
||||
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
|
||||
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"]
|
||||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "22.3.0"
|
||||
description = "The uncompromising code formatter."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6.2"
|
||||
|
||||
[package.dependencies]
|
||||
click = ">=8.0.0"
|
||||
mypy-extensions = ">=0.4.3"
|
||||
pathspec = ">=0.9.0"
|
||||
platformdirs = ">=2"
|
||||
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||
|
||||
[package.extras]
|
||||
colorama = ["colorama (>=0.4.3)"]
|
||||
d = ["aiohttp (>=3.7.4)"]
|
||||
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
|
||||
uvloop = ["uvloop (>=0.15.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.1.3"
|
||||
description = "Composable command line interface toolkit"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.5"
|
||||
description = "Cross-platform colored terminal text."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "flake8"
|
||||
version = "4.0.1"
|
||||
description = "the modular source code checker: pep8 pyflakes and co"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
mccabe = ">=0.6.0,<0.7.0"
|
||||
pycodestyle = ">=2.8.0,<2.9.0"
|
||||
pyflakes = ">=2.4.0,<2.5.0"
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "1.1.1"
|
||||
description = "iniconfig: brain-dead simple config-ini parsing"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "jedi"
|
||||
version = "0.18.1"
|
||||
description = "An autocompletion tool for Python that can be used for text editors."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
parso = ">=0.8.0,<0.9.0"
|
||||
|
||||
[package.extras]
|
||||
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
|
||||
testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "mccabe"
|
||||
version = "0.6.1"
|
||||
description = "McCabe checker, plugin for flake8"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "mypy-extensions"
|
||||
version = "0.4.3"
|
||||
description = "Experimental type system extensions for programs checked with the mypy typechecker."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "21.3"
|
||||
description = "Core utilities for Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
|
||||
|
||||
[[package]]
|
||||
name = "parso"
|
||||
version = "0.8.3"
|
||||
description = "A Python Parser"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.extras]
|
||||
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
|
||||
testing = ["docopt", "pytest (<6.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pathspec"
|
||||
version = "0.9.0"
|
||||
description = "Utility library for gitignore style pattern matching of file paths."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "2.5.2"
|
||||
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"]
|
||||
test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.0.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "tox"]
|
||||
testing = ["pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "py"
|
||||
version = "1.11.0"
|
||||
description = "library with cross-python path, ini-parsing, io, code, log facilities"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "pybricks"
|
||||
version = "3.2.0b1-r2"
|
||||
description = "Documentation and user-API stubs for Pybricks MicroPython"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "^3.8"
|
||||
develop = true
|
||||
|
||||
[package.source]
|
||||
type = "directory"
|
||||
url = ".."
|
||||
|
||||
[[package]]
|
||||
name = "pycodestyle"
|
||||
version = "2.8.0"
|
||||
description = "Python style guide checker"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "pyflakes"
|
||||
version = "2.4.0"
|
||||
description = "passive checker of Python programs"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "pyparsing"
|
||||
version = "3.0.9"
|
||||
description = "pyparsing module - Classes and methods to define and execute parsing grammars"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6.8"
|
||||
|
||||
[package.extras]
|
||||
diagrams = ["railroad-diagrams", "jinja2"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "7.1.2"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
|
||||
attrs = ">=19.2.0"
|
||||
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
iniconfig = "*"
|
||||
packaging = "*"
|
||||
pluggy = ">=0.12,<2.0"
|
||||
py = ">=1.8.2"
|
||||
tomli = ">=1.0.0"
|
||||
|
||||
[package.extras]
|
||||
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"]
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.0.1"
|
||||
description = "A lil' TOML parser"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.2.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.7+"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = ">= 3.10, < 3.11"
|
||||
content-hash = "9b91afcb8ccd46cc8be150f48170e45e86a6c65686d7e6e97ac3de67988c0ff5"
|
||||
|
||||
[metadata.files]
|
||||
atomicwrites = [
|
||||
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
|
||||
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
|
||||
]
|
||||
attrs = [
|
||||
{file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
|
||||
{file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"},
|
||||
]
|
||||
black = [
|
||||
{file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"},
|
||||
{file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"},
|
||||
{file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"},
|
||||
{file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"},
|
||||
{file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"},
|
||||
{file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"},
|
||||
{file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"},
|
||||
{file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"},
|
||||
{file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"},
|
||||
{file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"},
|
||||
{file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"},
|
||||
{file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"},
|
||||
{file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"},
|
||||
{file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"},
|
||||
{file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"},
|
||||
{file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"},
|
||||
{file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"},
|
||||
{file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"},
|
||||
{file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"},
|
||||
{file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"},
|
||||
{file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"},
|
||||
{file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"},
|
||||
{file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"},
|
||||
]
|
||||
click = [
|
||||
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
|
||||
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
|
||||
]
|
||||
colorama = [
|
||||
{file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"},
|
||||
{file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
|
||||
]
|
||||
flake8 = [
|
||||
{file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"},
|
||||
{file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"},
|
||||
]
|
||||
iniconfig = [
|
||||
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
|
||||
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
|
||||
]
|
||||
jedi = [
|
||||
{file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"},
|
||||
{file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"},
|
||||
]
|
||||
mccabe = [
|
||||
{file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
|
||||
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
|
||||
]
|
||||
mypy-extensions = [
|
||||
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
|
||||
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
|
||||
]
|
||||
packaging = [
|
||||
{file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
|
||||
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
|
||||
]
|
||||
parso = [
|
||||
{file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"},
|
||||
{file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"},
|
||||
]
|
||||
pathspec = [
|
||||
{file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
|
||||
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
|
||||
]
|
||||
platformdirs = [
|
||||
{file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"},
|
||||
{file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"},
|
||||
]
|
||||
pluggy = [
|
||||
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
|
||||
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
|
||||
]
|
||||
py = [
|
||||
{file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
|
||||
{file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
|
||||
]
|
||||
pybricks = []
|
||||
pycodestyle = [
|
||||
{file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"},
|
||||
{file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"},
|
||||
]
|
||||
pyflakes = [
|
||||
{file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"},
|
||||
{file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"},
|
||||
]
|
||||
pyparsing = [
|
||||
{file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
|
||||
{file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
|
||||
]
|
||||
pytest = [
|
||||
{file = "pytest-7.1.2-py3-none-any.whl", hash = "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c"},
|
||||
{file = "pytest-7.1.2.tar.gz", hash = "sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45"},
|
||||
]
|
||||
tomli = [
|
||||
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
||||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||
]
|
||||
typing-extensions = [
|
||||
{file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"},
|
||||
{file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"},
|
||||
]
|
||||
@@ -0,0 +1,26 @@
|
||||
[tool.poetry]
|
||||
name = "pybricks_jedi"
|
||||
version = "1.0.0"
|
||||
description = "Code completion for Pybricks."
|
||||
authors = ["The Pybricks Authors"]
|
||||
license = "MIT"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">= 3.10, < 3.11"
|
||||
pybricks = "^3.2.0b1-r2"
|
||||
jedi = "^0.18.1"
|
||||
typing-extensions = "^4.2.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^7.1.2"
|
||||
black = "^22.3.0"
|
||||
flake8 = "^4.0.1"
|
||||
pybricks = { path = "../", develop = true }
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
pythonpath = ["src"]
|
||||
testpaths = ["tests"]
|
||||
@@ -0,0 +1,391 @@
|
||||
from enum import IntEnum
|
||||
import json
|
||||
from typing_extensions import TypedDict, NotRequired
|
||||
import jedi
|
||||
from jedi.api.classes import Completion, Signature, ParamName
|
||||
|
||||
# Packages included in Pybricks firmware that ships with Pybricks Code.
|
||||
PYBRICKS_CODE_PACKAGES = {
|
||||
"micropython",
|
||||
"pybricks",
|
||||
"pybricks.geometry",
|
||||
"pybricks.hubs",
|
||||
"pybricks.iodevices",
|
||||
"pybricks.parameters",
|
||||
"pybricks.pupdevices",
|
||||
"pybricks.robotics",
|
||||
"pybricks.tools",
|
||||
"uerrno",
|
||||
"uio",
|
||||
"umath",
|
||||
"urandom",
|
||||
"uselect",
|
||||
"usys",
|
||||
}
|
||||
|
||||
# Subset of Python builtins included in Pybricks MicroPython.
|
||||
PYBRICKS_BUILTINS = {
|
||||
"abs",
|
||||
"all",
|
||||
"any",
|
||||
"ArithmeticError",
|
||||
"AssertionError",
|
||||
"AttributeError",
|
||||
"BaseException",
|
||||
"bin",
|
||||
"bool",
|
||||
"bytearray",
|
||||
"bytes",
|
||||
"callable",
|
||||
"chr",
|
||||
"classmethod",
|
||||
"complex",
|
||||
"dict",
|
||||
"dir",
|
||||
"divmod",
|
||||
"enumerate",
|
||||
"EOFError",
|
||||
"eval",
|
||||
"Exception",
|
||||
"exec",
|
||||
"float",
|
||||
"GeneratorExit",
|
||||
"getattr",
|
||||
"globals",
|
||||
"hasattr",
|
||||
"hash",
|
||||
"help",
|
||||
"hex",
|
||||
"id",
|
||||
"ImportError",
|
||||
"IndentationError",
|
||||
"IndexError",
|
||||
"input",
|
||||
"int",
|
||||
"isinstance",
|
||||
"issubclass",
|
||||
"iter",
|
||||
"KeyboardInterrupt",
|
||||
"KeyError",
|
||||
"len",
|
||||
"list",
|
||||
"locals",
|
||||
"LookupError",
|
||||
"map",
|
||||
"max",
|
||||
"MemoryError",
|
||||
"min",
|
||||
"NameError",
|
||||
"next",
|
||||
"NotImplementedError",
|
||||
"object",
|
||||
"oct",
|
||||
"ord",
|
||||
"OSError",
|
||||
"OverflowError",
|
||||
"pow",
|
||||
"print",
|
||||
"range",
|
||||
"repr",
|
||||
"reversed",
|
||||
"round",
|
||||
"RuntimeError",
|
||||
"set",
|
||||
"setattr",
|
||||
"slice",
|
||||
"sorted",
|
||||
"staticmethod",
|
||||
"StopIteration",
|
||||
"str",
|
||||
"sum",
|
||||
"super",
|
||||
"SyntaxError",
|
||||
"SystemExit",
|
||||
"tuple",
|
||||
"type",
|
||||
"TypeError",
|
||||
"ValueError",
|
||||
"ZeroDivisionError",
|
||||
"zip",
|
||||
}
|
||||
|
||||
# Types from monaco editor
|
||||
|
||||
|
||||
class IRange(TypedDict):
|
||||
startLineNumber: int
|
||||
startColumn: int
|
||||
endLineNumber: int
|
||||
endColumn: int
|
||||
|
||||
|
||||
class ISingleEditOperation(TypedDict):
|
||||
range: IRange
|
||||
text: str # TODO: can also be JavaScript null
|
||||
forceMoveMarkers: NotRequired[bool]
|
||||
|
||||
|
||||
class Command(TypedDict):
|
||||
id: str
|
||||
title: str
|
||||
tooltip: NotRequired[str]
|
||||
arguments: NotRequired[list]
|
||||
|
||||
|
||||
class CompletionItemKind(IntEnum):
|
||||
Method = 0
|
||||
Function = 1
|
||||
Constructor = 2
|
||||
Field = 3
|
||||
Variable = 4
|
||||
Class = 5
|
||||
Struct = 6
|
||||
Interface = 7
|
||||
Module = 8
|
||||
Property = 9
|
||||
Event = 10
|
||||
Operator = 11
|
||||
Unit = 12
|
||||
Value = 13
|
||||
Constant = 14
|
||||
Enum = 15
|
||||
EnumMember = 16
|
||||
Keyword = 17
|
||||
Text = 18
|
||||
Color = 19
|
||||
File = 20
|
||||
Reference = 21
|
||||
Customcolor = 22
|
||||
Folder = 23
|
||||
TypeParameter = 24
|
||||
User = 25
|
||||
Issue = 26
|
||||
Snippet = 27
|
||||
|
||||
|
||||
class CompletionItemTag(IntEnum):
|
||||
Deprecated = 1
|
||||
|
||||
|
||||
class CompletionItemInsertTextRule(IntEnum):
|
||||
KeepWhitespace = 1
|
||||
InsertAsSnippet = 4
|
||||
|
||||
|
||||
class CompletionItemLabel(TypedDict):
|
||||
label: str
|
||||
detail: NotRequired[str]
|
||||
description: NotRequired[str]
|
||||
|
||||
|
||||
class CompletionItemRanges(TypedDict):
|
||||
insert: IRange
|
||||
replace: IRange
|
||||
|
||||
|
||||
class CompletionItem(TypedDict):
|
||||
label: str | CompletionItemLabel
|
||||
kind: CompletionItemKind
|
||||
tags: NotRequired[list[CompletionItemTag]]
|
||||
detail: NotRequired[str]
|
||||
documentation: NotRequired[str]
|
||||
sortText: NotRequired[str]
|
||||
filterText: NotRequired[str]
|
||||
preselect: NotRequired[bool]
|
||||
insertText: str
|
||||
insertTextRules: NotRequired[CompletionItemInsertTextRule]
|
||||
range: IRange | CompletionItemRanges
|
||||
commitCharacters: NotRequired[list[str]]
|
||||
additionalTextEdits: NotRequired[list[ISingleEditOperation]]
|
||||
command: NotRequired[Command]
|
||||
|
||||
|
||||
class ParameterInformation(TypedDict):
|
||||
label: str | tuple[int, int]
|
||||
documentation: NotRequired[str]
|
||||
|
||||
|
||||
class SignatureInformation(TypedDict):
|
||||
label: str
|
||||
documentation: NotRequired[str]
|
||||
parameters: list[ParameterInformation]
|
||||
activeParameter: NotRequired[int]
|
||||
|
||||
|
||||
class SignatureHelp(TypedDict):
|
||||
signatures: list[SignatureInformation]
|
||||
activeSignature: int
|
||||
activeParameter: int
|
||||
|
||||
|
||||
def _is_pybricks(c: Completion) -> bool:
|
||||
# filter all "private" names (leading underscore)
|
||||
if (isinstance(c.name, str)) and c.name.startswith("_"):
|
||||
return False
|
||||
|
||||
if isinstance(c.full_name, str):
|
||||
# this catches things like `from __future__ import annotations`
|
||||
if c.full_name.startswith("_") and c.module_name != "__main__":
|
||||
return False
|
||||
|
||||
# filter out enum types
|
||||
if c.full_name.startswith("enum."):
|
||||
return False
|
||||
|
||||
# filter out typing types
|
||||
if c.full_name.startswith("typing."):
|
||||
return False
|
||||
|
||||
# filter out packages/modules that are not included in Pybricks firmware
|
||||
if c.type == "module" or c.type == "namespace":
|
||||
return c.full_name in PYBRICKS_CODE_PACKAGES
|
||||
|
||||
# filter subset of builtins
|
||||
if c.module_name == "builtins" and c.type != "keyword":
|
||||
return c.name in PYBRICKS_BUILTINS
|
||||
|
||||
# this is a type alias, not a real type
|
||||
if c.full_name == "pybricks.parameters.Number":
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def _map_completion_kind(type: str) -> CompletionItemKind:
|
||||
match type:
|
||||
case "module":
|
||||
return CompletionItemKind.Module
|
||||
case "class":
|
||||
return CompletionItemKind.Class
|
||||
case "instance":
|
||||
return CompletionItemKind.Variable
|
||||
case "function":
|
||||
return CompletionItemKind.Function
|
||||
case "param":
|
||||
return CompletionItemKind.Variable
|
||||
case "path":
|
||||
return CompletionItemKind.File
|
||||
case "keyword":
|
||||
return CompletionItemKind.Keyword
|
||||
case "property":
|
||||
return CompletionItemKind.Property
|
||||
case "statement":
|
||||
return CompletionItemKind.Variable
|
||||
case _:
|
||||
return CompletionItemKind.User
|
||||
|
||||
|
||||
def _map_completion_item(
|
||||
completion: Completion, line: int, column: int
|
||||
) -> CompletionItem:
|
||||
"""
|
||||
Maps a Jedi completion to a Monaco editor CompletionItem.
|
||||
|
||||
Note: All members of the CompletionItem must be directly mappable without
|
||||
PyProxy in Pyodide.
|
||||
"""
|
||||
return CompletionItem(
|
||||
insertText=completion.name_with_symbols,
|
||||
kind=_map_completion_kind(completion.type),
|
||||
label=completion.name_with_symbols,
|
||||
range=IRange(
|
||||
startLineNumber=line,
|
||||
startColumn=column - completion.get_completion_prefix_length(),
|
||||
endLineNumber=line,
|
||||
endColumn=column,
|
||||
),
|
||||
documentation=completion.docstring(),
|
||||
)
|
||||
|
||||
|
||||
def _map_parameter(param: ParamName) -> ParameterInformation:
|
||||
# NB: it is not possible to get docstring for individual parameters from jedi
|
||||
return ParameterInformation(label=param.to_string())
|
||||
|
||||
|
||||
def _map_signature(signature: Signature) -> SignatureInformation:
|
||||
optional = {} if signature.index is None else dict(activeParameter=signature.index)
|
||||
|
||||
return SignatureInformation(
|
||||
label=signature.to_string(),
|
||||
documentation=signature.docstring(),
|
||||
parameters=[_map_parameter(p) for p in signature.params],
|
||||
**optional,
|
||||
)
|
||||
|
||||
|
||||
def _map_signatures(signatures: list[Signature]) -> SignatureHelp:
|
||||
return SignatureHelp(
|
||||
signatures=[_map_signature(s) for s in signatures],
|
||||
activeSignature=0,
|
||||
activeParameter=0,
|
||||
)
|
||||
|
||||
|
||||
def initialize():
|
||||
"""
|
||||
Initialize jedi with Pybricks-specific config.
|
||||
"""
|
||||
|
||||
jedi.preload_module(
|
||||
"typing",
|
||||
"enum",
|
||||
"micropython",
|
||||
"pybricks._common",
|
||||
"pybricks.ev3dev",
|
||||
"pybricks.ev3dev.speaker",
|
||||
"pybricks.geometry",
|
||||
"pybricks.hubs",
|
||||
"pybricks.iodevices",
|
||||
"pybricks.parameters",
|
||||
"pybricks.pupdevices",
|
||||
"pybricks.robotics",
|
||||
"pybricks.tools",
|
||||
"pybricks",
|
||||
"ubuiltins",
|
||||
"uerrno",
|
||||
"uio",
|
||||
"ujson",
|
||||
"umath",
|
||||
"urandom",
|
||||
"uselect",
|
||||
"ustruct",
|
||||
"usys",
|
||||
)
|
||||
|
||||
# also preload "everything" in builtins
|
||||
jedi.Script("").complete()
|
||||
|
||||
|
||||
def complete(code: str, line: int, column: int) -> str:
|
||||
"""
|
||||
Calls jedi.Script().complete() and filters the results for Pybricks.
|
||||
|
||||
Args:
|
||||
code: The Python code to parse.
|
||||
line: The 1-based line number of the cursor position.
|
||||
column: The 1-based column number of the cursor position.
|
||||
|
||||
Returns:
|
||||
A json string containing a filtered list of completion items.
|
||||
"""
|
||||
completions = jedi.Script(code).complete(line, column - 1, fuzzy=True)
|
||||
return json.dumps(
|
||||
[_map_completion_item(c, line, column) for c in completions if _is_pybricks(c)]
|
||||
)
|
||||
|
||||
|
||||
def get_signatures(code: str, line: int, column: int) -> str:
|
||||
"""
|
||||
Calls jedi.Script().get_signatures().
|
||||
|
||||
Args:
|
||||
code: The Python code to parse.
|
||||
line: The 1-based line number of the cursor position.
|
||||
column: The 1-based column number of the cursor position.
|
||||
|
||||
Returns:
|
||||
A json string containing the signature help.
|
||||
"""
|
||||
signatures = jedi.Script(code).get_signatures(line, column - 1)
|
||||
return json.dumps(_map_signatures(signatures))
|
||||
@@ -0,0 +1,30 @@
|
||||
import pybricks_jedi
|
||||
|
||||
|
||||
def pytest_configure(config):
|
||||
"""
|
||||
Allows plugins and conftest files to perform initial configuration.
|
||||
This hook is called for every plugin and initial conftest
|
||||
file after command line options have been parsed.
|
||||
"""
|
||||
|
||||
|
||||
def pytest_sessionstart(session):
|
||||
"""
|
||||
Called after the Session object has been created and
|
||||
before performing collection and entering the run test loop.
|
||||
"""
|
||||
pybricks_jedi.initialize()
|
||||
|
||||
|
||||
def pytest_sessionfinish(session, exitstatus):
|
||||
"""
|
||||
Called after whole test run finished, right before
|
||||
returning the exit status to the system.
|
||||
"""
|
||||
|
||||
|
||||
def pytest_unconfigure(config):
|
||||
"""
|
||||
called before test process is exited.
|
||||
"""
|
||||
@@ -0,0 +1,126 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2022 The Pybricks Authors
|
||||
|
||||
"""
|
||||
Tests for correct code completion of builtins.
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
from pybricks_jedi import CompletionItem, complete
|
||||
|
||||
|
||||
def test_empty_code():
|
||||
code = ""
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, 1))
|
||||
# since nothing has been imported, this is just all builtins and keywords
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"abs",
|
||||
"all",
|
||||
"any",
|
||||
"ArithmeticError",
|
||||
"assert",
|
||||
"AssertionError",
|
||||
"async",
|
||||
"AttributeError",
|
||||
"await",
|
||||
"BaseException",
|
||||
"bin",
|
||||
"bool",
|
||||
"break",
|
||||
"bytearray",
|
||||
"bytes",
|
||||
"callable",
|
||||
"chr",
|
||||
"class",
|
||||
"classmethod",
|
||||
"complex",
|
||||
"continue",
|
||||
"def",
|
||||
"del",
|
||||
"dict",
|
||||
"dir",
|
||||
"divmod",
|
||||
"enumerate",
|
||||
"EOFError",
|
||||
"eval",
|
||||
"Exception",
|
||||
"exec",
|
||||
"False",
|
||||
"float",
|
||||
"for",
|
||||
"from",
|
||||
"GeneratorExit",
|
||||
"getattr",
|
||||
"global",
|
||||
"globals",
|
||||
"hasattr",
|
||||
"hash",
|
||||
"help",
|
||||
"hex",
|
||||
"id",
|
||||
"if",
|
||||
"import",
|
||||
"ImportError",
|
||||
"IndentationError",
|
||||
"IndexError",
|
||||
"input",
|
||||
"int",
|
||||
"isinstance",
|
||||
"issubclass",
|
||||
"iter",
|
||||
"KeyboardInterrupt",
|
||||
"KeyError",
|
||||
"lambda",
|
||||
"len",
|
||||
"list",
|
||||
"locals",
|
||||
"LookupError",
|
||||
"map",
|
||||
"max",
|
||||
"MemoryError",
|
||||
"min",
|
||||
"NameError",
|
||||
"next",
|
||||
"None",
|
||||
"nonlocal",
|
||||
"not",
|
||||
"NotImplementedError",
|
||||
"object",
|
||||
"oct",
|
||||
"ord",
|
||||
"OSError",
|
||||
"OverflowError",
|
||||
"pass",
|
||||
"pow",
|
||||
"print",
|
||||
"raise",
|
||||
"range",
|
||||
"repr",
|
||||
"return",
|
||||
"reversed",
|
||||
"round",
|
||||
"RuntimeError",
|
||||
"set",
|
||||
"setattr",
|
||||
"slice",
|
||||
"sorted",
|
||||
"staticmethod",
|
||||
"StopIteration",
|
||||
"str",
|
||||
"sum",
|
||||
"super",
|
||||
"SyntaxError",
|
||||
"SystemExit",
|
||||
"True",
|
||||
"try",
|
||||
"tuple",
|
||||
"type",
|
||||
"TypeError",
|
||||
"ValueError",
|
||||
"while",
|
||||
"with",
|
||||
"yield",
|
||||
"ZeroDivisionError",
|
||||
"zip",
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2022 The Pybricks Authors
|
||||
|
||||
"""
|
||||
Tests for correct code completion of the CityHub class.
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
from pybricks_jedi import CompletionItem, complete
|
||||
|
||||
IMPORT = "from pybricks.hubs import CityHub"
|
||||
CREATE_INSTANCE = "hub = CityHub()"
|
||||
|
||||
|
||||
def _create_snippet(line: str) -> str:
|
||||
"""
|
||||
Creates a code snippet::
|
||||
|
||||
from pybricks.hubs import CityHub
|
||||
hub = CityHub()
|
||||
{line}
|
||||
|
||||
Args:
|
||||
line: The value substituted for ``{line}``
|
||||
"""
|
||||
return "\n".join((IMPORT, CREATE_INSTANCE, line))
|
||||
|
||||
|
||||
def test_hub_dot():
|
||||
line = "hub."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"battery",
|
||||
"button",
|
||||
"light",
|
||||
"system",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_battery_dot():
|
||||
line = "hub.battery."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"current",
|
||||
"voltage",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_button_dot():
|
||||
line = "hub.button."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"pressed",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_light_dot():
|
||||
line = "hub.light."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"animate",
|
||||
"blink",
|
||||
"off",
|
||||
"on",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_system_dot():
|
||||
line = "hub.system."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"name",
|
||||
"reset_reason",
|
||||
"set_stop_button",
|
||||
"shutdown",
|
||||
]
|
||||
@@ -0,0 +1,254 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2022 The Pybricks Authors
|
||||
|
||||
"""
|
||||
Tests for correct code completion of import statements.
|
||||
"""
|
||||
|
||||
import json
|
||||
from pybricks_jedi import CompletionItem, complete
|
||||
|
||||
|
||||
def test_from():
|
||||
code = "from "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
# only modules included in Pybricks firmware should be listed
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"micropython",
|
||||
"pybricks",
|
||||
"uerrno",
|
||||
"uio",
|
||||
"umath",
|
||||
"urandom",
|
||||
"uselect",
|
||||
"usys",
|
||||
]
|
||||
|
||||
|
||||
def test_from_pybricks_import():
|
||||
code = "from pybricks import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"geometry",
|
||||
"hubs",
|
||||
"iodevices",
|
||||
"parameters",
|
||||
"pupdevices",
|
||||
"robotics",
|
||||
"tools",
|
||||
"version",
|
||||
]
|
||||
|
||||
|
||||
def test_from_pybricks_dot():
|
||||
code = "from pybricks."
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"geometry",
|
||||
"hubs",
|
||||
"iodevices",
|
||||
"parameters",
|
||||
"pupdevices",
|
||||
"robotics",
|
||||
"tools",
|
||||
]
|
||||
|
||||
|
||||
def test_from_pybricks_geometry_import():
|
||||
code = "from pybricks.geometry import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"Axis",
|
||||
"Matrix",
|
||||
"vector",
|
||||
]
|
||||
|
||||
|
||||
def test_from_pybricks_hubs_import():
|
||||
code = "from pybricks.hubs import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"CityHub",
|
||||
"EV3Brick",
|
||||
"InventorHub",
|
||||
"MoveHub",
|
||||
"PrimeHub",
|
||||
"TechnicHub",
|
||||
]
|
||||
|
||||
|
||||
def test_from_pybricks_iodevices_import():
|
||||
code = "from pybricks.iodevices import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"AnalogSensor",
|
||||
"DCMotor",
|
||||
"Ev3devSensor",
|
||||
"I2CDevice",
|
||||
"LUMPDevice",
|
||||
"LWP3Device",
|
||||
"PUPDevice",
|
||||
"UARTDevice",
|
||||
]
|
||||
|
||||
|
||||
def test_from_pybricks_parameters_import():
|
||||
code = "from pybricks.parameters import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"Button",
|
||||
"Color",
|
||||
"Direction",
|
||||
"Icon",
|
||||
"Port",
|
||||
"Side",
|
||||
"Stop",
|
||||
]
|
||||
|
||||
|
||||
def test_from_pybricks_pupdevices_import():
|
||||
code = "from pybricks.pupdevices import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"ColorDistanceSensor",
|
||||
"ColorLightMatrix",
|
||||
"ColorSensor",
|
||||
"DCMotor",
|
||||
"ForceSensor",
|
||||
"InfraredSensor",
|
||||
"Light",
|
||||
"Motor",
|
||||
"PFMotor",
|
||||
"Remote",
|
||||
"TiltSensor",
|
||||
"UltrasonicSensor",
|
||||
]
|
||||
|
||||
|
||||
def test_from_pybricks_robotics_import():
|
||||
code = "from pybricks.robotics import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"DriveBase",
|
||||
]
|
||||
|
||||
|
||||
def test_from_pybricks_tools_import():
|
||||
code = "from pybricks.tools import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"DataLog",
|
||||
"StopWatch",
|
||||
"wait",
|
||||
]
|
||||
|
||||
|
||||
def test_from_micropython_import():
|
||||
code = "from micropython import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"const",
|
||||
"kbd_intr",
|
||||
"mem_info",
|
||||
"opt_level",
|
||||
"qstr_info",
|
||||
"stack_use",
|
||||
]
|
||||
|
||||
|
||||
def test_from_uerrno_import():
|
||||
code = "from uerrno import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"EAGAIN",
|
||||
"EBUSY",
|
||||
"ECANCELED",
|
||||
"EINVAL",
|
||||
"EIO",
|
||||
"ENODEV",
|
||||
"EOPNOTSUPP",
|
||||
"EPERM",
|
||||
"errorcode",
|
||||
"ETIMEDOUT",
|
||||
]
|
||||
|
||||
|
||||
def test_from_uio_import():
|
||||
code = "from uio import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"BytesIO",
|
||||
"FileIO",
|
||||
"StringIO",
|
||||
]
|
||||
|
||||
|
||||
def test_from_umath_import():
|
||||
code = "from umath import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"acos",
|
||||
"asin",
|
||||
"atan",
|
||||
"atan2",
|
||||
"ceil",
|
||||
"copysign",
|
||||
"cos",
|
||||
"degrees",
|
||||
"e",
|
||||
"exp",
|
||||
"fabs",
|
||||
"floor",
|
||||
"fmod",
|
||||
"frexp",
|
||||
"isfinite",
|
||||
"isinfinite",
|
||||
"isnan",
|
||||
"ldexp",
|
||||
"log",
|
||||
"modf",
|
||||
"pi",
|
||||
"pow",
|
||||
"radians",
|
||||
"sin",
|
||||
"sqrt",
|
||||
"tan",
|
||||
"trunc",
|
||||
]
|
||||
|
||||
|
||||
def test_from_urandom_import():
|
||||
code = "from urandom import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"choice",
|
||||
"getrandbits",
|
||||
"randint",
|
||||
"random",
|
||||
"randrange",
|
||||
"seed",
|
||||
"uniform",
|
||||
]
|
||||
|
||||
|
||||
def test_from_uselect_import():
|
||||
code = "from uselect import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"poll",
|
||||
"Poll",
|
||||
"POLLERR",
|
||||
"POLLHUP",
|
||||
"POLLIN",
|
||||
"POLLOUT",
|
||||
]
|
||||
|
||||
|
||||
def test_from_usys_import():
|
||||
code = "from usys import "
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 1, len(code) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"stderr",
|
||||
"stdin",
|
||||
"stdout",
|
||||
]
|
||||
@@ -0,0 +1,327 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2022 The Pybricks Authors
|
||||
|
||||
"""
|
||||
Tests for correct code completion of the InventorHub class.
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
from pybricks_jedi import SignatureHelp, complete, get_signatures, CompletionItem
|
||||
|
||||
IMPORT = "from pybricks.hubs import InventorHub"
|
||||
CREATE_INSTANCE = "hub = InventorHub()"
|
||||
|
||||
|
||||
def _create_snippet(line: str) -> str:
|
||||
"""
|
||||
Creates a code snippet::
|
||||
|
||||
from pybricks.hubs import InventorHub
|
||||
hub = InventorHub()
|
||||
{line}
|
||||
|
||||
Args:
|
||||
line: The value substituted for ``{line}``
|
||||
"""
|
||||
return "\n".join((IMPORT, CREATE_INSTANCE, line))
|
||||
|
||||
|
||||
def test_hub_dot():
|
||||
line = "hub."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"battery",
|
||||
"buttons",
|
||||
"charger",
|
||||
"display",
|
||||
"imu",
|
||||
"light",
|
||||
"speaker",
|
||||
"system",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_battery_dot():
|
||||
line = "hub.battery."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"current",
|
||||
"voltage",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_battery_dot_current():
|
||||
line = "hub.battery.current("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == ["current() -> int"]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [None]
|
||||
|
||||
|
||||
def test_hub_dot_battery_dot_voltage():
|
||||
line = "hub.battery.voltage("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == ["voltage() -> int"]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [None]
|
||||
|
||||
|
||||
def test_hub_dot_buttons_dot():
|
||||
line = "hub.buttons."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"pressed",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_battery_dot_pressed():
|
||||
line = "hub.buttons.pressed("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"pressed() -> Tuple[Button]"
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [None]
|
||||
|
||||
|
||||
def test_hub_dot_charger_dot():
|
||||
line = "hub.charger."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"connected",
|
||||
"current",
|
||||
"status",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_charger_dot_connected():
|
||||
line = "hub.charger.connected("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == ["connected() -> bool"]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [None]
|
||||
|
||||
|
||||
def test_hub_dot_charger_dot_current():
|
||||
line = "hub.charger.current("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == ["current() -> int"]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [None]
|
||||
|
||||
|
||||
def test_hub_dot_display_dot():
|
||||
line = "hub.display."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"animate",
|
||||
"char",
|
||||
"image",
|
||||
"number",
|
||||
"off",
|
||||
"orientation",
|
||||
"pixel",
|
||||
"text",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_imu_dot():
|
||||
line = "hub.imu."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"acceleration",
|
||||
"angular_velocity",
|
||||
"heading",
|
||||
"reset_heading",
|
||||
"tilt",
|
||||
"up",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_light_dot():
|
||||
line = "hub.light."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"animate",
|
||||
"blink",
|
||||
"off",
|
||||
"on",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_light_dot_animate():
|
||||
line = "hub.light.animate("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"animate(colors: Collection[Color], interval: Number) -> None",
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [0]
|
||||
assert [
|
||||
[p["label"] for p in s["parameters"]] for s in signatures["signatures"]
|
||||
] == [["colors: Collection[Color]", "interval: Number"]]
|
||||
|
||||
|
||||
def test_hub_dot_light_dot_animate2():
|
||||
line = "hub.light.animate([],"
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"animate(colors: Collection[Color], interval: Number) -> None",
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [1]
|
||||
assert [
|
||||
[p["label"] for p in s["parameters"]] for s in signatures["signatures"]
|
||||
] == [["colors: Collection[Color]", "interval: Number"]]
|
||||
|
||||
|
||||
def test_hub_dot_light_dot_blink():
|
||||
line = "hub.light.blink("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"blink(color: Color, durations: Collection[int]) -> None",
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [0]
|
||||
|
||||
|
||||
def test_hub_dot_light_dot_blink2():
|
||||
line = "hub.light.blink(Color.RED,"
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"blink(color: Color, durations: Collection[int]) -> None",
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [1]
|
||||
|
||||
|
||||
def test_hub_dot_light_dot_on():
|
||||
line = "hub.light.on("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"on(color: Color) -> None",
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [0]
|
||||
|
||||
|
||||
def test_hub_dot_speaker_dot():
|
||||
line = "hub.speaker."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"beep",
|
||||
"play_notes",
|
||||
"volume",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_speaker_dot_beep():
|
||||
line = "hub.speaker.beep("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"beep(frequency: Number=500, duration: Number=100) -> None",
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [0]
|
||||
|
||||
|
||||
def test_hub_dot_speaker_dot_beep2():
|
||||
line = "hub.speaker.beep(100,"
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"beep(frequency: Number=500, duration: Number=100) -> None",
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [1]
|
||||
|
||||
|
||||
def test_hub_dot_speaker_dot_play_notes():
|
||||
line = "hub.speaker.play_notes("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"play_notes(notes: Iterable[str], tempo: Number=120) -> None",
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [0]
|
||||
|
||||
|
||||
def test_hub_dot_speaker_dot_play_notes2():
|
||||
line = "hub.speaker.play_notes([],"
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"play_notes(notes: Iterable[str], tempo: Number=120) -> None",
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [1]
|
||||
|
||||
|
||||
def test_hub_dot_speaker_dot_volume():
|
||||
line = "hub.speaker.volume("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"volume() -> int",
|
||||
"volume(volume: Number) -> None",
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [None, 0]
|
||||
|
||||
|
||||
def test_hub_dot_system_dot():
|
||||
line = "hub.system."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"name",
|
||||
"reset_reason",
|
||||
"set_stop_button",
|
||||
"shutdown",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_system_dot_name():
|
||||
line = "hub.system.name("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"name() -> str",
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [None]
|
||||
|
||||
|
||||
def test_hub_dot_system_dot_reset_reason():
|
||||
line = "hub.system.reset_reason("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"reset_reason() -> int",
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [None]
|
||||
|
||||
|
||||
def test_hub_dot_system_dot_set_stop_button():
|
||||
line = "hub.system.set_stop_button("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"set_stop_button(button: Optional[Union[Button, Iterable[Button]]]) -> None",
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [0]
|
||||
|
||||
|
||||
def test_hub_dot_system_dot_shutdown():
|
||||
line = "hub.system.shutdown("
|
||||
code = _create_snippet(line)
|
||||
signatures: SignatureHelp = json.loads(get_signatures(code, 3, len(line) + 1))
|
||||
assert [s["label"] for s in signatures["signatures"]] == [
|
||||
"shutdown() -> None",
|
||||
]
|
||||
assert [s.get("activeParameter") for s in signatures["signatures"]] == [None]
|
||||
@@ -0,0 +1,93 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2022 The Pybricks Authors
|
||||
|
||||
"""
|
||||
Tests for correct code completion of the MoveHub class.
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
from pybricks_jedi import CompletionItem, complete
|
||||
|
||||
IMPORT = "from pybricks.hubs import MoveHub"
|
||||
CREATE_INSTANCE = "hub = MoveHub()"
|
||||
|
||||
|
||||
def _create_snippet(line: str) -> str:
|
||||
"""
|
||||
Creates a code snippet::
|
||||
|
||||
from pybricks.hubs import MoveHub
|
||||
hub = MoveHub()
|
||||
{line}
|
||||
|
||||
Args:
|
||||
line: The value substituted for ``{line}``
|
||||
"""
|
||||
return "\n".join((IMPORT, CREATE_INSTANCE, line))
|
||||
|
||||
|
||||
def test_hub_dot():
|
||||
line = "hub."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"battery",
|
||||
"button",
|
||||
"imu",
|
||||
"light",
|
||||
"system",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_battery_dot():
|
||||
line = "hub.battery."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"current",
|
||||
"voltage",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_button_dot():
|
||||
line = "hub.button."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"pressed",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_imu_dot():
|
||||
line = "hub.imu."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"acceleration",
|
||||
"up",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_light_dot():
|
||||
line = "hub.light."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"animate",
|
||||
"blink",
|
||||
"off",
|
||||
"on",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_system_dot():
|
||||
line = "hub.system."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"name",
|
||||
"reset_reason",
|
||||
"set_stop_button",
|
||||
"shutdown",
|
||||
]
|
||||
@@ -0,0 +1,138 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2022 The Pybricks Authors
|
||||
|
||||
"""
|
||||
Tests for correct code completion of the PrimeHub class.
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
from pybricks_jedi import CompletionItem, complete
|
||||
|
||||
IMPORT = "from pybricks.hubs import PrimeHub"
|
||||
CREATE_INSTANCE = "hub = PrimeHub()"
|
||||
|
||||
|
||||
def _create_snippet(line: str) -> str:
|
||||
"""
|
||||
Creates a code snippet::
|
||||
|
||||
from pybricks.hubs import PrimeHub
|
||||
hub = PrimeHub()
|
||||
{line}
|
||||
|
||||
Args:
|
||||
line: The value substituted for ``{line}``
|
||||
"""
|
||||
return "\n".join((IMPORT, CREATE_INSTANCE, line))
|
||||
|
||||
|
||||
def test_hub_dot():
|
||||
line = "hub."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"battery",
|
||||
"buttons",
|
||||
"charger",
|
||||
"display",
|
||||
"imu",
|
||||
"light",
|
||||
"speaker",
|
||||
"system",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_battery_dot():
|
||||
line = "hub.battery."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"current",
|
||||
"voltage",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_buttons_dot():
|
||||
line = "hub.buttons."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"pressed",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_charger_dot():
|
||||
line = "hub.charger."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"connected",
|
||||
"current",
|
||||
"status",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_display_dot():
|
||||
line = "hub.display."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"animate",
|
||||
"char",
|
||||
"image",
|
||||
"number",
|
||||
"off",
|
||||
"orientation",
|
||||
"pixel",
|
||||
"text",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_imu_dot():
|
||||
line = "hub.imu."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"acceleration",
|
||||
"angular_velocity",
|
||||
"heading",
|
||||
"reset_heading",
|
||||
"tilt",
|
||||
"up",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_light_dot():
|
||||
line = "hub.light."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"animate",
|
||||
"blink",
|
||||
"off",
|
||||
"on",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_speaker_dot():
|
||||
line = "hub.speaker."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"beep",
|
||||
"play_notes",
|
||||
"volume",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_system_dot():
|
||||
line = "hub.system."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"name",
|
||||
"reset_reason",
|
||||
"set_stop_button",
|
||||
"shutdown",
|
||||
]
|
||||
@@ -0,0 +1,97 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2022 The Pybricks Authors
|
||||
|
||||
"""
|
||||
Tests for correct code completion of the TechnicHub class.
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
from pybricks_jedi import CompletionItem, complete
|
||||
|
||||
IMPORT = "from pybricks.hubs import TechnicHub"
|
||||
CREATE_INSTANCE = "hub = TechnicHub()"
|
||||
|
||||
|
||||
def _create_snippet(line: str) -> str:
|
||||
"""
|
||||
Creates a code snippet::
|
||||
|
||||
from pybricks.hubs import TechnicHub
|
||||
hub = TechnicHub()
|
||||
{line}
|
||||
|
||||
Args:
|
||||
line: The value substituted for ``{line}``
|
||||
"""
|
||||
return "\n".join((IMPORT, CREATE_INSTANCE, line))
|
||||
|
||||
|
||||
def test_hub_dot():
|
||||
line = "hub."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"battery",
|
||||
"button",
|
||||
"imu",
|
||||
"light",
|
||||
"system",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_battery_dot():
|
||||
line = "hub.battery."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"current",
|
||||
"voltage",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_button_dot():
|
||||
line = "hub.button."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"pressed",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_imu_dot():
|
||||
line = "hub.imu."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"acceleration",
|
||||
"angular_velocity",
|
||||
"heading",
|
||||
"reset_heading",
|
||||
"tilt",
|
||||
"up",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_light_dot():
|
||||
line = "hub.light."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"animate",
|
||||
"blink",
|
||||
"off",
|
||||
"on",
|
||||
]
|
||||
|
||||
|
||||
def test_hub_dot_system_dot():
|
||||
line = "hub.system."
|
||||
code = _create_snippet(line)
|
||||
completions: list[CompletionItem] = json.loads(complete(code, 3, len(line) + 1))
|
||||
assert [c["insertText"] for c in completions] == [
|
||||
"name",
|
||||
"reset_reason",
|
||||
"set_stop_button",
|
||||
"shutdown",
|
||||
]
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "pybricks"
|
||||
version = "3.2.0b1"
|
||||
version = "3.2.0b1-r2"
|
||||
description = "Documentation and user-API stubs for Pybricks MicroPython"
|
||||
authors = ["The Pybricks Authors <dev@pybricks.com>"]
|
||||
maintainers = ["Laurens Valk <laurens@pybricks.com>", "David Lechner <david@pybricks.com>" ]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
[flake8]
|
||||
exclude = .venv/,*.pyi
|
||||
exclude = .venv/,*.pyi,jedi/
|
||||
max-line-length = 88
|
||||
ignore = E203,W503
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
version: Tuple[str, str, str] = (
|
||||
"hub",
|
||||
"3.2.0b1",
|
||||
"v3.2.0b1-GIT_HASH on DATE",
|
||||
)
|
||||
+147
-66
@@ -4,20 +4,23 @@
|
||||
"""Generic cross-platform module for typical devices like lights, displays,
|
||||
speakers, and batteries."""
|
||||
|
||||
from .parameters import Direction, Stop, Button, Port, Color, Side
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Union, Iterable, overload, Optional, Tuple, Collection, TYPE_CHECKING
|
||||
|
||||
from .geometry import Matrix, Axis
|
||||
from .parameters import Direction, Stop, Button, Port, Color, Side
|
||||
|
||||
from typing import Union, Iterable, overload, Optional, Tuple, Collection
|
||||
|
||||
|
||||
Number = Union[int, float]
|
||||
if TYPE_CHECKING:
|
||||
from .parameters import Number
|
||||
|
||||
|
||||
class System:
|
||||
"""System control actions for a hub."""
|
||||
|
||||
def set_stop_button(self, button: Union[Button, Iterable[Button]]) -> None:
|
||||
def set_stop_button(
|
||||
self, button: Optional[Union[Button, Iterable[Button]]]
|
||||
) -> None:
|
||||
"""
|
||||
set_stop_button(button)
|
||||
|
||||
@@ -33,13 +36,11 @@ class System:
|
||||
or a tuple of multiple buttons. Choose ``None`` to disable the
|
||||
stop button altogether.
|
||||
"""
|
||||
pass
|
||||
|
||||
def shutdown(self) -> None:
|
||||
"""shutdown()
|
||||
|
||||
Stops your program and shuts the hub down."""
|
||||
pass
|
||||
|
||||
def reset_reason(self) -> int:
|
||||
"""reset_reason() -> int
|
||||
@@ -56,7 +57,6 @@ class System:
|
||||
crashed due to a watchdog timeout, which indicates a firmware
|
||||
issue.
|
||||
"""
|
||||
pass
|
||||
|
||||
def name(self) -> str:
|
||||
"""name() -> str
|
||||
@@ -67,7 +67,6 @@ class System:
|
||||
Returns:
|
||||
The hub name.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class DCMotor:
|
||||
@@ -75,14 +74,13 @@ class DCMotor:
|
||||
as train motors."""
|
||||
|
||||
def __init__(self, port: Port, positive_direction: Direction = Direction.CLOCKWISE):
|
||||
"""DCMotor(port, positive_direction=Direction.CLOCKWISE)
|
||||
"""__init__(port, positive_direction=Direction.CLOCKWISE)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the motor is connected.
|
||||
positive_direction (Direction): Which direction the motor should
|
||||
turn when you give a positive duty cycle value.
|
||||
"""
|
||||
pass
|
||||
|
||||
def dc(self, duty: Number) -> None:
|
||||
"""dc(duty)
|
||||
@@ -92,7 +90,6 @@ class DCMotor:
|
||||
Arguments:
|
||||
duty (Number, %): The duty cycle (-100.0 to 100).
|
||||
"""
|
||||
pass
|
||||
|
||||
def stop(self) -> None:
|
||||
"""stop()
|
||||
@@ -100,7 +97,6 @@ class DCMotor:
|
||||
Stops the motor and lets it spin freely.
|
||||
|
||||
The motor gradually stops due to friction."""
|
||||
pass
|
||||
|
||||
def brake(self) -> None:
|
||||
"""brake()
|
||||
@@ -109,7 +105,6 @@ class DCMotor:
|
||||
|
||||
The motor stops due to friction, plus the voltage that
|
||||
is generated while the motor is still moving."""
|
||||
pass
|
||||
|
||||
@overload
|
||||
def settings(self, max_voltage: Optional[int] = None) -> None:
|
||||
@@ -131,7 +126,6 @@ class DCMotor:
|
||||
max_voltage (Number, mV):
|
||||
Maximum voltage applied to the motor during all motor commands.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Control:
|
||||
@@ -177,7 +171,6 @@ class Control:
|
||||
torque (:ref:`torque`):
|
||||
Maximum feedback torque during control.
|
||||
"""
|
||||
pass
|
||||
|
||||
@overload
|
||||
def pid(self) -> Tuple[int, int, int, None, int]:
|
||||
@@ -215,7 +208,6 @@ class Control:
|
||||
integral_rate (Number, deg/s or Number, mm/s): Maximum rate at
|
||||
which the error integral is allowed to grow.
|
||||
"""
|
||||
pass
|
||||
|
||||
@overload
|
||||
def target_tolerances(self) -> Tuple[int, int]:
|
||||
@@ -242,7 +234,6 @@ class Control:
|
||||
deviation from the target before motion is considered
|
||||
complete.
|
||||
"""
|
||||
pass
|
||||
|
||||
@overload
|
||||
def stall_tolerances(self) -> Tuple[int, int]:
|
||||
@@ -269,7 +260,6 @@ class Control:
|
||||
time (Number, ms): How long the controller has to be below this
|
||||
minimum ``speed`` before we say it is stalled.
|
||||
"""
|
||||
pass
|
||||
|
||||
def stalled(self) -> bool:
|
||||
"""stalled() -> bool
|
||||
@@ -282,7 +272,6 @@ class Control:
|
||||
Returns:
|
||||
``True`` if the controller is stalled, ``False`` if not.
|
||||
"""
|
||||
pass
|
||||
|
||||
def done(self) -> bool:
|
||||
"""done() -> bool
|
||||
@@ -292,7 +281,6 @@ class Control:
|
||||
Returns:
|
||||
``True`` if the command is done, ``False`` if not.
|
||||
"""
|
||||
pass
|
||||
|
||||
def load(self) -> int:
|
||||
"""load() -> int: mNm
|
||||
@@ -306,7 +294,6 @@ class Control:
|
||||
Returns:
|
||||
The load torque. It returns 0 if control is not active.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Motor(DCMotor):
|
||||
@@ -325,7 +312,7 @@ class Motor(DCMotor):
|
||||
gears: Optional[Union[Collection[int], Collection[Collection[int]]]] = None,
|
||||
reset_angle: bool = True,
|
||||
):
|
||||
"""Motor(port, positive_direction=Direction.CLOCKWISE, gears=None, reset_angle=True)
|
||||
"""__init__(port, positive_direction=Direction.CLOCKWISE, gears=None, reset_angle=True)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the motor is connected.
|
||||
@@ -349,7 +336,6 @@ class Motor(DCMotor):
|
||||
current value, so your program knows where it left off last
|
||||
time.
|
||||
"""
|
||||
pass
|
||||
|
||||
def angle(self) -> int:
|
||||
"""angle() -> int: deg
|
||||
@@ -359,7 +345,6 @@ class Motor(DCMotor):
|
||||
Returns:
|
||||
Motor angle.
|
||||
"""
|
||||
pass
|
||||
|
||||
def speed(self) -> int:
|
||||
"""speed() -> int: deg/s
|
||||
@@ -370,7 +355,6 @@ class Motor(DCMotor):
|
||||
Motor speed.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def reset_angle(self, angle: Number) -> None:
|
||||
"""
|
||||
@@ -381,13 +365,11 @@ class Motor(DCMotor):
|
||||
Arguments:
|
||||
angle (Number, deg): Value to which the angle should be reset.
|
||||
"""
|
||||
pass
|
||||
|
||||
def hold(self) -> None:
|
||||
"""hold()
|
||||
|
||||
Stops the motor and actively holds it at its current angle."""
|
||||
pass
|
||||
|
||||
def run(self, speed: Number) -> None:
|
||||
"""run(speed)
|
||||
@@ -400,7 +382,6 @@ class Motor(DCMotor):
|
||||
Arguments:
|
||||
speed (Number, deg/s): Speed of the motor.
|
||||
"""
|
||||
pass
|
||||
|
||||
def run_time(
|
||||
self, speed: Number, time: Number, then: Stop = Stop.HOLD, wait: bool = True
|
||||
@@ -420,7 +401,6 @@ class Motor(DCMotor):
|
||||
wait (bool): Wait for the maneuver to complete before continuing
|
||||
with the rest of the program.
|
||||
"""
|
||||
pass
|
||||
|
||||
def run_angle(
|
||||
self,
|
||||
@@ -441,7 +421,6 @@ class Motor(DCMotor):
|
||||
wait (bool): Wait for the maneuver to complete before continuing
|
||||
with the rest of the program.
|
||||
"""
|
||||
pass
|
||||
|
||||
def run_target(
|
||||
self,
|
||||
@@ -464,7 +443,6 @@ class Motor(DCMotor):
|
||||
wait (bool): Wait for the motor to reach the target
|
||||
before continuing with the rest of the program.
|
||||
"""
|
||||
pass
|
||||
|
||||
def run_until_stalled(
|
||||
self,
|
||||
@@ -488,7 +466,6 @@ class Motor(DCMotor):
|
||||
Returns:
|
||||
Angle at which the motor becomes stalled.
|
||||
"""
|
||||
pass
|
||||
|
||||
def track_target(self, target_angle: Number) -> None:
|
||||
"""track_target(target_angle)
|
||||
@@ -502,7 +479,6 @@ class Motor(DCMotor):
|
||||
target_angle (Number, deg): Target angle that the motor should
|
||||
rotate to.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Speaker:
|
||||
@@ -527,7 +503,6 @@ class Speaker:
|
||||
Arguments:
|
||||
volume (Number, %): Volume of the speaker in the 0-100 range.
|
||||
"""
|
||||
pass
|
||||
|
||||
def beep(self, frequency: Number = 500, duration: Number = 100) -> None:
|
||||
"""beep(frequency=500, duration=100)
|
||||
@@ -542,7 +517,6 @@ class Speaker:
|
||||
than 0, then the method returns immediately and the frequency
|
||||
play continues to play indefinitely.
|
||||
"""
|
||||
pass
|
||||
|
||||
def play_notes(self, notes: Iterable[str], tempo: Number = 120) -> None:
|
||||
"""play_notes(notes, tempo=120)
|
||||
@@ -577,7 +551,6 @@ class Speaker:
|
||||
tempo (int):
|
||||
Beats per minute. A quarter note is one beat.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class ColorLight:
|
||||
@@ -591,13 +564,11 @@ class ColorLight:
|
||||
Arguments:
|
||||
color (Color): Color of the light.
|
||||
"""
|
||||
pass
|
||||
|
||||
def off(self) -> None:
|
||||
"""off()
|
||||
|
||||
Turns off the light."""
|
||||
pass
|
||||
|
||||
def blink(self, color: Color, durations: Collection[int]) -> None:
|
||||
"""blink(color, durations)
|
||||
@@ -645,7 +616,6 @@ class LightArray:
|
||||
Arguments:
|
||||
n (int): Number of lights
|
||||
"""
|
||||
pass
|
||||
|
||||
def on(self, brightness: Union[int, Collection[int]]) -> None:
|
||||
"""on(brightness)
|
||||
@@ -658,13 +628,11 @@ class LightArray:
|
||||
If you give just one brightness value, all lights get that
|
||||
brightness.
|
||||
"""
|
||||
pass
|
||||
|
||||
def off(self) -> None:
|
||||
"""off()
|
||||
|
||||
Turns off all the lights."""
|
||||
pass
|
||||
|
||||
|
||||
class LightMatrix:
|
||||
@@ -679,7 +647,6 @@ class LightMatrix:
|
||||
rows (int): Number of rows in the grid
|
||||
columns (int): Number of columns in the grid
|
||||
"""
|
||||
pass
|
||||
|
||||
def orientation(self, up: Side) -> None:
|
||||
"""orientation(up)
|
||||
@@ -694,7 +661,6 @@ class LightMatrix:
|
||||
design. Choose ``Side.TOP``, ``Side.LEFT``, ``Side.RIGHT``,
|
||||
or ``Side.BOTTOM``.
|
||||
"""
|
||||
pass
|
||||
|
||||
def image(self, matrix: Matrix) -> None:
|
||||
"""image(matrix)
|
||||
@@ -706,7 +672,6 @@ class LightMatrix:
|
||||
matrix (Matrix): Matrix of intensities (:ref:`brightness`). A 2D
|
||||
list is also accepted.
|
||||
"""
|
||||
pass
|
||||
|
||||
def animate(self, matrices: Collection[Matrix], interval: Number) -> None:
|
||||
"""animate(matrices, interval)
|
||||
@@ -722,7 +687,6 @@ class LightMatrix:
|
||||
:class:`Matrix <pybricks.geometry.Matrix>` of intensities.
|
||||
interval (Number, ms): Time to display each image in the list.
|
||||
"""
|
||||
pass
|
||||
|
||||
def pixel(self, row: int, column: int, brightness: Number = 100) -> None:
|
||||
"""pixel(row, column, brightness=100)
|
||||
@@ -734,13 +698,11 @@ class LightMatrix:
|
||||
column (int): Horizontal grid index, starting at 0 from the left.
|
||||
brightness (:ref:`brightness`): Brightness of the pixel.
|
||||
"""
|
||||
pass
|
||||
|
||||
def off(self) -> None:
|
||||
"""off()
|
||||
|
||||
Turns off all the pixels."""
|
||||
pass
|
||||
|
||||
def number(self, number: Number) -> None:
|
||||
"""number(number)
|
||||
@@ -754,7 +716,6 @@ class LightMatrix:
|
||||
Arguments:
|
||||
number (int): The number to be displayed.
|
||||
"""
|
||||
pass
|
||||
|
||||
def char(self, char: str) -> None:
|
||||
"""char(char)
|
||||
@@ -766,7 +727,6 @@ class LightMatrix:
|
||||
Arguments:
|
||||
character (str): The character or symbol to be displayed.
|
||||
"""
|
||||
pass
|
||||
|
||||
def text(self, text: str, on: Number = 500, off: Number = 50) -> None:
|
||||
"""text(text, on=500, off=50)
|
||||
@@ -781,14 +741,13 @@ class LightMatrix:
|
||||
off (Number, ms): For how long the display is off between
|
||||
characters.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Keypad:
|
||||
"""Get status of buttons on a keypad layout."""
|
||||
|
||||
def __init__(self, active_buttons):
|
||||
pass
|
||||
...
|
||||
|
||||
def pressed(self) -> Tuple[Button]:
|
||||
"""pressed() -> Tuple[Button]
|
||||
@@ -798,7 +757,6 @@ class Keypad:
|
||||
Returns:
|
||||
Tuple of pressed buttons.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Battery:
|
||||
@@ -812,7 +770,6 @@ class Battery:
|
||||
Returns:
|
||||
Battery voltage.
|
||||
"""
|
||||
pass
|
||||
|
||||
def current(self) -> int:
|
||||
"""current() -> int: mA
|
||||
@@ -822,7 +779,6 @@ class Battery:
|
||||
Returns:
|
||||
Battery current.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Charger:
|
||||
@@ -852,7 +808,6 @@ class Charger:
|
||||
Returns:
|
||||
Status value.
|
||||
"""
|
||||
pass
|
||||
|
||||
def current(self) -> int:
|
||||
"""current() -> int: mA
|
||||
@@ -862,7 +817,6 @@ class Charger:
|
||||
Returns:
|
||||
Charging current.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class SimpleAccelerometer:
|
||||
@@ -876,7 +830,6 @@ class SimpleAccelerometer:
|
||||
Returns:
|
||||
Acceleration along all three axes.
|
||||
"""
|
||||
pass
|
||||
|
||||
def up(self) -> Side:
|
||||
"""up() -> Side
|
||||
@@ -887,7 +840,6 @@ class SimpleAccelerometer:
|
||||
``Side.TOP``, ``Side.BOTTOM``, ``Side.LEFT``, ``Side.RIGHT``,
|
||||
``Side.FRONT`` or ``Side.BACK``.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Accelerometer(SimpleAccelerometer):
|
||||
@@ -917,7 +869,6 @@ class Accelerometer(SimpleAccelerometer):
|
||||
Acceleration along the specified axis. If you specify no axis,
|
||||
this returns a vector of accelerations along all axes.
|
||||
"""
|
||||
pass
|
||||
|
||||
def tilt(self) -> Tuple[int, int]:
|
||||
"""tilt() -> Tuple[int, int]
|
||||
@@ -932,7 +883,6 @@ class Accelerometer(SimpleAccelerometer):
|
||||
Returns:
|
||||
Tuple of pitch and roll angles.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class IMU(Accelerometer):
|
||||
@@ -952,10 +902,9 @@ class IMU(Accelerometer):
|
||||
Heading angle relative to starting orientation.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def reset_heading(self, angle: Number) -> None:
|
||||
"""reset_heading(angle: Number)
|
||||
"""reset_heading(angle)
|
||||
|
||||
Resets the accumulated heading angle of the robot.
|
||||
|
||||
@@ -964,7 +913,6 @@ class IMU(Accelerometer):
|
||||
Arguments:
|
||||
angle (Number, deg): Value to which the heading should be reset.
|
||||
"""
|
||||
pass
|
||||
|
||||
@overload
|
||||
def angular_velocity(self) -> Matrix:
|
||||
@@ -989,4 +937,137 @@ class IMU(Accelerometer):
|
||||
Angular velocity along the specified axis. If you specify no axis,
|
||||
this returns a vector of accelerations along all axes.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class CommonColorSensor:
|
||||
"""Generic color sensor that supports Pybricks color calibration."""
|
||||
|
||||
def __init__(self, port: Port):
|
||||
"""__init__(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
|
||||
def color(self) -> Color:
|
||||
"""color() -> Color
|
||||
|
||||
Scans the color of a surface.
|
||||
|
||||
You choose which colors are detected using the
|
||||
``detectable_colors()`` method. By default, it detects
|
||||
``Color.RED``, ``Color.YELLOW``, ``Color.GREEN``, ``Color.BLUE``,
|
||||
``Color.WHITE``, or ``Color.NONE``.
|
||||
|
||||
Returns:
|
||||
Detected color.
|
||||
"""
|
||||
|
||||
def hsv(self) -> Color:
|
||||
"""hsv() -> Color
|
||||
|
||||
Scans the color of a surface.
|
||||
|
||||
This method is similar to ``color()``, but it gives the full range
|
||||
of hue, saturation and brightness values, instead of rounding it to the
|
||||
nearest detectable color.
|
||||
|
||||
Returns:
|
||||
Measured color. The color is described by a hue (0--359), a
|
||||
saturation (0--100), and a brightness value (0--100).
|
||||
"""
|
||||
|
||||
def ambient(self) -> int:
|
||||
"""ambient() -> int: %
|
||||
|
||||
Measures the ambient light intensity.
|
||||
|
||||
Returns:
|
||||
Ambient light intensity, ranging from 0% (dark)
|
||||
to 100% (bright).
|
||||
"""
|
||||
|
||||
def reflection(self) -> int:
|
||||
"""reflection() -> int: %
|
||||
|
||||
Measures how much a surface reflects the light emitted by the
|
||||
sensor.
|
||||
|
||||
Returns:
|
||||
Measured reflection, ranging from 0% (no reflection) to
|
||||
100% (high reflection).
|
||||
"""
|
||||
|
||||
@overload
|
||||
def detectable_colors(self, colors: Collection[Color]) -> None:
|
||||
...
|
||||
|
||||
@overload
|
||||
def detectable_colors(self) -> Tuple[Color]:
|
||||
...
|
||||
|
||||
def detectable_colors(self, *args):
|
||||
"""
|
||||
detectable_colors(colors)
|
||||
detectable_colors() -> Tuple[Color]
|
||||
|
||||
Configures which colors the ``color()`` method should detect.
|
||||
|
||||
Specify only colors that you wish to detect in your application.
|
||||
This way, the full-color measurements are rounded to the nearest
|
||||
desired color, and other colors are ignored. This improves reliability.
|
||||
|
||||
If you give no arguments, the currently chosen colors will be returned
|
||||
as a tuple.
|
||||
|
||||
Arguments:
|
||||
colors (tuple): Tuple of :class:`Color <.parameters.Color>`
|
||||
objects: the colors that you want to detect. You can pick
|
||||
standard colors such as ``Color.MAGENTA``, or provide your
|
||||
own colors like ``Color(h=348, s=96, v=40)`` for even
|
||||
better results. You measure your own colors with the
|
||||
``hsv()`` method.
|
||||
"""
|
||||
|
||||
|
||||
class AmbientColorSensor(CommonColorSensor):
|
||||
"""Like CommonColorSensor, but also detects ambient colors when the sensor
|
||||
light is turned off"""
|
||||
|
||||
def color(self, surface: bool = True) -> Optional[Color]:
|
||||
"""color(surface=True) -> Color
|
||||
|
||||
Scans the color of a surface or an external light source.
|
||||
|
||||
You choose which colors are detected using the
|
||||
``detectable_colors()`` method. By default, it detects
|
||||
``Color.RED``, ``Color.YELLOW``, ``Color.GREEN``, ``Color.BLUE``,
|
||||
``Color.WHITE``, or ``Color.NONE``.
|
||||
|
||||
Arguments:
|
||||
surface (bool): Choose ``true`` to scan the color of objects
|
||||
and surfaces. Choose ``false`` to scan the color of
|
||||
screens and other external light sources.
|
||||
|
||||
Returns:
|
||||
Detected color.`
|
||||
"""
|
||||
|
||||
def hsv(self, surface: bool = True) -> Color:
|
||||
"""hsv(surface=True) -> Color
|
||||
|
||||
Scans the color of a surface or an external light source.
|
||||
|
||||
This method is similar to ``color()``, but it gives the full range
|
||||
of hue, saturation and brightness values, instead of rounding it to the
|
||||
nearest detectable color.
|
||||
|
||||
Arguments:
|
||||
surface (bool): Choose ``true`` to scan the color of objects
|
||||
and surfaces. Choose ``false`` to scan the color of
|
||||
screens and other external light sources.
|
||||
|
||||
Returns:
|
||||
Measured color. The color is described by a hue (0--359), a
|
||||
saturation (0--100), and a brightness value (0--100).
|
||||
"""
|
||||
|
||||
@@ -1,26 +1,33 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2018-2021 The Pybricks Authors
|
||||
|
||||
from typing import Iterable, Union, Optional
|
||||
|
||||
from ..media.ev3dev import SoundFile
|
||||
|
||||
|
||||
class Speaker:
|
||||
"""Plays beeps and sounds using a speaker."""
|
||||
|
||||
def beep(self, frequency=500, duration=100):
|
||||
"""Play a beep/tone.
|
||||
def beep(self, frequency: int = 500, duration: int = 100) -> None:
|
||||
"""beep(frequency=500, duration=100)
|
||||
|
||||
Play a beep/tone.
|
||||
|
||||
Arguments:
|
||||
frequency (:ref:`frequency`):
|
||||
Frequency of the beep. Frequencies below 100
|
||||
are treated as 100.
|
||||
duration (:ref:`time`):
|
||||
Duration of the beep. If the duration is less
|
||||
than 0, then the method returns immediately and the frequency
|
||||
play continues to play indefinitely.
|
||||
frequency (Number, Hz):
|
||||
Frequency of the beep. Frequencies below 100 Hz are treated as
|
||||
100 Hz.
|
||||
duration (Number, ms):
|
||||
Duration of the beep. If the duration is less than 0, then the
|
||||
method returns immediately and the frequency play continues to
|
||||
play indefinitely.
|
||||
"""
|
||||
pass
|
||||
|
||||
def play_notes(self, notes, tempo=120):
|
||||
"""Plays a sequence of musical notes. For example:
|
||||
def play_notes(self, notes: Iterable[str], tempo: int = 120) -> None:
|
||||
"""play_notes(notes, tempo=120)
|
||||
|
||||
Plays a sequence of musical notes. For example:
|
||||
``['C4/4', 'C4/4', 'G4/4', 'G4/4']``.
|
||||
|
||||
Each note is a string with the following format:
|
||||
@@ -50,20 +57,21 @@ class Speaker:
|
||||
tempo (int):
|
||||
Beats per minute. A quarter note is one beat.
|
||||
"""
|
||||
pass
|
||||
|
||||
def play_file(self, file):
|
||||
"""Plays a sound file.
|
||||
def play_file(self, file_name: Union[SoundFile, str]) -> None:
|
||||
"""play_file(file_name)
|
||||
|
||||
Plays a sound file.
|
||||
|
||||
Arguments:
|
||||
file (str):
|
||||
Path to the sound file, including the file extension.
|
||||
"""
|
||||
|
||||
pass
|
||||
def say(self, text: str) -> None:
|
||||
"""say(text)
|
||||
|
||||
def say(self, text):
|
||||
"""Says a given text string.
|
||||
Says a given text string.
|
||||
|
||||
You can configure the language and voice of the text using
|
||||
:meth:`.set_speech_options`.
|
||||
@@ -72,10 +80,16 @@ class Speaker:
|
||||
text (str): What to say.
|
||||
"""
|
||||
|
||||
pass
|
||||
def set_speech_options(
|
||||
self,
|
||||
language: Optional[str] = None,
|
||||
voice: Optional[str] = None,
|
||||
speed: Optional[int] = None,
|
||||
pitch: Optional[int] = None,
|
||||
):
|
||||
"""set_speech_options(language, voice, speed, pitch)
|
||||
|
||||
def set_speech_options(self, language=None, voice=None, speed=None, pitch=None):
|
||||
"""Configures speech settings used by the :meth:`.say` method.
|
||||
Configures speech settings used by the :meth:`.say` method.
|
||||
|
||||
Any option that is set to ``None`` will not be changed. If an option
|
||||
is set to an invalid value :meth:`.say` will use the default value
|
||||
@@ -95,13 +109,14 @@ class Speaker:
|
||||
Pitch (0 to 99). Higher numbers make the voice higher pitched
|
||||
and lower numbers make the voice lower pitched.
|
||||
"""
|
||||
pass
|
||||
|
||||
def set_volume(self, volume, which="_all_"):
|
||||
"""Sets the speaker volume.
|
||||
def set_volume(self, volume: int, which: str = "_all_") -> None:
|
||||
"""set_volume(volume, which="_all_")
|
||||
|
||||
Sets the speaker volume.
|
||||
|
||||
Arguments:
|
||||
volume (:ref:`percentage`):
|
||||
volume (Number, %):
|
||||
Volume of the speaker.
|
||||
which (str):
|
||||
Which volume to set. ``'Beep'`` sets the volume for
|
||||
@@ -109,4 +124,3 @@ class Speaker:
|
||||
volume for :meth:`.play_file` and :meth:`.say`. ``'_all_'``
|
||||
sets both at the same time.
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2020-2021 The Pybricks Authors
|
||||
|
||||
from typing import Iterable, Optional, Union
|
||||
|
||||
from pybricks.media.ev3dev import SoundFile
|
||||
|
||||
class Speaker:
|
||||
def beep(self, frequency: int = 500, duration: int = 100) -> None: ...
|
||||
def play_notes(self, notes: Iterable[str], tempo: int = 120) -> None: ...
|
||||
def play_file(self, file_name: Union[SoundFile, str]) -> None: ...
|
||||
def say(self, text: str) -> None: ...
|
||||
def set_speech_options(
|
||||
self,
|
||||
language: Optional[str] = None,
|
||||
voice: Optional[str] = None,
|
||||
speed: Optional[int] = None,
|
||||
pitch: Optional[int] = None,
|
||||
): ...
|
||||
def set_volume(self, volume: int, which: str = "_all_") -> None: ...
|
||||
+20
-32
@@ -3,26 +3,30 @@
|
||||
|
||||
"""LEGO® MINDSTORMS® EV3 motors and sensors."""
|
||||
|
||||
from .parameters import Direction, Port, Color, Button
|
||||
from ._common import Motor as _Motor
|
||||
|
||||
from typing import Optional, Tuple, List
|
||||
|
||||
from . import _common
|
||||
from .parameters import (
|
||||
Button as _Button,
|
||||
Color as _Color,
|
||||
Direction as _Direction,
|
||||
Port as _Port,
|
||||
)
|
||||
|
||||
class Motor(_Motor):
|
||||
pass
|
||||
|
||||
class Motor(_common.Motor):
|
||||
"""LEGO® MINDSTORMS® EV3 Motor."""
|
||||
|
||||
|
||||
class TouchSensor:
|
||||
"""LEGO® MINDSTORMS® EV3 Touch Sensor."""
|
||||
|
||||
def __init__(self, port: Port):
|
||||
def __init__(self, port: _Port):
|
||||
"""TouchSensor(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def pressed(self) -> bool:
|
||||
"""pressed() -> bool
|
||||
@@ -33,21 +37,19 @@ class TouchSensor:
|
||||
``True`` if the sensor is pressed, ``False`` if it is
|
||||
not pressed.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class ColorSensor:
|
||||
"""LEGO® MINDSTORMS® EV3 Color Sensor."""
|
||||
|
||||
def __init__(self, port: Port):
|
||||
def __init__(self, port: _Port):
|
||||
"""ColorSensor(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def color(self) -> Optional[Color]:
|
||||
def color(self) -> Optional[_Color]:
|
||||
"""color() -> Color
|
||||
|
||||
Measures the color of a surface.
|
||||
@@ -58,7 +60,6 @@ class ColorSensor:
|
||||
or ``None`` if no color is detected.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def ambient(self) -> int:
|
||||
"""ambient() -> int: %
|
||||
@@ -69,7 +70,6 @@ class ColorSensor:
|
||||
Ambient light intensity, ranging from 0% (dark)
|
||||
to 100% (bright).
|
||||
"""
|
||||
pass
|
||||
|
||||
def reflection(self) -> int:
|
||||
"""reflection() -> int: %
|
||||
@@ -81,7 +81,6 @@ class ColorSensor:
|
||||
100% (high reflection).
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def rgb(self) -> Tuple[int, int, int]:
|
||||
"""rgb() -> Tuple[int, int, int]
|
||||
@@ -93,20 +92,18 @@ class ColorSensor:
|
||||
Tuple of reflections for red, green, and blue light, each
|
||||
ranging from 0.0% (no reflection) to 100.0% (high reflection).
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class InfraredSensor:
|
||||
"""LEGO® MINDSTORMS® EV3 Infrared Sensor and Beacon."""
|
||||
|
||||
def __init__(self, port: Port):
|
||||
def __init__(self, port: _Port):
|
||||
"""InfraredSensor(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def distance(self) -> int:
|
||||
"""distance() -> int: %
|
||||
@@ -119,7 +116,6 @@ class InfraredSensor:
|
||||
to 100% (farthest).
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def beacon(self, channel: int) -> Tuple[Optional[int], Optional[int]]:
|
||||
"""
|
||||
@@ -137,9 +133,8 @@ class InfraredSensor:
|
||||
(-75 to 75 degrees) between remote and infrared sensor or
|
||||
a tuple of (``None``, ``None``) if no remote is detected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def buttons(self, channel: int) -> List[Button]:
|
||||
def buttons(self, channel: int) -> List[_Button]:
|
||||
"""buttons(channel) -> List[Button]
|
||||
|
||||
Checks which buttons on the infrared remote are pressed.
|
||||
@@ -154,9 +149,8 @@ class InfraredSensor:
|
||||
List of pressed buttons on the remote on the selected channel.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def keypad(self) -> List[Button]:
|
||||
def keypad(self) -> List[_Button]:
|
||||
"""keypad() -> List[Button]
|
||||
|
||||
Checks which buttons on the infrared remote are pressed.
|
||||
@@ -169,13 +163,14 @@ class InfraredSensor:
|
||||
Returns:
|
||||
List of pressed buttons.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class GyroSensor:
|
||||
"""LEGO® MINDSTORMS® EV3 Gyro Sensor."""
|
||||
|
||||
def __init__(self, port: Port, positive_direction: Direction = Direction.CLOCKWISE):
|
||||
def __init__(
|
||||
self, port: _Port, positive_direction: _Direction = _Direction.CLOCKWISE
|
||||
):
|
||||
"""GyroSensor(port)
|
||||
|
||||
Arguments:
|
||||
@@ -185,7 +180,6 @@ class GyroSensor:
|
||||
of the sensor.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def speed(self) -> int:
|
||||
"""speed() -> int: deg/s
|
||||
@@ -196,7 +190,6 @@ class GyroSensor:
|
||||
Angular velocity.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def angle(self) -> int:
|
||||
"""angle() -> int: deg
|
||||
@@ -207,7 +200,6 @@ class GyroSensor:
|
||||
Rotation angle.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def reset_angle(self, angle: int) -> None:
|
||||
"""reset_angle(angle)
|
||||
@@ -217,20 +209,18 @@ class GyroSensor:
|
||||
Arguments:
|
||||
angle (Number, deg): Value to which the angle should be reset.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class UltrasonicSensor:
|
||||
"""LEGO® MINDSTORMS® EV3 Ultrasonic Sensor."""
|
||||
|
||||
def __init__(self, port: Port):
|
||||
def __init__(self, port: _Port):
|
||||
"""UltrasonicSensor(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def distance(self, silent: bool = False) -> int:
|
||||
"""distance(silent=False) -> int: mm
|
||||
@@ -249,7 +239,6 @@ class UltrasonicSensor:
|
||||
Measured distance.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def presence(self) -> bool:
|
||||
"""presence() -> bool
|
||||
@@ -265,4 +254,3 @@ class UltrasonicSensor:
|
||||
``True`` if ultrasonic sounds are detected,
|
||||
``False`` if not.
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -63,14 +63,12 @@ class Matrix:
|
||||
def T(self) -> Matrix:
|
||||
"""Returns a new :class:`.Matrix` that is the transpose of the
|
||||
original."""
|
||||
pass
|
||||
|
||||
@property
|
||||
def shape(self) -> Tuple[int, int]:
|
||||
"""Returns a tuple (``m``, ``n``),
|
||||
where ``m`` is the number of rows and ``n`` is the number of columns.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
@overload
|
||||
@@ -99,7 +97,6 @@ def vector(*args):
|
||||
Returns:
|
||||
A matrix with the shape of a column vector.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Axis:
|
||||
|
||||
+36
-50
@@ -2,18 +2,8 @@
|
||||
# Copyright (c) 2018-2020 The Pybricks Authors
|
||||
|
||||
"""LEGO® Programmable Hubs."""
|
||||
from ._common import (
|
||||
Speaker as _Speaker,
|
||||
Battery as _Battery,
|
||||
ColorLight as _ColorLight,
|
||||
Keypad as _Keypad,
|
||||
LightMatrix as _LightMatrix,
|
||||
IMU as _IMU,
|
||||
Charger as _Charger,
|
||||
System as _System,
|
||||
SimpleAccelerometer as _SimpleAccelerometer,
|
||||
)
|
||||
from .ev3dev._speaker import Speaker as _EV3Speaker
|
||||
from . import _common
|
||||
from .ev3dev import _speaker
|
||||
from .geometry import Axis as _Axis
|
||||
from .media.ev3dev import Image as _Image
|
||||
from .parameters import Button as _Button
|
||||
@@ -24,19 +14,19 @@ class EV3Brick:
|
||||
|
||||
# These class attributes are here for auto-documentation only.
|
||||
# In reality, they are instance attributes created by __init__.
|
||||
buttons = _Keypad(
|
||||
(
|
||||
buttons = _common.Keypad(
|
||||
[
|
||||
_Button.LEFT,
|
||||
_Button.RIGHT,
|
||||
_Button.CENTER,
|
||||
_Button.UP,
|
||||
_Button.DOWN,
|
||||
)
|
||||
]
|
||||
)
|
||||
screen = _Image("_screen_")
|
||||
speaker = _EV3Speaker()
|
||||
battery = _Battery()
|
||||
light = _ColorLight()
|
||||
speaker = _speaker.Speaker()
|
||||
battery = _common.Battery()
|
||||
light = _common.ColorLight()
|
||||
|
||||
|
||||
class MoveHub:
|
||||
@@ -44,11 +34,11 @@ class MoveHub:
|
||||
|
||||
# These class attributes are here for auto-documentation only.
|
||||
# In reality, they are instance attributes created by __init__.
|
||||
battery = _Battery()
|
||||
light = _ColorLight()
|
||||
imu = _SimpleAccelerometer()
|
||||
system = _System()
|
||||
button = _Keypad((_Button.CENTER,))
|
||||
battery = _common.Battery()
|
||||
light = _common.ColorLight()
|
||||
imu = _common.SimpleAccelerometer()
|
||||
system = _common.System()
|
||||
button = _common.Keypad([_Button.CENTER])
|
||||
|
||||
|
||||
class CityHub:
|
||||
@@ -56,10 +46,10 @@ class CityHub:
|
||||
|
||||
# These class attributes are here for auto-documentation only.
|
||||
# In reality, they are instance attributes created by __init__.
|
||||
battery = _Battery()
|
||||
light = _ColorLight()
|
||||
system = _System()
|
||||
button = _Keypad((_Button.CENTER,))
|
||||
battery = _common.Battery()
|
||||
light = _common.ColorLight()
|
||||
system = _common.System()
|
||||
button = _common.Keypad([_Button.CENTER])
|
||||
|
||||
|
||||
class TechnicHub:
|
||||
@@ -67,14 +57,14 @@ class TechnicHub:
|
||||
|
||||
# These class attributes are here for auto-documentation only.
|
||||
# In reality, they are instance attributes created by __init__.
|
||||
battery = _Battery()
|
||||
light = _ColorLight()
|
||||
imu = _IMU()
|
||||
system = _System()
|
||||
button = _Keypad((_Button.CENTER,))
|
||||
battery = _common.Battery()
|
||||
light = _common.ColorLight()
|
||||
imu = _common.IMU()
|
||||
system = _common.System()
|
||||
button = _common.Keypad([_Button.CENTER])
|
||||
|
||||
def __init__(self, top_side=_Axis.Z, front_side=_Axis.X):
|
||||
"""__init__(top_side=Axis.Z, front_side=Axis.X)
|
||||
def __init__(self, top_side: _Axis = _Axis.Z, front_side: _Axis = _Axis.X):
|
||||
"""TechnicHub(top_side=Axis.Z, front_side=Axis.X)
|
||||
|
||||
Initializes the hub. Optionally, specify how the hub is
|
||||
:ref:`placed in your design <robotframe>` by saying in which
|
||||
@@ -87,7 +77,6 @@ class TechnicHub:
|
||||
front_side (Axis): The axis that passes through the *front side* of
|
||||
the hub.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class PrimeHub:
|
||||
@@ -95,24 +84,24 @@ class PrimeHub:
|
||||
|
||||
# These class attributes are here for auto-documentation only.
|
||||
# In reality, they are instance attributes created by __init__.
|
||||
battery = _Battery()
|
||||
buttons = _Keypad(
|
||||
(
|
||||
battery = _common.Battery()
|
||||
buttons = _common.Keypad(
|
||||
[
|
||||
_Button.LEFT,
|
||||
_Button.RIGHT,
|
||||
_Button.CENTER,
|
||||
_Button.BLUETOOTH,
|
||||
)
|
||||
]
|
||||
)
|
||||
charger = _Charger()
|
||||
light = _ColorLight()
|
||||
display = _LightMatrix(5, 5)
|
||||
speaker = _Speaker()
|
||||
imu = _IMU()
|
||||
system = _System()
|
||||
charger = _common.Charger()
|
||||
light = _common.ColorLight()
|
||||
display = _common.LightMatrix(5, 5)
|
||||
speaker = _common.Speaker()
|
||||
imu = _common.IMU()
|
||||
system = _common.System()
|
||||
|
||||
def __init__(self, top_side=_Axis.Z, front_side=_Axis.X):
|
||||
"""__init__(top_side=Axis.Z, front_side=Axis.X)
|
||||
def __init__(self, top_side: _Axis = _Axis.Z, front_side: _Axis = _Axis.X):
|
||||
"""PrimeHub(top_side=Axis.Z, front_side=Axis.X)
|
||||
|
||||
Initializes the hub. Optionally, specify how the hub is
|
||||
:ref:`placed in your design <robotframe>` by saying in which
|
||||
@@ -125,10 +114,7 @@ class PrimeHub:
|
||||
front_side (Axis): The axis that passes through the *front side* of
|
||||
the hub.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class InventorHub(PrimeHub):
|
||||
"""LEGO® MINDSTORMS Inventor Hub."""
|
||||
|
||||
pass
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2020 The Pybricks Authors
|
||||
|
||||
from ._common import (
|
||||
Battery,
|
||||
ColorLight,
|
||||
Charger,
|
||||
IMU,
|
||||
Keypad,
|
||||
LightMatrix,
|
||||
SimpleAccelerometer,
|
||||
Speaker,
|
||||
System,
|
||||
)
|
||||
from .ev3dev._speaker import Speaker as EV3Speaker
|
||||
from .geometry import Axis
|
||||
from .media.ev3dev import Image
|
||||
|
||||
class EV3Brick:
|
||||
screen: Image
|
||||
speaker: EV3Speaker
|
||||
battery: Battery
|
||||
light: ColorLight
|
||||
buttons = Keypad
|
||||
|
||||
class MoveHub:
|
||||
battery: Battery
|
||||
light: ColorLight
|
||||
system: System
|
||||
imu: SimpleAccelerometer
|
||||
|
||||
class CityHub:
|
||||
battery: Battery
|
||||
light: ColorLight
|
||||
system: System
|
||||
|
||||
class TechnicHub:
|
||||
def __init__(self, top_size: Axis, front_side: Axis): ...
|
||||
battery: Battery
|
||||
light: ColorLight
|
||||
system: System
|
||||
imu: IMU
|
||||
|
||||
class PrimeHub:
|
||||
def __init__(self, top_side: Axis = Axis.Z, front_side: Axis = Axis.X): ...
|
||||
battery: Battery
|
||||
light: ColorLight
|
||||
display: LightMatrix
|
||||
buttons: Keypad
|
||||
speaker: Speaker
|
||||
system: System
|
||||
imu: IMU
|
||||
charger: Charger
|
||||
|
||||
class InventorHub(PrimeHub): ...
|
||||
+133
-102
@@ -3,132 +3,146 @@
|
||||
|
||||
"""Generic input/output devices."""
|
||||
|
||||
from typing import Dict, Tuple, Optional, overload
|
||||
|
||||
from . import _common
|
||||
from .parameters import Port as _Port
|
||||
|
||||
|
||||
class PUPDevice:
|
||||
"""Powered Up motor or sensor."""
|
||||
|
||||
def __init__(self, port):
|
||||
"""
|
||||
def __init__(self, port: _Port):
|
||||
"""PUPDevice(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the device is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def info(self):
|
||||
"""Returns information about the device.
|
||||
def info(self) -> Dict[str, str]:
|
||||
"""info() -> Dict
|
||||
|
||||
Gets information about the device.
|
||||
|
||||
Returns:
|
||||
``dict``: Dictionary with information, such as the device ``id``.
|
||||
Dictionary with information, such as the device ``id``.
|
||||
"""
|
||||
pass
|
||||
|
||||
def read(self, mode):
|
||||
"""Reads values from a given mode.
|
||||
def read(self, mode: int) -> Tuple:
|
||||
"""read(mode) -> Tuple
|
||||
|
||||
Reads values from a given mode.
|
||||
|
||||
Arguments:
|
||||
mode (``int``): Device mode.
|
||||
mode (int): Device mode.
|
||||
|
||||
Returns:
|
||||
``tuple``: Values read from the sensor.
|
||||
Values read from the sensor.
|
||||
"""
|
||||
pass
|
||||
|
||||
def write(self, mode, data):
|
||||
"""Writes values to the sensor. Only selected sensors and modes support
|
||||
def write(self, mode: int, data: Tuple) -> None:
|
||||
"""write(mode, data)
|
||||
|
||||
Writes values to the sensor. Only selected sensors and modes support
|
||||
this.
|
||||
|
||||
Arguments:
|
||||
mode (``int``): Device mode.
|
||||
data (``tuple``): Values to be written.
|
||||
mode (int): Device mode.
|
||||
data (tuple): Values to be written.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class LUMPDevice:
|
||||
"""Devices using the LEGO UART Messaging Protocol."""
|
||||
|
||||
def __init__(self, port):
|
||||
"""
|
||||
def __init__(self, port: _Port):
|
||||
"""LUMPDevice(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the device is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def read(self, mode):
|
||||
"""Reads values from a given mode.
|
||||
def read(self, mode: int) -> Tuple:
|
||||
"""read(mode) -> Tuple
|
||||
|
||||
Reads values from a given mode.
|
||||
|
||||
Arguments:
|
||||
mode (``int``): Device mode.
|
||||
mode (int): Device mode.
|
||||
|
||||
Returns:
|
||||
``tuple``: Values read from the sensor.
|
||||
Values read from the sensor.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class DCMotor(_common.DCMotor):
|
||||
"""DC Motor for LEGO® MINDSTORMS EV3."""
|
||||
|
||||
|
||||
class Ev3devSensor:
|
||||
"""Read values of an ev3dev-compatible sensor."""
|
||||
|
||||
sensor_index = 0
|
||||
sensor_index: int
|
||||
"""Index of the ev3dev sysfs `lego-sensor`_ class."""
|
||||
|
||||
port_index = 0
|
||||
port_index: int
|
||||
"""Index of the ev3dev sysfs `lego-port`_ class."""
|
||||
|
||||
def __init__(self, port):
|
||||
"""
|
||||
def __init__(self, port: _Port):
|
||||
"""Ev3devSensor(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the device is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def read(self, mode):
|
||||
"""Reads values at a given mode.
|
||||
def read(self, mode: str) -> Tuple:
|
||||
"""read(mode) -> Tuple
|
||||
|
||||
Reads values at a given mode.
|
||||
|
||||
Arguments:
|
||||
mode (``str``): `Mode name`_.
|
||||
mode (str): `Mode name`_.
|
||||
|
||||
Returns:
|
||||
``tuple``: Values read from the sensor.
|
||||
values read from the sensor.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class AnalogSensor:
|
||||
"""Generic or custom analog sensor."""
|
||||
|
||||
def __init__(self, port):
|
||||
"""
|
||||
def __init__(self, port: _Port):
|
||||
"""AnalogSensor(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def voltage(self):
|
||||
"""Measures analog voltage.
|
||||
def voltage(self) -> int:
|
||||
"""voltage() -> int: mV
|
||||
|
||||
Measures analog voltage.
|
||||
|
||||
Returns:
|
||||
:ref:`voltage`: Analog voltage.
|
||||
Analog voltage.
|
||||
"""
|
||||
pass
|
||||
|
||||
def resistance(self):
|
||||
"""Measures resistance.
|
||||
def resistance(self) -> int:
|
||||
"""resistance() -> int: Ω
|
||||
|
||||
Measures resistance.
|
||||
|
||||
This value is only meaningful if the analog device is a passive load
|
||||
such as a resistor or thermistor.
|
||||
|
||||
Returns:
|
||||
:ref:`resistance: Ω <voltage>`: Resistance of the analog device.
|
||||
Resistance of the analog device.
|
||||
"""
|
||||
pass
|
||||
|
||||
def active(self):
|
||||
"""Sets sensor to active mode. This sets pin 5 of the sensor
|
||||
def active(self) -> None:
|
||||
"""active()
|
||||
|
||||
Sets sensor to active mode. This sets pin 5 of the sensor
|
||||
port to `high`.
|
||||
|
||||
This is used in some analog
|
||||
@@ -136,10 +150,11 @@ class AnalogSensor:
|
||||
Sensor as a custom analog sensor, this method will turn the light on.
|
||||
From then on, ``voltage()`` returns the raw reflected light value.
|
||||
"""
|
||||
pass
|
||||
|
||||
def passive(self):
|
||||
"""Sets sensor to passive mode. This sets pin 5 of the sensor
|
||||
def passive(self) -> None:
|
||||
"""passive()
|
||||
|
||||
Sets sensor to passive mode. This sets pin 5 of the sensor
|
||||
port to `low`.
|
||||
|
||||
This is used in some analog
|
||||
@@ -147,116 +162,120 @@ class AnalogSensor:
|
||||
Sensor as a custom analog sensor, this method will turn the light off.
|
||||
From then on, ``voltage()`` returns the raw ambient light value.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class I2CDevice:
|
||||
"""Generic or custom I2C device."""
|
||||
|
||||
def __init__(self, port, address):
|
||||
"""
|
||||
def __init__(self, port: _Port, address: int):
|
||||
"""I2CDevice(port, address)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the device is connected.
|
||||
address(int): I2C address of the client device. See
|
||||
:ref:`I2C Addresses <i2caddress>`.
|
||||
"""
|
||||
pass
|
||||
|
||||
def read(self, reg, length=1):
|
||||
"""Reads bytes, starting at a given register.
|
||||
def read(self, reg: Optional[int], length: Optional[int] = 1) -> bytes:
|
||||
"""read(reg, length=1)
|
||||
|
||||
Reads bytes, starting at a given register.
|
||||
|
||||
Arguments:
|
||||
reg (``int``): Register at which to begin
|
||||
reg (int): Register at which to begin
|
||||
reading: 0--255 or 0x00--0xFF.
|
||||
length (``int``): How many bytes to read.
|
||||
length (int): How many bytes to read.
|
||||
|
||||
Returns:
|
||||
``bytes``: Bytes returned from the device.
|
||||
Bytes returned from the device.
|
||||
"""
|
||||
pass
|
||||
|
||||
def write(self, reg, data=None):
|
||||
"""Writes bytes, starting at a given register.
|
||||
def write(self, reg: Optional[int], data: Optional[bytes] = None) -> None:
|
||||
"""write(reg, data=None)
|
||||
|
||||
Writes bytes, starting at a given register.
|
||||
|
||||
Arguments:
|
||||
reg (``int``): Register at which to begin
|
||||
reg (int): Register at which to begin
|
||||
writing: 0--255 or 0x00--0xFF.
|
||||
data (``bytes``): Bytes to be written.
|
||||
data (bytes): Bytes to be written.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class UARTDevice:
|
||||
"""Generic UART device."""
|
||||
|
||||
def __init__(self, port, baudrate, timeout=None):
|
||||
"""
|
||||
def __init__(self, port: _Port, baudrate: int, timeout: Optional[int] = None):
|
||||
"""UARTDevice(port, baudrate, timeout=None)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the device is connected.
|
||||
baudrate (int): Baudrate of the UART device.
|
||||
timeout (:ref:`time`): How long to wait
|
||||
timeout (Number, ms): How long to wait
|
||||
during ``read`` before giving up. If you choose ``None``,
|
||||
it will wait forever.
|
||||
"""
|
||||
pass
|
||||
|
||||
def read(self, length=1):
|
||||
"""Reads a given number of bytes from the buffer.
|
||||
def read(self, length: int = 1) -> bytes:
|
||||
"""read(length=1) -> bytes
|
||||
|
||||
Reads a given number of bytes from the buffer.
|
||||
|
||||
Your program will wait until the requested number of bytes are
|
||||
received. If this takes longer than ``timeout``, the ``ETIMEDOUT``
|
||||
exception is raised.
|
||||
|
||||
Arguments:
|
||||
length (``int``): How many bytes to read.
|
||||
length (int): How many bytes to read.
|
||||
|
||||
Returns:
|
||||
``bytes``: Bytes returned from the device.
|
||||
Bytes returned from the device.
|
||||
"""
|
||||
pass
|
||||
|
||||
def read_all(self):
|
||||
"""Reads all bytes from the buffer.
|
||||
def read_all(self) -> bytes:
|
||||
"""read_all() -> bytes
|
||||
|
||||
Reads all bytes from the buffer.
|
||||
|
||||
Returns:
|
||||
``bytes``: Bytes returned from the device.
|
||||
Bytes returned from the device.
|
||||
"""
|
||||
pass
|
||||
|
||||
def write(self, data):
|
||||
"""Writes bytes.
|
||||
def write(self, data: bytes) -> None:
|
||||
"""write(data)
|
||||
|
||||
Writes bytes.
|
||||
|
||||
Arguments:
|
||||
data (``bytes``): Bytes to be written.
|
||||
data (bytes): Bytes to be written.
|
||||
"""
|
||||
pass
|
||||
|
||||
def waiting(self):
|
||||
"""Gets how many bytes are still waiting to be read.
|
||||
def waiting(self) -> int:
|
||||
"""waiting() -> int
|
||||
|
||||
Gets how many bytes are still waiting to be read.
|
||||
|
||||
Returns:
|
||||
``int``: Number of bytes in the buffer.
|
||||
Number of bytes in the buffer.
|
||||
"""
|
||||
pass
|
||||
|
||||
def clear(self):
|
||||
"""Empties the buffer."""
|
||||
pass
|
||||
def clear(self) -> None:
|
||||
"""clear()
|
||||
|
||||
Empties the buffer."""
|
||||
|
||||
|
||||
class LWP3Device:
|
||||
"""
|
||||
Connects to a remote hub running official LEGO firmware using the the
|
||||
Connects to a hub running official LEGO firmware using the
|
||||
`LEGO Wireless Protocol v3`_
|
||||
|
||||
.. _`LEGO Wireless Protocol v3`:
|
||||
https://lego.github.io/lego-ble-wireless-protocol-docs/
|
||||
"""
|
||||
|
||||
def __init__(self, hub_kind, name=None, timeout=10000):
|
||||
"""
|
||||
def __init__(self, hub_kind: int, name: str = None, timeout: int = 10000):
|
||||
"""LWP3Device(hub_kind, name=None, timeout=10000)
|
||||
|
||||
Arguments:
|
||||
hub_kind (int):
|
||||
@@ -273,30 +292,42 @@ class LWP3Device:
|
||||
https://github.com/pybricks/technical-info/blob/master/assigned-numbers.md#hub-type-ids
|
||||
"""
|
||||
|
||||
def name(self, name=None):
|
||||
"""Gets or sets the Bluetooth name of the remote.
|
||||
@overload
|
||||
def name(self, name: str) -> None:
|
||||
...
|
||||
|
||||
If no name is given, this method returns the current name.
|
||||
@overload
|
||||
def name(self) -> str:
|
||||
...
|
||||
|
||||
def name(self, *args):
|
||||
"""name(name)
|
||||
name() -> str
|
||||
|
||||
Sets or gets the Bluetooth name of the device.
|
||||
|
||||
Arguments:
|
||||
name (str): New Bluetooth name of the remote.
|
||||
name (str): New Bluetooth name of the device. If no name is given,
|
||||
this method returns the current name.
|
||||
"""
|
||||
|
||||
def write(self, buf):
|
||||
"""
|
||||
def write(self, buf: bytes) -> None:
|
||||
"""write(buf)
|
||||
|
||||
Sends a message to the remote hub.
|
||||
|
||||
Arguments:
|
||||
buf (bytes): The raw binary message to send.
|
||||
"""
|
||||
|
||||
def read(self):
|
||||
"""
|
||||
def read(self) -> bytes:
|
||||
"""read() -> bytes
|
||||
|
||||
Retrieves the most recent message received from the remote hub.
|
||||
|
||||
If a message has not been received since the last read, the method will
|
||||
block until a message is received.
|
||||
|
||||
Returns:
|
||||
bytes: The raw binary message.
|
||||
The raw binary message.
|
||||
"""
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2020 The Pybricks Authors
|
||||
|
||||
from typing import Dict, Optional, Tuple, overload
|
||||
|
||||
from .parameters import Port
|
||||
|
||||
class PUPDevice:
|
||||
def __init__(self, port: Port): ...
|
||||
def info(self) -> Dict[str, str]: ...
|
||||
def read(self, mode: int) -> Tuple: ...
|
||||
def write(self, mode: int, data: Tuple) -> None: ...
|
||||
|
||||
class LUMPDevice:
|
||||
def __init__(self, port: Port): ...
|
||||
def read(self, mode: int) -> Tuple: ...
|
||||
|
||||
class Ev3devSensor:
|
||||
sensor_index: int
|
||||
port_index: int
|
||||
def __init__(self, port: Port): ...
|
||||
def read(self, mode: int) -> Tuple: ...
|
||||
|
||||
class AnalogSensor:
|
||||
def __init__(self, port: Port): ...
|
||||
def voltage(self) -> int: ...
|
||||
def resistance(self) -> int: ...
|
||||
def active(self) -> None: ...
|
||||
def passive(self) -> None: ...
|
||||
|
||||
class I2CDevice:
|
||||
def __init__(self, port: Port, address: int): ...
|
||||
def read(self, reg: Optional[int], length: Optional[int] = 1) -> bytes: ...
|
||||
def write(self, reg: Optional[int], data: Optional[bytes] = None) -> None: ...
|
||||
|
||||
class UARTDevice:
|
||||
def __init__(self, port: Port, baudrate: int, timeout: Optional[int] = None): ...
|
||||
def read(self, length: int = 1) -> bytes: ...
|
||||
def read_all(self) -> bytes: ...
|
||||
def write(self, data: bytes) -> None: ...
|
||||
def waiting(self) -> int: ...
|
||||
def clear(self) -> None: ...
|
||||
|
||||
class LWP3Device:
|
||||
def __init__(self, hub_kind: int, name: str = None, timeout: int = 10000): ...
|
||||
@overload
|
||||
def name(self) -> str: ...
|
||||
@overload
|
||||
def name(self, name: str) -> None: ...
|
||||
def name(self, *args): ...
|
||||
def read(self) -> bytes: ...
|
||||
def write(self, buf: bytes) -> None: ...
|
||||
+279
-208
@@ -3,7 +3,11 @@
|
||||
|
||||
"""Images and Sounds for Pybricks on ev3dev."""
|
||||
|
||||
from ..parameters import Color as _Color
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Union, Literal, overload, Optional, Any
|
||||
|
||||
from ..parameters import Color
|
||||
|
||||
|
||||
class Image:
|
||||
@@ -15,8 +19,20 @@ class Image:
|
||||
# in that context and it is automatically replaced when the documentation
|
||||
# is generated.
|
||||
|
||||
def __init__(self, source, sub=False):
|
||||
"""
|
||||
@overload
|
||||
def __init__(self, /, source: Union[Image, ImageFile, str]):
|
||||
...
|
||||
|
||||
@overload
|
||||
def __init__(
|
||||
self, /, source: Image, sub: Literal[False], x1: int, y1: int, x2: int, y2: int
|
||||
):
|
||||
...
|
||||
|
||||
def __init__(self, *args):
|
||||
"""Image(source, sub=False)
|
||||
|
||||
|
||||
Arguments:
|
||||
source (str or Image):
|
||||
The source of the image.
|
||||
@@ -39,36 +55,47 @@ class Image:
|
||||
bottom-right coordinates in the ``source`` image that will be
|
||||
used as the bounds for the sub-image.
|
||||
"""
|
||||
pass
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
def width(self) -> int:
|
||||
"""Gets the width of |this image| in pixels."""
|
||||
return 0
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
def height(self) -> int:
|
||||
"""Gets the height of |this image| in pixels."""
|
||||
return 0
|
||||
|
||||
def clear(self):
|
||||
"""Clears |this image|. All pixels on |this image| will be set to
|
||||
def clear(self) -> None:
|
||||
"""clear()
|
||||
|
||||
Clears |this image|. All pixels on |this image| will be set to
|
||||
:attr:`Color.WHITE <pybricks.parameters.Color.WHITE>`.
|
||||
"""
|
||||
pass
|
||||
|
||||
def draw_pixel(self, x, y, color=_Color.BLACK):
|
||||
"""Draws a single pixel on |this image|.
|
||||
def draw_pixel(self, x: int, y: int, color: Color = Color.BLACK) -> None:
|
||||
"""draw_pixel(x, y, color=Color.BLACK)
|
||||
|
||||
Draws a single pixel on |this image|.
|
||||
|
||||
Arguments:
|
||||
x (int): The x coordinate of the pixel.
|
||||
y (int): The y coordinate of the pixel.
|
||||
color (Color): The color of the pixel.
|
||||
"""
|
||||
pass
|
||||
|
||||
def draw_line(self, x1, y1, x2, y2, width=1, color=_Color.BLACK):
|
||||
"""Draws a line on |this image|.
|
||||
def draw_line(
|
||||
self,
|
||||
x1: int,
|
||||
y1: int,
|
||||
x2: int,
|
||||
y2: int,
|
||||
width: int = 1,
|
||||
color: Color = Color.BLACK,
|
||||
) -> None:
|
||||
"""draw_line(x1, y1, x2, y2, width=1, color=Color.BLACK)
|
||||
|
||||
Draws a line on |this image|.
|
||||
|
||||
Arguments:
|
||||
x1 (int): The x coordinate of the starting point of the line.
|
||||
@@ -78,10 +105,20 @@ class Image:
|
||||
width (int): The width of the line in pixels.
|
||||
color (Color): The color of the line.
|
||||
"""
|
||||
pass
|
||||
|
||||
def draw_box(self, x1, y1, x2, y2, r=0, fill=False, color=_Color.BLACK):
|
||||
"""Draws a box on |this image|.
|
||||
def draw_box(
|
||||
self,
|
||||
x1: int,
|
||||
y1: int,
|
||||
x2: int,
|
||||
y2: int,
|
||||
r: int = 0,
|
||||
fill: bool = False,
|
||||
color: Color = Color.BLACK,
|
||||
) -> None:
|
||||
"""draw_box(x1, y1, x2, y2, r=0, fill=False, color=Color.BLACK)
|
||||
|
||||
Draws a box on |this image|.
|
||||
|
||||
Arguments:
|
||||
x1 (int): The x coordinate of the left side of the box.
|
||||
@@ -93,10 +130,13 @@ class Image:
|
||||
otherwise only the outline of the box will be drawn.
|
||||
color (Color): The color of the box.
|
||||
"""
|
||||
pass
|
||||
|
||||
def draw_circle(self, x, y, r, fill=False, color=_Color.BLACK):
|
||||
"""Draws a circle on |this image|.
|
||||
def draw_circle(
|
||||
self, x: int, y: int, r: int, fill: bool = False, color: Color = Color.BLACK
|
||||
) -> None:
|
||||
"""draw_circle(x, y, r, fill=False, color=Color.BLACK)
|
||||
|
||||
Draws a circle on |this image|.
|
||||
|
||||
Arguments:
|
||||
x (int): The x coordinate of the center of the circle.
|
||||
@@ -106,10 +146,17 @@ class Image:
|
||||
``color``, otherwise only the circumference will be drawn.
|
||||
color (Color): The color of the circle.
|
||||
"""
|
||||
pass
|
||||
|
||||
def draw_image(self, x, y, source, transparent=None):
|
||||
"""Draws the ``source`` image on |this image|.
|
||||
def draw_image(
|
||||
self,
|
||||
x: int,
|
||||
y: int,
|
||||
source: Union[Image, ImageFile, str],
|
||||
transparent: Optional[Color] = None,
|
||||
) -> None:
|
||||
"""draw_image(x, y, source, transparent=None)
|
||||
|
||||
Draws the ``source`` image on |this image|.
|
||||
|
||||
Arguments:
|
||||
x (int):
|
||||
@@ -125,8 +172,10 @@ class Image:
|
||||
no transparency.
|
||||
"""
|
||||
|
||||
def load_image(self, source):
|
||||
"""Clears this image, then draws the ``source`` image centered in
|
||||
def load_image(self, source: Union[Image, ImageFile, str]) -> None:
|
||||
"""load_image(source)
|
||||
|
||||
Clears this image, then draws the ``source`` image centered in
|
||||
|this image|.
|
||||
|
||||
Arguments:
|
||||
@@ -136,8 +185,17 @@ class Image:
|
||||
from file.
|
||||
"""
|
||||
|
||||
def draw_text(self, x, y, text, text_color=_Color.BLACK, background_color=None):
|
||||
"""Draws text on |this image|.
|
||||
def draw_text(
|
||||
self,
|
||||
x: int,
|
||||
y: int,
|
||||
text: str,
|
||||
text_color: Color = Color.BLACK,
|
||||
background_color: Optional[Color] = None,
|
||||
) -> None:
|
||||
"""draw_text(x, y, text, text_color=Color.BLACK, background_color=None)
|
||||
|
||||
Draws text on |this image|.
|
||||
|
||||
The most recent font set using :meth:`.set_font` will be used or
|
||||
:data:`Font.DEFAULT <pybricks.media.ev3dev.Font.DEFAULT>` if no font
|
||||
@@ -156,10 +214,11 @@ class Image:
|
||||
The color used to fill the rectangle behind the text or
|
||||
``None`` for transparent background.
|
||||
"""
|
||||
pass
|
||||
|
||||
def print(self, *args, sep=" ", end="\n"):
|
||||
"""Prints a line of text on |this image|.
|
||||
def print(self, *args: Any, sep: str = " ", end: str = "\n") -> None:
|
||||
"""print(*args, sep=" ", end="\\n")
|
||||
|
||||
Prints a line of text on |this image|.
|
||||
|
||||
This method works like the builtin ``print()`` function, but it writes
|
||||
on |this image| instead.
|
||||
@@ -176,18 +235,16 @@ class Image:
|
||||
bottom of |this image|.
|
||||
|
||||
Arguments:
|
||||
* (object):
|
||||
Zero or more objects to print.
|
||||
sep (str):
|
||||
Separator that will be placed between each object that is
|
||||
printed.
|
||||
end (str):
|
||||
End of line that will be printed after the last object.
|
||||
args (Any): Zero or more objects to print.
|
||||
sep (str): Separator that will be placed between each object that
|
||||
is printed.
|
||||
end (str): End of line that will be printed after the last object.
|
||||
"""
|
||||
pass
|
||||
|
||||
def set_font(self, font):
|
||||
"""Sets the font used for writing on |this image|.
|
||||
def set_font(self, font: Font) -> None:
|
||||
"""set_font(font)
|
||||
|
||||
Sets the font used for writing on |this image|.
|
||||
|
||||
The font is used for both :meth:`.draw_text` and :meth:`.print`.
|
||||
|
||||
@@ -195,11 +252,10 @@ class Image:
|
||||
font (Font):
|
||||
The font to use.
|
||||
"""
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def empty(width=178, height=128):
|
||||
"""empty(width=<screen width>, height=<screen height>)
|
||||
def empty(width: int = 178, height: int = 128) -> Image:
|
||||
"""empty(width=178, height=128) -> Image
|
||||
|
||||
Creates a new empty :class:`Image` object.
|
||||
|
||||
@@ -210,21 +266,22 @@ class Image:
|
||||
The height of the image in pixels.
|
||||
|
||||
Returns:
|
||||
Image:
|
||||
A new image with all pixels set to :attr:`Color.WHITE
|
||||
<pybricks.parameters.Color.WHITE>`.
|
||||
A new image with all pixels set
|
||||
to :attr:`Color.WHITE <pybricks.parameters.Color.WHITE>`.
|
||||
|
||||
Raises:
|
||||
TypeError:
|
||||
``width`` or ``height`` is not a number.
|
||||
If ``width`` or ``height`` is not a number.
|
||||
ValueError:
|
||||
``width`` or ``height`` is less than 1.
|
||||
If ``width`` or ``height`` is less than 1.
|
||||
RuntimeError:
|
||||
There was a problem allocating a new image.
|
||||
If there was a problem allocating a new image.
|
||||
"""
|
||||
|
||||
def save(self, filename):
|
||||
"""Saves |this image| as a ``.png`` file.
|
||||
def save(self, filename: str) -> None:
|
||||
"""save(filename)
|
||||
|
||||
Saves |this image| as a ``.png`` file.
|
||||
|
||||
Arguments:
|
||||
filename (str):
|
||||
@@ -241,13 +298,21 @@ class Image:
|
||||
class Font:
|
||||
"""Object that represents a font for writing text."""
|
||||
|
||||
DEFAULT = None # assigned later since we can't use Font() here
|
||||
DEFAULT: Font = None # assigned later since we can't use Font() here
|
||||
"""The default font."""
|
||||
|
||||
def __init__(
|
||||
self, family=None, size=12, bold=False, monospace=False, lang=None, script=None
|
||||
self,
|
||||
family: Optional[str] = None,
|
||||
size: int = 12,
|
||||
bold: bool = False,
|
||||
monospace: bool = False,
|
||||
lang: Optional[str] = None,
|
||||
script: Optional[str] = None,
|
||||
):
|
||||
"""The font object will be a font that is the "best" match based on the
|
||||
"""Font(family=None, size=12, bold=False, monospace=False, lang=None, script=None)
|
||||
|
||||
The font object will be a font that is the "best" match based on the
|
||||
parameters given and available fonts installed.
|
||||
|
||||
Arguments:
|
||||
@@ -269,30 +334,34 @@ class Font:
|
||||
"""
|
||||
|
||||
@property
|
||||
def family(self):
|
||||
def family(self) -> str:
|
||||
"""Gets the family name of the font."""
|
||||
return "Lucida"
|
||||
|
||||
@property
|
||||
def style(self):
|
||||
"""Gets a string describing the font style.
|
||||
def style(self) -> str:
|
||||
"""style -> str
|
||||
|
||||
Gets a string describing the font style.
|
||||
|
||||
Can be "Regular" or "Bold".
|
||||
"""
|
||||
return "Regular"
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
def width(self) -> int:
|
||||
"""Gets the width of the widest character of the font."""
|
||||
return 0
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
def height(self) -> int:
|
||||
"""Gets the height of the font."""
|
||||
return 0
|
||||
|
||||
def text_width(self, text):
|
||||
"""Gets the width of the text when the text is drawn using this font.
|
||||
def text_width(self, text: str) -> int:
|
||||
"""text_width(text)
|
||||
|
||||
Gets the width of the text when the text is drawn using this font.
|
||||
|
||||
Arguments:
|
||||
text (str):
|
||||
@@ -304,8 +373,10 @@ class Font:
|
||||
"""
|
||||
return 0
|
||||
|
||||
def text_height(self, text):
|
||||
"""Gets the height of the text when the text is drawn using this font.
|
||||
def text_height(self, text: str) -> int:
|
||||
"""text_height(text)
|
||||
|
||||
Gets the height of the text when the text is drawn using this font.
|
||||
|
||||
Arguments:
|
||||
text (str):
|
||||
@@ -324,153 +395,153 @@ Font.DEFAULT = Font("Lucida", 12)
|
||||
class SoundFile:
|
||||
"""Paths to standard EV3 sounds."""
|
||||
|
||||
_BASE_PATH = "/usr/share/sounds/ev3dev/"
|
||||
SHOUTING = _BASE_PATH + "expressions/shouting.wav"
|
||||
CHEERING = _BASE_PATH + "expressions/cheering.wav"
|
||||
CRYING = _BASE_PATH + "expressions/crying.wav"
|
||||
OUCH = _BASE_PATH + "expressions/ouch.wav"
|
||||
LAUGHING_2 = _BASE_PATH + "expressions/laughing_2.wav"
|
||||
SNEEZING = _BASE_PATH + "expressions/sneezing.wav"
|
||||
SMACK = _BASE_PATH + "expressions/smack.wav"
|
||||
BOING = _BASE_PATH + "expressions/boing.wav"
|
||||
BOO = _BASE_PATH + "expressions/boo.wav"
|
||||
UH_OH = _BASE_PATH + "expressions/uh-oh.wav"
|
||||
SNORING = _BASE_PATH + "expressions/snoring.wav"
|
||||
KUNG_FU = _BASE_PATH + "expressions/kung_fu.wav"
|
||||
FANFARE = _BASE_PATH + "expressions/fanfare.wav"
|
||||
CRUNCHING = _BASE_PATH + "expressions/crunching.wav"
|
||||
MAGIC_WAND = _BASE_PATH + "expressions/magic_wand.wav"
|
||||
LAUGHING_1 = _BASE_PATH + "expressions/laughing_1.wav"
|
||||
LEFT = _BASE_PATH + "information/left.wav"
|
||||
BACKWARDS = _BASE_PATH + "information/backwards.wav"
|
||||
RIGHT = _BASE_PATH + "information/right.wav"
|
||||
OBJECT = _BASE_PATH + "information/object.wav"
|
||||
COLOR = _BASE_PATH + "information/color.wav"
|
||||
FLASHING = _BASE_PATH + "information/flashing.wav"
|
||||
ERROR = _BASE_PATH + "information/error.wav"
|
||||
ERROR_ALARM = _BASE_PATH + "information/error_alarm.wav"
|
||||
DOWN = _BASE_PATH + "information/down.wav"
|
||||
FORWARD = _BASE_PATH + "information/forward.wav"
|
||||
ACTIVATE = _BASE_PATH + "information/activate.wav"
|
||||
SEARCHING = _BASE_PATH + "information/searching.wav"
|
||||
TOUCH = _BASE_PATH + "information/touch.wav"
|
||||
UP = _BASE_PATH + "information/up.wav"
|
||||
ANALYZE = _BASE_PATH + "information/analyze.wav"
|
||||
STOP = _BASE_PATH + "information/stop.wav"
|
||||
DETECTED = _BASE_PATH + "information/detected.wav"
|
||||
TURN = _BASE_PATH + "information/turn.wav"
|
||||
START = _BASE_PATH + "information/start.wav"
|
||||
MORNING = _BASE_PATH + "communication/morning.wav"
|
||||
EV3 = _BASE_PATH + "communication/ev3.wav"
|
||||
GO = _BASE_PATH + "communication/go.wav"
|
||||
GOOD_JOB = _BASE_PATH + "communication/good_job.wav"
|
||||
OKEY_DOKEY = _BASE_PATH + "communication/okey-dokey.wav"
|
||||
GOOD = _BASE_PATH + "communication/good.wav"
|
||||
NO = _BASE_PATH + "communication/no.wav"
|
||||
THANK_YOU = _BASE_PATH + "communication/thank_you.wav"
|
||||
YES = _BASE_PATH + "communication/yes.wav"
|
||||
GAME_OVER = _BASE_PATH + "communication/game_over.wav"
|
||||
OKAY = _BASE_PATH + "communication/okay.wav"
|
||||
SORRY = _BASE_PATH + "communication/sorry.wav"
|
||||
BRAVO = _BASE_PATH + "communication/bravo.wav"
|
||||
GOODBYE = _BASE_PATH + "communication/goodbye.wav"
|
||||
HI = _BASE_PATH + "communication/hi.wav"
|
||||
HELLO = _BASE_PATH + "communication/hello.wav"
|
||||
MINDSTORMS = _BASE_PATH + "communication/mindstorms.wav"
|
||||
LEGO = _BASE_PATH + "communication/lego.wav"
|
||||
FANTASTIC = _BASE_PATH + "communication/fantastic.wav"
|
||||
SPEED_IDLE = _BASE_PATH + "movements/speed_idle.wav"
|
||||
SPEED_DOWN = _BASE_PATH + "movements/speed_down.wav"
|
||||
SPEED_UP = _BASE_PATH + "movements/speed_up.wav"
|
||||
BROWN = _BASE_PATH + "colors/brown.wav"
|
||||
GREEN = _BASE_PATH + "colors/green.wav"
|
||||
BLACK = _BASE_PATH + "colors/black.wav"
|
||||
WHITE = _BASE_PATH + "colors/white.wav"
|
||||
RED = _BASE_PATH + "colors/red.wav"
|
||||
BLUE = _BASE_PATH + "colors/blue.wav"
|
||||
YELLOW = _BASE_PATH + "colors/yellow.wav"
|
||||
TICK_TACK = _BASE_PATH + "mechanical/tick_tack.wav"
|
||||
HORN_1 = _BASE_PATH + "mechanical/horn_1.wav"
|
||||
BACKING_ALERT = _BASE_PATH + "mechanical/backing_alert.wav"
|
||||
MOTOR_IDLE = _BASE_PATH + "mechanical/motor_idle.wav"
|
||||
AIR_RELEASE = _BASE_PATH + "mechanical/air_release.wav"
|
||||
AIRBRAKE = _BASE_PATH + "mechanical/airbrake.wav"
|
||||
RATCHET = _BASE_PATH + "mechanical/ratchet.wav"
|
||||
MOTOR_STOP = _BASE_PATH + "mechanical/motor_stop.wav"
|
||||
HORN_2 = _BASE_PATH + "mechanical/horn_2.wav"
|
||||
LASER = _BASE_PATH + "mechanical/laser.wav"
|
||||
SONAR = _BASE_PATH + "mechanical/sonar.wav"
|
||||
MOTOR_START = _BASE_PATH + "mechanical/motor_start.wav"
|
||||
INSECT_BUZZ_2 = _BASE_PATH + "animals/insect_buzz_2.wav"
|
||||
ELEPHANT_CALL = _BASE_PATH + "animals/elephant_call.wav"
|
||||
SNAKE_HISS = _BASE_PATH + "animals/snake_hiss.wav"
|
||||
DOG_BARK_2 = _BASE_PATH + "animals/dog_bark_2.wav"
|
||||
DOG_WHINE = _BASE_PATH + "animals/dog_whine.wav"
|
||||
INSECT_BUZZ_1 = _BASE_PATH + "animals/insect_buzz_1.wav"
|
||||
DOG_SNIFF = _BASE_PATH + "animals/dog_sniff.wav"
|
||||
T_REX_ROAR = _BASE_PATH + "animals/t-rex_roar.wav"
|
||||
INSECT_CHIRP = _BASE_PATH + "animals/insect_chirp.wav"
|
||||
DOG_GROWL = _BASE_PATH + "animals/dog_growl.wav"
|
||||
SNAKE_RATTLE = _BASE_PATH + "animals/snake_rattle.wav"
|
||||
DOG_BARK_1 = _BASE_PATH + "animals/dog_bark_1.wav"
|
||||
CAT_PURR = _BASE_PATH + "animals/cat_purr.wav"
|
||||
EIGHT = _BASE_PATH + "numbers/eight.wav"
|
||||
SEVEN = _BASE_PATH + "numbers/seven.wav"
|
||||
SIX = _BASE_PATH + "numbers/six.wav"
|
||||
FOUR = _BASE_PATH + "numbers/four.wav"
|
||||
TEN = _BASE_PATH + "numbers/ten.wav"
|
||||
ONE = _BASE_PATH + "numbers/one.wav"
|
||||
TWO = _BASE_PATH + "numbers/two.wav"
|
||||
THREE = _BASE_PATH + "numbers/three.wav"
|
||||
ZERO = _BASE_PATH + "numbers/zero.wav"
|
||||
FIVE = _BASE_PATH + "numbers/five.wav"
|
||||
NINE = _BASE_PATH + "numbers/nine.wav"
|
||||
READY = _BASE_PATH + "system/ready.wav"
|
||||
CONFIRM = _BASE_PATH + "system/confirm.wav"
|
||||
GENERAL_ALERT = _BASE_PATH + "system/general_alert.wav"
|
||||
CLICK = _BASE_PATH + "system/click.wav"
|
||||
OVERPOWER = _BASE_PATH + "system/overpower.wav"
|
||||
_BASE_PATH: str = "/usr/share/sounds/ev3dev/"
|
||||
SHOUTING: str = _BASE_PATH + "expressions/shouting.wav"
|
||||
CHEERING: str = _BASE_PATH + "expressions/cheering.wav"
|
||||
CRYING: str = _BASE_PATH + "expressions/crying.wav"
|
||||
OUCH: str = _BASE_PATH + "expressions/ouch.wav"
|
||||
LAUGHING_2: str = _BASE_PATH + "expressions/laughing_2.wav"
|
||||
SNEEZING: str = _BASE_PATH + "expressions/sneezing.wav"
|
||||
SMACK: str = _BASE_PATH + "expressions/smack.wav"
|
||||
BOING: str = _BASE_PATH + "expressions/boing.wav"
|
||||
BOO: str = _BASE_PATH + "expressions/boo.wav"
|
||||
UH_OH: str = _BASE_PATH + "expressions/uh-oh.wav"
|
||||
SNORING: str = _BASE_PATH + "expressions/snoring.wav"
|
||||
KUNG_FU: str = _BASE_PATH + "expressions/kung_fu.wav"
|
||||
FANFARE: str = _BASE_PATH + "expressions/fanfare.wav"
|
||||
CRUNCHING: str = _BASE_PATH + "expressions/crunching.wav"
|
||||
MAGIC_WAND: str = _BASE_PATH + "expressions/magic_wand.wav"
|
||||
LAUGHING_1: str = _BASE_PATH + "expressions/laughing_1.wav"
|
||||
LEFT: str = _BASE_PATH + "information/left.wav"
|
||||
BACKWARDS: str = _BASE_PATH + "information/backwards.wav"
|
||||
RIGHT: str = _BASE_PATH + "information/right.wav"
|
||||
OBJECT: str = _BASE_PATH + "information/object.wav"
|
||||
COLOR: str = _BASE_PATH + "information/color.wav"
|
||||
FLASHING: str = _BASE_PATH + "information/flashing.wav"
|
||||
ERROR: str = _BASE_PATH + "information/error.wav"
|
||||
ERROR_ALARM: str = _BASE_PATH + "information/error_alarm.wav"
|
||||
DOWN: str = _BASE_PATH + "information/down.wav"
|
||||
FORWARD: str = _BASE_PATH + "information/forward.wav"
|
||||
ACTIVATE: str = _BASE_PATH + "information/activate.wav"
|
||||
SEARCHING: str = _BASE_PATH + "information/searching.wav"
|
||||
TOUCH: str = _BASE_PATH + "information/touch.wav"
|
||||
UP: str = _BASE_PATH + "information/up.wav"
|
||||
ANALYZE: str = _BASE_PATH + "information/analyze.wav"
|
||||
STOP: str = _BASE_PATH + "information/stop.wav"
|
||||
DETECTED: str = _BASE_PATH + "information/detected.wav"
|
||||
TURN: str = _BASE_PATH + "information/turn.wav"
|
||||
START: str = _BASE_PATH + "information/start.wav"
|
||||
MORNING: str = _BASE_PATH + "communication/morning.wav"
|
||||
EV3: str = _BASE_PATH + "communication/ev3.wav"
|
||||
GO: str = _BASE_PATH + "communication/go.wav"
|
||||
GOOD_JOB: str = _BASE_PATH + "communication/good_job.wav"
|
||||
OKEY_DOKEY: str = _BASE_PATH + "communication/okey-dokey.wav"
|
||||
GOOD: str = _BASE_PATH + "communication/good.wav"
|
||||
NO: str = _BASE_PATH + "communication/no.wav"
|
||||
THANK_YOU: str = _BASE_PATH + "communication/thank_you.wav"
|
||||
YES: str = _BASE_PATH + "communication/yes.wav"
|
||||
GAME_OVER: str = _BASE_PATH + "communication/game_over.wav"
|
||||
OKAY: str = _BASE_PATH + "communication/okay.wav"
|
||||
SORRY: str = _BASE_PATH + "communication/sorry.wav"
|
||||
BRAVO: str = _BASE_PATH + "communication/bravo.wav"
|
||||
GOODBYE: str = _BASE_PATH + "communication/goodbye.wav"
|
||||
HI: str = _BASE_PATH + "communication/hi.wav"
|
||||
HELLO: str = _BASE_PATH + "communication/hello.wav"
|
||||
MINDSTORMS: str = _BASE_PATH + "communication/mindstorms.wav"
|
||||
LEGO: str = _BASE_PATH + "communication/lego.wav"
|
||||
FANTASTIC: str = _BASE_PATH + "communication/fantastic.wav"
|
||||
SPEED_IDLE: str = _BASE_PATH + "movements/speed_idle.wav"
|
||||
SPEED_DOWN: str = _BASE_PATH + "movements/speed_down.wav"
|
||||
SPEED_UP: str = _BASE_PATH + "movements/speed_up.wav"
|
||||
BROWN: str = _BASE_PATH + "colors/brown.wav"
|
||||
GREEN: str = _BASE_PATH + "colors/green.wav"
|
||||
BLACK: str = _BASE_PATH + "colors/black.wav"
|
||||
WHITE: str = _BASE_PATH + "colors/white.wav"
|
||||
RED: str = _BASE_PATH + "colors/red.wav"
|
||||
BLUE: str = _BASE_PATH + "colors/blue.wav"
|
||||
YELLOW: str = _BASE_PATH + "colors/yellow.wav"
|
||||
TICK_TACK: str = _BASE_PATH + "mechanical/tick_tack.wav"
|
||||
HORN_1: str = _BASE_PATH + "mechanical/horn_1.wav"
|
||||
BACKING_ALERT: str = _BASE_PATH + "mechanical/backing_alert.wav"
|
||||
MOTOR_IDLE: str = _BASE_PATH + "mechanical/motor_idle.wav"
|
||||
AIR_RELEASE: str = _BASE_PATH + "mechanical/air_release.wav"
|
||||
AIRBRAKE: str = _BASE_PATH + "mechanical/airbrake.wav"
|
||||
RATCHET: str = _BASE_PATH + "mechanical/ratchet.wav"
|
||||
MOTOR_STOP: str = _BASE_PATH + "mechanical/motor_stop.wav"
|
||||
HORN_2: str = _BASE_PATH + "mechanical/horn_2.wav"
|
||||
LASER: str = _BASE_PATH + "mechanical/laser.wav"
|
||||
SONAR: str = _BASE_PATH + "mechanical/sonar.wav"
|
||||
MOTOR_START: str = _BASE_PATH + "mechanical/motor_start.wav"
|
||||
INSECT_BUZZ_2: str = _BASE_PATH + "animals/insect_buzz_2.wav"
|
||||
ELEPHANT_CALL: str = _BASE_PATH + "animals/elephant_call.wav"
|
||||
SNAKE_HISS: str = _BASE_PATH + "animals/snake_hiss.wav"
|
||||
DOG_BARK_2: str = _BASE_PATH + "animals/dog_bark_2.wav"
|
||||
DOG_WHINE: str = _BASE_PATH + "animals/dog_whine.wav"
|
||||
INSECT_BUZZ_1: str = _BASE_PATH + "animals/insect_buzz_1.wav"
|
||||
DOG_SNIFF: str = _BASE_PATH + "animals/dog_sniff.wav"
|
||||
T_REX_ROAR: str = _BASE_PATH + "animals/t-rex_roar.wav"
|
||||
INSECT_CHIRP: str = _BASE_PATH + "animals/insect_chirp.wav"
|
||||
DOG_GROWL: str = _BASE_PATH + "animals/dog_growl.wav"
|
||||
SNAKE_RATTLE: str = _BASE_PATH + "animals/snake_rattle.wav"
|
||||
DOG_BARK_1: str = _BASE_PATH + "animals/dog_bark_1.wav"
|
||||
CAT_PURR: str = _BASE_PATH + "animals/cat_purr.wav"
|
||||
EIGHT: str = _BASE_PATH + "numbers/eight.wav"
|
||||
SEVEN: str = _BASE_PATH + "numbers/seven.wav"
|
||||
SIX: str = _BASE_PATH + "numbers/six.wav"
|
||||
FOUR: str = _BASE_PATH + "numbers/four.wav"
|
||||
TEN: str = _BASE_PATH + "numbers/ten.wav"
|
||||
ONE: str = _BASE_PATH + "numbers/one.wav"
|
||||
TWO: str = _BASE_PATH + "numbers/two.wav"
|
||||
THREE: str = _BASE_PATH + "numbers/three.wav"
|
||||
ZERO: str = _BASE_PATH + "numbers/zero.wav"
|
||||
FIVE: str = _BASE_PATH + "numbers/five.wav"
|
||||
NINE: str = _BASE_PATH + "numbers/nine.wav"
|
||||
READY: str = _BASE_PATH + "system/ready.wav"
|
||||
CONFIRM: str = _BASE_PATH + "system/confirm.wav"
|
||||
GENERAL_ALERT: str = _BASE_PATH + "system/general_alert.wav"
|
||||
CLICK: str = _BASE_PATH + "system/click.wav"
|
||||
OVERPOWER: str = _BASE_PATH + "system/overpower.wav"
|
||||
|
||||
|
||||
class ImageFile:
|
||||
"""Paths to standard EV3 images."""
|
||||
|
||||
_BASE_PATH = "/usr/share/images/ev3dev/mono/"
|
||||
RIGHT = _BASE_PATH + "information/right.png"
|
||||
FORWARD = _BASE_PATH + "information/forward.png"
|
||||
ACCEPT = _BASE_PATH + "information/accept.png"
|
||||
QUESTION_MARK = _BASE_PATH + "information/question_mark.png"
|
||||
STOP_1 = _BASE_PATH + "information/stop_1.png"
|
||||
LEFT = _BASE_PATH + "information/left.png"
|
||||
DECLINE = _BASE_PATH + "information/decline.png"
|
||||
THUMBS_DOWN = _BASE_PATH + "information/thumbs_down.png"
|
||||
BACKWARD = _BASE_PATH + "information/backward.png"
|
||||
NO_GO = _BASE_PATH + "information/no_go.png"
|
||||
WARNING = _BASE_PATH + "information/warning.png"
|
||||
STOP_2 = _BASE_PATH + "information/stop_2.png"
|
||||
THUMBS_UP = _BASE_PATH + "information/thumbs_up.png"
|
||||
EV3 = _BASE_PATH + "lego/ev3.png"
|
||||
EV3_ICON = _BASE_PATH + "lego/ev3_icon.png"
|
||||
TARGET = _BASE_PATH + "objects/target.png"
|
||||
BOTTOM_RIGHT = _BASE_PATH + "eyes/bottom_right.png"
|
||||
BOTTOM_LEFT = _BASE_PATH + "eyes/bottom_left.png"
|
||||
EVIL = _BASE_PATH + "eyes/evil.png"
|
||||
CRAZY_2 = _BASE_PATH + "eyes/crazy_2.png"
|
||||
KNOCKED_OUT = _BASE_PATH + "eyes/knocked_out.png"
|
||||
PINCHED_RIGHT = _BASE_PATH + "eyes/pinched_right.png"
|
||||
WINKING = _BASE_PATH + "eyes/winking.png"
|
||||
DIZZY = _BASE_PATH + "eyes/dizzy.png"
|
||||
DOWN = _BASE_PATH + "eyes/down.png"
|
||||
TIRED_MIDDLE = _BASE_PATH + "eyes/tired_middle.png"
|
||||
MIDDLE_RIGHT = _BASE_PATH + "eyes/middle_right.png"
|
||||
SLEEPING = _BASE_PATH + "eyes/sleeping.png"
|
||||
MIDDLE_LEFT = _BASE_PATH + "eyes/middle_left.png"
|
||||
TIRED_RIGHT = _BASE_PATH + "eyes/tired_right.png"
|
||||
PINCHED_LEFT = _BASE_PATH + "eyes/pinched_left.png"
|
||||
PINCHED_MIDDLE = _BASE_PATH + "eyes/pinched_middle.png"
|
||||
CRAZY_1 = _BASE_PATH + "eyes/crazy_1.png"
|
||||
NEUTRAL = _BASE_PATH + "eyes/neutral.png"
|
||||
AWAKE = _BASE_PATH + "eyes/awake.png"
|
||||
UP = _BASE_PATH + "eyes/up.png"
|
||||
TIRED_LEFT = _BASE_PATH + "eyes/tired_left.png"
|
||||
ANGRY = _BASE_PATH + "eyes/angry.png"
|
||||
_BASE_PATH: str = "/usr/share/images/ev3dev/mono/"
|
||||
RIGHT: str = _BASE_PATH + "information/right.png"
|
||||
FORWARD: str = _BASE_PATH + "information/forward.png"
|
||||
ACCEPT: str = _BASE_PATH + "information/accept.png"
|
||||
QUESTION_MARK: str = _BASE_PATH + "information/question_mark.png"
|
||||
STOP_1: str = _BASE_PATH + "information/stop_1.png"
|
||||
LEFT: str = _BASE_PATH + "information/left.png"
|
||||
DECLINE: str = _BASE_PATH + "information/decline.png"
|
||||
THUMBS_DOWN: str = _BASE_PATH + "information/thumbs_down.png"
|
||||
BACKWARD: str = _BASE_PATH + "information/backward.png"
|
||||
NO_GO: str = _BASE_PATH + "information/no_go.png"
|
||||
WARNING: str = _BASE_PATH + "information/warning.png"
|
||||
STOP_2: str = _BASE_PATH + "information/stop_2.png"
|
||||
THUMBS_UP: str = _BASE_PATH + "information/thumbs_up.png"
|
||||
EV3: str = _BASE_PATH + "lego/ev3.png"
|
||||
EV3_ICON: str = _BASE_PATH + "lego/ev3_icon.png"
|
||||
TARGET: str = _BASE_PATH + "objects/target.png"
|
||||
BOTTOM_RIGHT: str = _BASE_PATH + "eyes/bottom_right.png"
|
||||
BOTTOM_LEFT: str = _BASE_PATH + "eyes/bottom_left.png"
|
||||
EVIL: str = _BASE_PATH + "eyes/evil.png"
|
||||
CRAZY_2: str = _BASE_PATH + "eyes/crazy_2.png"
|
||||
KNOCKED_OUT: str = _BASE_PATH + "eyes/knocked_out.png"
|
||||
PINCHED_RIGHT: str = _BASE_PATH + "eyes/pinched_right.png"
|
||||
WINKING: str = _BASE_PATH + "eyes/winking.png"
|
||||
DIZZY: str = _BASE_PATH + "eyes/dizzy.png"
|
||||
DOWN: str = _BASE_PATH + "eyes/down.png"
|
||||
TIRED_MIDDLE: str = _BASE_PATH + "eyes/tired_middle.png"
|
||||
MIDDLE_RIGHT: str = _BASE_PATH + "eyes/middle_right.png"
|
||||
SLEEPING: str = _BASE_PATH + "eyes/sleeping.png"
|
||||
MIDDLE_LEFT: str = _BASE_PATH + "eyes/middle_left.png"
|
||||
TIRED_RIGHT: str = _BASE_PATH + "eyes/tired_right.png"
|
||||
PINCHED_LEFT: str = _BASE_PATH + "eyes/pinched_left.png"
|
||||
PINCHED_MIDDLE: str = _BASE_PATH + "eyes/pinched_middle.png"
|
||||
CRAZY_1: str = _BASE_PATH + "eyes/crazy_1.png"
|
||||
NEUTRAL: str = _BASE_PATH + "eyes/neutral.png"
|
||||
AWAKE: str = _BASE_PATH + "eyes/awake.png"
|
||||
UP: str = _BASE_PATH + "eyes/up.png"
|
||||
TIRED_LEFT: str = _BASE_PATH + "eyes/tired_left.png"
|
||||
ANGRY: str = _BASE_PATH + "eyes/angry.png"
|
||||
|
||||
@@ -1,232 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2020 The Pybricks Authors
|
||||
|
||||
from typing import Any, Literal, Optional, Union, overload
|
||||
|
||||
from ..parameters import Color
|
||||
|
||||
class Image:
|
||||
@overload
|
||||
def __init__(self, /, source: Union[Image, ImageFile, str]): ...
|
||||
@overload
|
||||
def __init__(
|
||||
self, /, source: Image, sub: Literal[True], x1: int, y1: int, x2: int, y2: int
|
||||
): ...
|
||||
@property
|
||||
def width(self) -> int: ...
|
||||
@property
|
||||
def height(self) -> int: ...
|
||||
def clear(self) -> None: ...
|
||||
def draw_pixel(self, x: int, y: int, color: Color = Color.BLACK) -> None: ...
|
||||
def draw_line(
|
||||
self,
|
||||
x1: int,
|
||||
y1: int,
|
||||
x2: int,
|
||||
y2: int,
|
||||
width: int = 1,
|
||||
color: Color = Color.BLACK,
|
||||
) -> None: ...
|
||||
def draw_box(
|
||||
self,
|
||||
x1: int,
|
||||
y1: int,
|
||||
x2: int,
|
||||
y2: int,
|
||||
r: int = 0,
|
||||
fill: bool = False,
|
||||
color: Color = Color.BLACK,
|
||||
) -> None: ...
|
||||
def draw_circle(
|
||||
self, x: int, y: int, r: int, fill: bool = False, color: Color = Color.BLACK
|
||||
) -> None: ...
|
||||
def draw_image(
|
||||
self,
|
||||
x: int,
|
||||
y: int,
|
||||
source: Union[Image, ImageFile, str],
|
||||
transparent: Optional[Color] = None,
|
||||
) -> None: ...
|
||||
def load_image(self, source: Union[Image, ImageFile, str]) -> None: ...
|
||||
def draw_text(
|
||||
self,
|
||||
x: int,
|
||||
y: int,
|
||||
text: str,
|
||||
text_color: Color = Color.BLACK,
|
||||
background_color: Optional[Color] = None,
|
||||
) -> None: ...
|
||||
def print(self, *args: Any, sep: str = " ", end: str = "\n") -> None: ...
|
||||
def set_font(self, font: Font) -> None: ...
|
||||
@staticmethod
|
||||
def empty(width: int = 178, height: int = 128) -> Image: ...
|
||||
def save(self, filename: str) -> None: ...
|
||||
|
||||
class Font:
|
||||
DEFAULT: Font
|
||||
def __init__(
|
||||
self,
|
||||
family: Optional[str] = None,
|
||||
size: int = 12,
|
||||
bold: bool = False,
|
||||
monospace: bool = False,
|
||||
lang: Optional[str] = None,
|
||||
script: Optional[str] = None,
|
||||
): ...
|
||||
@property
|
||||
def family(self) -> str: ...
|
||||
@property
|
||||
def style(self) -> str: ...
|
||||
@property
|
||||
def width(self) -> int: ...
|
||||
@property
|
||||
def height(self) -> int: ...
|
||||
def text_width(self, text: str) -> int: ...
|
||||
def text_height(self, text: str) -> int: ...
|
||||
|
||||
class SoundFile:
|
||||
SHOUTING: SoundFile
|
||||
CHEERING: SoundFile
|
||||
CRYING: SoundFile
|
||||
OUCH: SoundFile
|
||||
LAUGHING_2: SoundFile
|
||||
SNEEZING: SoundFile
|
||||
SMACK: SoundFile
|
||||
BOING: SoundFile
|
||||
BOO: SoundFile
|
||||
UH_OH: SoundFile
|
||||
SNORING: SoundFile
|
||||
KUNG_FU: SoundFile
|
||||
FANFARE: SoundFile
|
||||
CRUNCHING: SoundFile
|
||||
MAGIC_WAND: SoundFile
|
||||
LAUGHING_1: SoundFile
|
||||
LEFT: SoundFile
|
||||
BACKWARDS: SoundFile
|
||||
RIGHT: SoundFile
|
||||
OBJECT: SoundFile
|
||||
COLOR: SoundFile
|
||||
FLASHING: SoundFile
|
||||
ERROR: SoundFile
|
||||
ERROR_ALARM: SoundFile
|
||||
DOWN: SoundFile
|
||||
FORWARD: SoundFile
|
||||
ACTIVATE: SoundFile
|
||||
SEARCHING: SoundFile
|
||||
TOUCH: SoundFile
|
||||
UP: SoundFile
|
||||
ANALYZE: SoundFile
|
||||
STOP: SoundFile
|
||||
DETECTED: SoundFile
|
||||
TURN: SoundFile
|
||||
START: SoundFile
|
||||
MORNING: SoundFile
|
||||
EV3: SoundFile
|
||||
GO: SoundFile
|
||||
GOOD_JOB: SoundFile
|
||||
OKEY_DOKEY: SoundFile
|
||||
GOOD: SoundFile
|
||||
NO: SoundFile
|
||||
THANK_YOU: SoundFile
|
||||
YES: SoundFile
|
||||
GAME_OVER: SoundFile
|
||||
OKAY: SoundFile
|
||||
SORRY: SoundFile
|
||||
BRAVO: SoundFile
|
||||
GOODBYE: SoundFile
|
||||
HI: SoundFile
|
||||
HELLO: SoundFile
|
||||
MINDSTORMS: SoundFile
|
||||
LEGO: SoundFile
|
||||
FANTASTIC: SoundFile
|
||||
SPEED_IDLE: SoundFile
|
||||
SPEED_DOWN: SoundFile
|
||||
SPEED_UP: SoundFile
|
||||
BROWN: SoundFile
|
||||
GREEN: SoundFile
|
||||
BLACK: SoundFile
|
||||
WHITE: SoundFile
|
||||
RED: SoundFile
|
||||
BLUE: SoundFile
|
||||
YELLOW: SoundFile
|
||||
TICK_TACK: SoundFile
|
||||
HORN_1: SoundFile
|
||||
BACKING_ALERT: SoundFile
|
||||
MOTOR_IDLE: SoundFile
|
||||
AIR_RELEASE: SoundFile
|
||||
AIRBRAKE: SoundFile
|
||||
RATCHET: SoundFile
|
||||
MOTOR_STOP: SoundFile
|
||||
HORN_2: SoundFile
|
||||
LASER: SoundFile
|
||||
SONAR: SoundFile
|
||||
MOTOR_START: SoundFile
|
||||
INSECT_BUZZ_2: SoundFile
|
||||
ELEPHANT_CALL: SoundFile
|
||||
SNAKE_HISS: SoundFile
|
||||
DOG_BARK_2: SoundFile
|
||||
DOG_WHINE: SoundFile
|
||||
INSECT_BUZZ_1: SoundFile
|
||||
DOG_SNIFF: SoundFile
|
||||
T_REX_ROAR: SoundFile
|
||||
INSECT_CHIRP: SoundFile
|
||||
DOG_GROWL: SoundFile
|
||||
SNAKE_RATTLE: SoundFile
|
||||
DOG_BARK_1: SoundFile
|
||||
CAT_PURR: SoundFile
|
||||
EIGHT: SoundFile
|
||||
SEVEN: SoundFile
|
||||
SIX: SoundFile
|
||||
FOUR: SoundFile
|
||||
TEN: SoundFile
|
||||
ONE: SoundFile
|
||||
TWO: SoundFile
|
||||
THREE: SoundFile
|
||||
ZERO: SoundFile
|
||||
FIVE: SoundFile
|
||||
NINE: SoundFile
|
||||
READY: SoundFile
|
||||
CONFIRM: SoundFile
|
||||
GENERAL_ALERT: SoundFile
|
||||
CLICK: SoundFile
|
||||
OVERPOWER: SoundFile
|
||||
|
||||
class ImageFile:
|
||||
RIGHT: ImageFile
|
||||
FORWARD: ImageFile
|
||||
ACCEPT: ImageFile
|
||||
QUESTION_MARK: ImageFile
|
||||
STOP_1: ImageFile
|
||||
LEFT: ImageFile
|
||||
DECLINE: ImageFile
|
||||
THUMBS_DOWN: ImageFile
|
||||
BACKWARD: ImageFile
|
||||
NO_GO: ImageFile
|
||||
WARNING: ImageFile
|
||||
STOP_2: ImageFile
|
||||
THUMBS_UP: ImageFile
|
||||
EV3: ImageFile
|
||||
EV3_ICON: ImageFile
|
||||
TARGET: ImageFile
|
||||
BOTTOM_RIGHT: ImageFile
|
||||
BOTTOM_LEFT: ImageFile
|
||||
EVIL: ImageFile
|
||||
CRAZY_2: ImageFile
|
||||
KNOCKED_OUT: ImageFile
|
||||
PINCHED_RIGHT: ImageFile
|
||||
WINKING: ImageFile
|
||||
DIZZY: ImageFile
|
||||
DOWN: ImageFile
|
||||
TIRED_MIDDLE: ImageFile
|
||||
MIDDLE_RIGHT: ImageFile
|
||||
SLEEPING: ImageFile
|
||||
MIDDLE_LEFT: ImageFile
|
||||
TIRED_RIGHT: ImageFile
|
||||
PINCHED_LEFT: ImageFile
|
||||
PINCHED_MIDDLE: ImageFile
|
||||
CRAZY_1: ImageFile
|
||||
NEUTRAL: ImageFile
|
||||
AWAKE: ImageFile
|
||||
UP: ImageFile
|
||||
TIRED_LEFT: ImageFile
|
||||
ANGRY: ImageFile
|
||||
+84
-35
@@ -5,10 +5,38 @@
|
||||
Classes to exchange messages between EV3 bricks.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
class Mailbox:
|
||||
def __init__(self, name, connection, encode=None, decode=None):
|
||||
"""Object that represents a mailbox containing data.
|
||||
from typing import abstractmethod, TypeVar, Optional, Callable, Generic
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
class Connection:
|
||||
@abstractmethod
|
||||
def read_from_mailbox(self, name: str) -> bytes:
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
def send_to_mailbox(self, name: str, data: bytes) -> None:
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
def wait_for_mailbox_update(self, name: str) -> None:
|
||||
...
|
||||
|
||||
|
||||
class Mailbox(Generic[T]):
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
connection: Connection,
|
||||
encode: Optional[Callable[[T], bytes]] = None,
|
||||
decode: Optional[Callable[[bytes], T]] = None,
|
||||
):
|
||||
"""Mailbox(name, connection, encode=None, decode=None)
|
||||
|
||||
Object that represents a mailbox containing data.
|
||||
|
||||
You can read data that is delivered by other EV3 bricks, or send data
|
||||
to other bricks that have the same mailbox.
|
||||
@@ -29,16 +57,20 @@ class Mailbox:
|
||||
Function that creates a new Python object from bytes.
|
||||
"""
|
||||
|
||||
def read(self):
|
||||
"""Gets the current value of the mailbox.
|
||||
def read(self) -> T:
|
||||
"""read()
|
||||
|
||||
Gets the current value of the mailbox.
|
||||
|
||||
Returns:
|
||||
The current value or ``None`` if the mailbox is empty.
|
||||
"""
|
||||
return ""
|
||||
|
||||
def send(self, value, brick=None):
|
||||
"""Sends a value to this mailbox on connected devices.
|
||||
def send(self, value: T, brick: Optional[str] = None) -> None:
|
||||
"""send(value, brick=None)
|
||||
|
||||
Sends a value to this mailbox on connected devices.
|
||||
|
||||
Arguments:
|
||||
value:
|
||||
@@ -52,23 +84,28 @@ class Mailbox:
|
||||
There is a problem with the connection.
|
||||
"""
|
||||
|
||||
def wait(self):
|
||||
"""Waits for the mailbox to be updated by remote device."""
|
||||
def wait(self) -> None:
|
||||
"""wait()
|
||||
|
||||
def wait_new(self):
|
||||
"""Waits for a new value to be delivered to the mailbox that is not
|
||||
Waits for the mailbox to be updated by remote device."""
|
||||
|
||||
def wait_new(self) -> T:
|
||||
"""wait_new()
|
||||
|
||||
Waits for a new value to be delivered to the mailbox that is not
|
||||
equal to the current value in the mailbox.
|
||||
|
||||
|
||||
Returns:
|
||||
The new value.
|
||||
"""
|
||||
return object()
|
||||
|
||||
|
||||
class LogicMailbox(Mailbox):
|
||||
def __init__(self, name, connection):
|
||||
"""Object that represents a mailbox containing boolean data.
|
||||
class LogicMailbox(Mailbox[bool]):
|
||||
def __init__(self, name: str, connection: Connection):
|
||||
"""LogicMailbox(name, connection)
|
||||
|
||||
Object that represents a mailbox containing boolean data.
|
||||
|
||||
This works just like a regular :class:`Mailbox`, but values
|
||||
must be ``True`` or ``False``.
|
||||
@@ -83,9 +120,11 @@ class LogicMailbox(Mailbox):
|
||||
"""
|
||||
|
||||
|
||||
class NumericMailbox(Mailbox):
|
||||
def __init__(self, name, connection):
|
||||
"""Object that represents a mailbox containing numeric data.
|
||||
class NumericMailbox(Mailbox[float]):
|
||||
def __init__(self, name: str, connection: Connection):
|
||||
"""NumericMailbox(name, connection)
|
||||
|
||||
Object that represents a mailbox containing numeric data.
|
||||
|
||||
This works just like a regular :class:`Mailbox`, but values must be a
|
||||
number, such as ``15`` or ``12.345``
|
||||
@@ -100,12 +139,14 @@ class NumericMailbox(Mailbox):
|
||||
"""
|
||||
|
||||
|
||||
class TextMailbox(Mailbox):
|
||||
def __init__(self, name, connection):
|
||||
"""Object that represents a mailbox containing text data.
|
||||
class TextMailbox(Mailbox[str]):
|
||||
def __init__(self, name: str, connection: Connection):
|
||||
"""TextMailbox(name, connection)
|
||||
|
||||
Object that represents a mailbox containing text data.
|
||||
|
||||
This works just like a regular :class:`Mailbox`, but data must be a
|
||||
string, such as ``'hello!'`` or ``'My name is EV3'``.
|
||||
string, such as ``'hello!'``.
|
||||
|
||||
This is compatible with the "text" mailbox type in EV3-G.
|
||||
|
||||
@@ -127,14 +168,16 @@ class BluetoothMailboxServer:
|
||||
A "server" waits for a "client" to connect to it.
|
||||
"""
|
||||
|
||||
def __enter__(self):
|
||||
def __enter__(self) -> BluetoothMailboxServer:
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
self.close()
|
||||
def __exit__(self, type, value, traceback) -> None:
|
||||
self.server_close()
|
||||
|
||||
def wait_for_connection(self, count=1):
|
||||
"""Waits for a :class:`BluetoothMailboxClient` on a remote device to
|
||||
def wait_for_connection(self, count: int = 1) -> None:
|
||||
"""wait_for_connection(count=1)
|
||||
|
||||
Waits for a :class:`BluetoothMailboxClient` on a remote device to
|
||||
connect.
|
||||
|
||||
Arguments:
|
||||
@@ -146,8 +189,10 @@ class BluetoothMailboxServer:
|
||||
There was a problem establishing the connection.
|
||||
"""
|
||||
|
||||
def close(self):
|
||||
"""Closes all connections."""
|
||||
def server_close(self) -> None:
|
||||
"""server_close()
|
||||
|
||||
Closes all connections."""
|
||||
|
||||
|
||||
class BluetoothMailboxClient:
|
||||
@@ -159,14 +204,16 @@ class BluetoothMailboxClient:
|
||||
A "client" initiates a connection to a waiting "server".
|
||||
"""
|
||||
|
||||
def __enter__(self):
|
||||
def __enter__(self) -> BluetoothMailboxClient:
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
def __exit__(self, type, value, traceback) -> None:
|
||||
self.close()
|
||||
|
||||
def connect(self, brick):
|
||||
"""Connects to an :class:`BluetoothMailboxServer` on another device.
|
||||
def connect(self, brick: str) -> None:
|
||||
"""connect(brick)
|
||||
|
||||
Connects to an :class:`BluetoothMailboxServer` on another device.
|
||||
|
||||
The remote device must be paired and waiting for a connection. See
|
||||
:meth:`BluetoothMailboxServer.wait_for_connection`.
|
||||
@@ -180,5 +227,7 @@ class BluetoothMailboxClient:
|
||||
There was a problem establishing the connection.
|
||||
"""
|
||||
|
||||
def server_close(self):
|
||||
"""Closes all connections."""
|
||||
def close(self) -> None:
|
||||
"""close()
|
||||
|
||||
Closes all connections."""
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2020 The Pybricks Authors
|
||||
|
||||
from abc import abstractmethod
|
||||
from typing import Callable, Generic, Optional, TypeVar
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
class Connection:
|
||||
@abstractmethod
|
||||
def read_from_mailbox(self, name: str) -> bytes: ...
|
||||
@abstractmethod
|
||||
def send_to_mailbox(self, name: str, data: bytes) -> None: ...
|
||||
@abstractmethod
|
||||
def wait_for_mailbox_update(self, name: str) -> None: ...
|
||||
|
||||
class Mailbox(Generic[T]):
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
connection: Connection,
|
||||
encode: Optional[Callable[[T], bytes]] = None,
|
||||
decode: Optional[Callable[[bytes], T]] = None,
|
||||
): ...
|
||||
def read(self) -> T: ...
|
||||
def send(self, value: T, brick: Optional[str] = None) -> None: ...
|
||||
def wait(self) -> None: ...
|
||||
def wait_new(self) -> T: ...
|
||||
|
||||
class LogicMailbox(Mailbox[bool]):
|
||||
def __init__(self, name, connection: Connection): ...
|
||||
|
||||
class NumericMailbox(Mailbox[float]):
|
||||
def __init__(self, name, connection: Connection): ...
|
||||
|
||||
class TextMailbox(Mailbox[str]):
|
||||
def __init__(self, name, connection: Connection): ...
|
||||
|
||||
class BluetoothMailboxServer(Connection):
|
||||
def __enter__(self) -> BluetoothMailboxServer: ...
|
||||
def __exit__(self, type, value, traceback) -> None: ...
|
||||
def wait_for_connection(self, count: int = 1) -> None: ...
|
||||
def server_close(self) -> None: ...
|
||||
|
||||
class BluetoothMailboxClient(Connection):
|
||||
def __enter__(self) -> BluetoothMailboxClient: ...
|
||||
def __exit__(self, type, value, traceback) -> None: ...
|
||||
def connect(self, brick: str) -> None: ...
|
||||
def close(self) -> None: ...
|
||||
@@ -4,10 +4,10 @@
|
||||
"""Use LEGO® MINDSTORMS® NXT motors and sensors with the EV3 brick."""
|
||||
|
||||
|
||||
from .parameters import Port, Color
|
||||
from .parameters import Port
|
||||
|
||||
from ._common import ColorLight, CommonColorSensor
|
||||
from .iodevices import AnalogSensor
|
||||
from ._common import ColorLight
|
||||
|
||||
|
||||
from typing import Callable, Optional, Tuple
|
||||
@@ -22,7 +22,6 @@ class TouchSensor:
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def pressed(self) -> bool:
|
||||
"""pressed() -> bool
|
||||
@@ -33,7 +32,6 @@ class TouchSensor:
|
||||
``True`` if the sensor is pressed, ``False`` if it is
|
||||
not pressed.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class LightSensor:
|
||||
@@ -45,7 +43,6 @@ class LightSensor:
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def ambient(self) -> int:
|
||||
"""ambient() -> int: %
|
||||
@@ -55,7 +52,6 @@ class LightSensor:
|
||||
Returns:
|
||||
Ambient light intensity, ranging from 0% (dark) to 100% (bright).
|
||||
"""
|
||||
pass
|
||||
|
||||
def reflection(self) -> int:
|
||||
"""reflection() -> int: %
|
||||
@@ -66,54 +62,13 @@ class LightSensor:
|
||||
Reflection, ranging from 0% (no reflection) to 100% (high
|
||||
reflection).
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class ColorSensor(LightSensor):
|
||||
class ColorSensor(CommonColorSensor):
|
||||
"""LEGO® MINDSTORMS® NXT Color Sensor."""
|
||||
|
||||
light = ColorLight()
|
||||
|
||||
def __init__(self, port: Port):
|
||||
"""ColorSensor(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def color(self) -> Color:
|
||||
"""color() -> Color
|
||||
|
||||
Measures the color of a surface.
|
||||
|
||||
Returns:
|
||||
``Color.BLACK``, ``Color.BLUE``, ``Color.GREEN``, ``Color.YELLOW``,
|
||||
``Color.RED``, ``Color.WHITE`` or ``Color.NONE``.
|
||||
"""
|
||||
pass
|
||||
|
||||
def ambient(self) -> int:
|
||||
"""ambient() -> int: %
|
||||
|
||||
Measures the ambient light intensity.
|
||||
|
||||
Returns:
|
||||
Ambient light intensity, ranging from 0% (dark) to 100% (bright).
|
||||
"""
|
||||
pass
|
||||
|
||||
def reflection(self) -> int:
|
||||
"""reflection() -> int: %
|
||||
|
||||
Measures the reflection of a surface using a red light.
|
||||
|
||||
Returns:
|
||||
Reflection, ranging from 0% (no reflection) to 100% (high
|
||||
reflection).
|
||||
"""
|
||||
pass
|
||||
|
||||
def rgb(self) -> Tuple[int, int, int]:
|
||||
"""Measures the reflection of a surface using a red, green, and then a
|
||||
blue light.
|
||||
@@ -122,7 +77,6 @@ class ColorSensor(LightSensor):
|
||||
Tuple of reflections for red, green, and blue light, each
|
||||
ranging from 0.0% (no reflection) to 100.0% (high reflection).
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class UltrasonicSensor:
|
||||
@@ -134,7 +88,6 @@ class UltrasonicSensor:
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def distance(self) -> int:
|
||||
"""distance() -> int: mm
|
||||
@@ -145,7 +98,6 @@ class UltrasonicSensor:
|
||||
Returns:
|
||||
Measured distance.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class SoundSensor:
|
||||
@@ -157,7 +109,6 @@ class SoundSensor:
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def intensity(self, audible_only: bool = True) -> int:
|
||||
"""intensity(audible_only=True) -> int: %
|
||||
@@ -172,7 +123,6 @@ class SoundSensor:
|
||||
Returns:
|
||||
Sound intensity.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class TemperatureSensor:
|
||||
@@ -184,7 +134,6 @@ class TemperatureSensor:
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def temperature(self) -> int:
|
||||
"""temperature() -> float: °C
|
||||
@@ -194,7 +143,6 @@ class TemperatureSensor:
|
||||
Returns:
|
||||
Measured temperature.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class EnergyMeter:
|
||||
@@ -206,7 +154,6 @@ class EnergyMeter:
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def storage(self) -> int:
|
||||
"""storage() -> int: J
|
||||
@@ -216,7 +163,6 @@ class EnergyMeter:
|
||||
Returns:
|
||||
Remaining stored energy.
|
||||
"""
|
||||
pass
|
||||
|
||||
def input(self) -> Tuple[int, int, int]:
|
||||
"""input() -> Tuple[int, int, int]
|
||||
@@ -232,7 +178,6 @@ class EnergyMeter:
|
||||
Voltage (mV), current (mA), and power (mW) measured at the input
|
||||
port.
|
||||
"""
|
||||
pass
|
||||
|
||||
def output(self) -> Tuple[int, int, int]:
|
||||
"""output() -> Tuple[int, int, int]
|
||||
@@ -248,7 +193,6 @@ class EnergyMeter:
|
||||
Voltage (mV), current (mA), and power (mW) measured at the output
|
||||
port.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class VernierAdapter(AnalogSensor):
|
||||
@@ -265,7 +209,6 @@ class VernierAdapter(AnalogSensor):
|
||||
own conversion function. The example given below demonstrates
|
||||
the conversion for the Surface Temperature Sensor.
|
||||
"""
|
||||
pass
|
||||
|
||||
def voltage(self) -> int:
|
||||
"""voltage() -> int: mV
|
||||
@@ -275,7 +218,6 @@ class VernierAdapter(AnalogSensor):
|
||||
Returns:
|
||||
Analog voltage.
|
||||
"""
|
||||
pass
|
||||
|
||||
def conversion(self, voltage: int) -> float:
|
||||
"""conversion(voltage) -> float
|
||||
@@ -291,7 +233,6 @@ class VernierAdapter(AnalogSensor):
|
||||
Returns:
|
||||
Converted sensor value.
|
||||
"""
|
||||
pass
|
||||
|
||||
def value(self) -> float:
|
||||
"""value() -> float
|
||||
@@ -302,4 +243,3 @@ class VernierAdapter(AnalogSensor):
|
||||
Returns:
|
||||
Converted sensor value.
|
||||
"""
|
||||
pass
|
||||
|
||||
+126
-52
@@ -1,12 +1,41 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2018-2020 The Pybricks Authors
|
||||
# Copyright (c) 2018-2022 The Pybricks Authors
|
||||
|
||||
"""Constant parameters/arguments for the Pybricks API."""
|
||||
|
||||
from enum import Enum as _Enum
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import Enum
|
||||
from typing import Union, TYPE_CHECKING
|
||||
import os
|
||||
|
||||
from .geometry import Matrix as _Matrix
|
||||
|
||||
if TYPE_CHECKING or os.environ["SPHINX_BUILD"] == "True":
|
||||
Number = Union[int, float]
|
||||
"""
|
||||
Numbers can be represented as integers or floating point values:
|
||||
|
||||
* Integers (:class:`int <ubuiltins.int>`) are whole numbers
|
||||
like ``15`` or ``-123``.
|
||||
* Floating point values (:class:`float <ubuiltins.float>`) are decimal
|
||||
numbers like ``3.14`` or ``-123.45``.
|
||||
|
||||
If you see :class:`Number` as the argument type, both
|
||||
:class:`int <ubuiltins.int>` and :class:`float <ubuiltins.float>` may be used.
|
||||
|
||||
For example, :func:`wait(15) <pybricks.tools.wait>` and
|
||||
:func:`wait(15.75) <pybricks.tools.wait>` are both allowed. In most functions,
|
||||
however, your input value will be truncated to a whole number anyway. In this
|
||||
example, either command makes the program pause for just 15 milliseconds.
|
||||
|
||||
.. warning::
|
||||
The BOOST Move hub doesn't support floating point numbers due to
|
||||
limited system resources, so only integers can be used on that hub.
|
||||
"""
|
||||
|
||||
|
||||
class _PybricksEnumMeta(type(_Enum)):
|
||||
class _PybricksEnumMeta(type(Enum)):
|
||||
def __dir__(cls):
|
||||
yield "__class__"
|
||||
yield "__name__"
|
||||
@@ -14,7 +43,7 @@ class _PybricksEnumMeta(type(_Enum)):
|
||||
yield member.name
|
||||
|
||||
|
||||
class _PybricksEnum(_Enum, metaclass=_PybricksEnumMeta):
|
||||
class _PybricksEnum(Enum, metaclass=_PybricksEnumMeta):
|
||||
def __dir__(self):
|
||||
yield "__class__"
|
||||
for member in type(self):
|
||||
@@ -30,7 +59,18 @@ class _PybricksEnum(_Enum, metaclass=_PybricksEnumMeta):
|
||||
class Color:
|
||||
"""Light or surface color."""
|
||||
|
||||
def __init__(self, h, s=100, v=100):
|
||||
h: int
|
||||
s: int
|
||||
v: int
|
||||
|
||||
def __init__(self, h: Number, s: Number = 100, v: Number = 100):
|
||||
"""Color(h, s=100, v=100)
|
||||
|
||||
Arguments:
|
||||
h (Number, deg): Hue (0--360)
|
||||
s (Number, %): Saturation.
|
||||
v (Number, %): Brightness value.
|
||||
"""
|
||||
self.h = h % 360
|
||||
self.s = max(0, min(s, 100))
|
||||
self.v = max(0, min(v, 100))
|
||||
@@ -38,25 +78,20 @@ class Color:
|
||||
def __repr__(self):
|
||||
return "Color(h={}, s={}, v={})".format(self.h, self.s, self.v)
|
||||
|
||||
def __eq__(self, other):
|
||||
return (
|
||||
isinstance(other, Color)
|
||||
and self.h == other.h
|
||||
and self.s == other.s
|
||||
and self.v == other.v
|
||||
)
|
||||
def __eq__(self, other: Color) -> bool:
|
||||
...
|
||||
|
||||
def __mul__(self, scale):
|
||||
def __mul__(self, scale: float) -> Color:
|
||||
v = max(0, min(self.v * scale, 100))
|
||||
return Color(self.h, self.s, int(v), self.name)
|
||||
|
||||
def __rmul__(self, scale):
|
||||
def __rmul__(self, scale: float) -> Color:
|
||||
return self.__mul__(scale)
|
||||
|
||||
def __truediv__(self, scale):
|
||||
def __truediv__(self, scale: float) -> Color:
|
||||
return self.__mul__(1 / scale)
|
||||
|
||||
def __floordiv__(self, scale):
|
||||
def __floordiv__(self, scale: int) -> Color:
|
||||
return self.__mul__(1 / scale)
|
||||
|
||||
|
||||
@@ -79,30 +114,30 @@ class Port(_PybricksEnum):
|
||||
"""Port on the programmable brick or hub."""
|
||||
|
||||
# Generic motor/sensor ports
|
||||
A = ord("A")
|
||||
B = ord("B")
|
||||
C = ord("C")
|
||||
D = ord("D")
|
||||
E = ord("E")
|
||||
F = ord("F")
|
||||
A: Port = ord("A")
|
||||
B: Port = ord("B")
|
||||
C: Port = ord("C")
|
||||
D: Port = ord("D")
|
||||
E: Port = ord("E")
|
||||
F: Port = ord("F")
|
||||
|
||||
# NXT/EV3 sensor ports
|
||||
S1 = ord("1")
|
||||
S2 = ord("2")
|
||||
S3 = ord("3")
|
||||
S4 = ord("4")
|
||||
S1: Port = ord("1")
|
||||
S2: Port = ord("2")
|
||||
S3: Port = ord("3")
|
||||
S4: Port = ord("4")
|
||||
|
||||
|
||||
class Stop(_PybricksEnum):
|
||||
"""Action after the motor stops."""
|
||||
|
||||
COAST = 0
|
||||
COAST: Port = 0
|
||||
"""Let the motor move freely."""
|
||||
|
||||
BRAKE = 1
|
||||
BRAKE: Port = 1
|
||||
"""Passively resist small external forces."""
|
||||
|
||||
HOLD = 2
|
||||
HOLD: Port = 2
|
||||
"""Keep controlling the motor to hold it at the commanded angle. This is
|
||||
only available on motors with encoders."""
|
||||
|
||||
@@ -110,39 +145,78 @@ class Stop(_PybricksEnum):
|
||||
class Direction(_PybricksEnum):
|
||||
"""Rotational direction for positive speed or angle values."""
|
||||
|
||||
CLOCKWISE = 0
|
||||
CLOCKWISE: Direction = 0
|
||||
"""A positive speed value should make the motor move clockwise."""
|
||||
|
||||
COUNTERCLOCKWISE = 1
|
||||
COUNTERCLOCKWISE: Direction = 1
|
||||
"""A positive speed value should make the motor move counterclockwise."""
|
||||
|
||||
|
||||
class Button(_PybricksEnum):
|
||||
"""Buttons on a hub or remote."""
|
||||
|
||||
LEFT_DOWN = 1
|
||||
LEFT_MINUS = 1
|
||||
DOWN = 2
|
||||
RIGHT_DOWN = 3
|
||||
RIGHT_MINUS = 3
|
||||
LEFT = 4
|
||||
CENTER = 5
|
||||
RIGHT = 6
|
||||
LEFT_UP = 7
|
||||
LEFT_PLUS = 7
|
||||
UP = 8
|
||||
BEACON = 8
|
||||
RIGHT_UP = 9
|
||||
RIGHT_PLUS = 9
|
||||
BLUETOOTH = 9
|
||||
LEFT_DOWN: Button = 1
|
||||
LEFT_MINUS: Button = 1
|
||||
DOWN: Button = 2
|
||||
RIGHT_DOWN: Button = 3
|
||||
RIGHT_MINUS: Button = 3
|
||||
LEFT: Button = 4
|
||||
CENTER: Button = 5
|
||||
RIGHT: Button = 6
|
||||
LEFT_UP: Button = 7
|
||||
LEFT_PLUS: Button = 7
|
||||
UP: Button = 8
|
||||
BEACON: Button = 8
|
||||
RIGHT_UP: Button = 9
|
||||
RIGHT_PLUS: Button = 9
|
||||
BLUETOOTH: Button = 9
|
||||
|
||||
|
||||
class Side(_PybricksEnum):
|
||||
"""Side of a hub or a sensor."""
|
||||
|
||||
RIGHT = 6
|
||||
FRONT = 0
|
||||
TOP = 8
|
||||
LEFT = 4
|
||||
BACK = 5
|
||||
BOTTOM = 2
|
||||
RIGHT: Side = 6
|
||||
FRONT: Side = 0
|
||||
TOP: Side = 8
|
||||
LEFT: Side = 4
|
||||
BACK: Side = 5
|
||||
BOTTOM: Side = 2
|
||||
|
||||
|
||||
class Icon:
|
||||
UP: _Matrix
|
||||
DOWN: _Matrix
|
||||
LEFT: _Matrix
|
||||
RIGHT: _Matrix
|
||||
ARROW_RIGHT_UP: _Matrix
|
||||
ARROW_RIGHT_DOWN: _Matrix
|
||||
ARROW_LEFT_UP: _Matrix
|
||||
ARROW_LEFT_DOWN: _Matrix
|
||||
ARROW_UP: _Matrix
|
||||
ARROW_DOWN: _Matrix
|
||||
ARROW_LEFT: _Matrix
|
||||
ARROW_RIGHT: _Matrix
|
||||
HAPPY: _Matrix
|
||||
SAD: _Matrix
|
||||
EYE_LEFT: _Matrix
|
||||
EYE_RIGHT: _Matrix
|
||||
EYE_LEFT_BLINK: _Matrix
|
||||
EYE_RIGHT_BLINK: _Matrix
|
||||
EYE_RIGHT_BROW: _Matrix
|
||||
EYE_LEFT_BROW: _Matrix
|
||||
EYE_LEFT_BROW_UP: _Matrix
|
||||
EYE_RIGHT_BROW_UP: _Matrix
|
||||
HEART: _Matrix
|
||||
PAUSE: _Matrix
|
||||
EMPTY: _Matrix
|
||||
FULL: _Matrix
|
||||
SQUARE: _Matrix
|
||||
TRIANGLE_RIGHT: _Matrix
|
||||
TRIANGLE_LEFT: _Matrix
|
||||
TRIANGLE_UP: _Matrix
|
||||
TRIANGLE_DOWN: _Matrix
|
||||
CIRCLE: _Matrix
|
||||
CLOCKWISE: _Matrix
|
||||
COUNTERCLOCKWISE: _Matrix
|
||||
TRUE: _Matrix
|
||||
FALSE: _Matrix
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2020 The Pybricks Authors
|
||||
|
||||
from geometry import Matrix
|
||||
|
||||
class Color:
|
||||
BLACK: Color
|
||||
BLUE: Color
|
||||
BROWN: Color
|
||||
CYAN: Color
|
||||
GRAY: Color
|
||||
GREEN: Color
|
||||
MAGENTA: Color
|
||||
NONE: Color
|
||||
ORANGE: Color
|
||||
RED: Color
|
||||
VIOLET: Color
|
||||
WHITE: Color
|
||||
YELLOW: Color
|
||||
def __init__(self, h: int, s: int = 100, v: int = 100): ...
|
||||
def __eq__(self, other: "Color") -> bool: ...
|
||||
def __mul__(self, scale: float) -> Color: ...
|
||||
def __rmul__(self, scale: float) -> Color: ...
|
||||
def __truediv__(self, scale: float) -> Color: ...
|
||||
def __floordiv__(self, scale: int) -> Color: ...
|
||||
|
||||
class Port:
|
||||
A: Port
|
||||
B: Port
|
||||
C: Port
|
||||
D: Port
|
||||
E: Port
|
||||
F: Port
|
||||
S1: Port
|
||||
S2: Port
|
||||
S3: Port
|
||||
S4: Port
|
||||
|
||||
class Stop:
|
||||
COAST: Stop
|
||||
BRAKE: Stop
|
||||
HOLD: Stop
|
||||
|
||||
class Direction:
|
||||
CLOCKWISE: Direction
|
||||
COUNTERCLOCKWISE: Direction
|
||||
|
||||
class Button:
|
||||
LEFT_DOWN: Button
|
||||
LEFT_MINUS: Button
|
||||
DOWN: Button
|
||||
RIGHT_DOWN: Button
|
||||
RIGHT_MINUS: Button
|
||||
LEFT: Button
|
||||
CENTER: Button
|
||||
RIGHT: Button
|
||||
LEFT_UP: Button
|
||||
LEFT_PLUS: Button
|
||||
UP: Button
|
||||
BEACON: Button
|
||||
RIGHT_UP: Button
|
||||
RIGHT_PLUS: Button
|
||||
BLUETOOTH: Button
|
||||
|
||||
class Side:
|
||||
RIGHT: Side
|
||||
FRONT: Side
|
||||
TOP: Side
|
||||
LEFT: Side
|
||||
BACK: Side
|
||||
BOTTOM: Side
|
||||
|
||||
class Icon:
|
||||
UP: Matrix
|
||||
DOWN: Matrix
|
||||
LEFT: Matrix
|
||||
RIGHT: Matrix
|
||||
ARROW_RIGHT_UP: Matrix
|
||||
ARROW_RIGHT_DOWN: Matrix
|
||||
ARROW_LEFT_UP: Matrix
|
||||
ARROW_LEFT_DOWN: Matrix
|
||||
ARROW_UP: Matrix
|
||||
ARROW_DOWN: Matrix
|
||||
ARROW_LEFT: Matrix
|
||||
ARROW_RIGHT: Matrix
|
||||
HAPPY: Matrix
|
||||
SAD: Matrix
|
||||
EYE_LEFT: Matrix
|
||||
EYE_RIGHT: Matrix
|
||||
EYE_LEFT_BLINK: Matrix
|
||||
EYE_RIGHT_BLINK: Matrix
|
||||
EYE_RIGHT_BROW: Matrix
|
||||
EYE_LEFT_BROW: Matrix
|
||||
EYE_LEFT_BROW_UP: Matrix
|
||||
EYE_RIGHT_BROW_UP: Matrix
|
||||
HEART: Matrix
|
||||
PAUSE: Matrix
|
||||
EMPTY: Matrix
|
||||
FULL: Matrix
|
||||
SQUARE: Matrix
|
||||
TRIANGLE_RIGHT: Matrix
|
||||
TRIANGLE_LEFT: Matrix
|
||||
TRIANGLE_UP: Matrix
|
||||
TRIANGLE_DOWN: Matrix
|
||||
CIRCLE: Matrix
|
||||
CLOCKWISE: Matrix
|
||||
COUNTERCLOCKWISE: Matrix
|
||||
TRUE: Matrix
|
||||
FALSE: Matrix
|
||||
+127
-264
@@ -3,25 +3,28 @@
|
||||
|
||||
"""LEGO® Powered Up motor, sensors, and lights."""
|
||||
|
||||
from typing import Optional
|
||||
from __future__ import annotations
|
||||
|
||||
from ._common import (
|
||||
Keypad as _Keypad,
|
||||
DCMotor as _DCMotor,
|
||||
ColorLight as _ColorLight,
|
||||
Motor as _Motor,
|
||||
LightArray as _LightArray,
|
||||
from typing import TYPE_CHECKING, Collection, Optional, Union, overload, Tuple
|
||||
|
||||
from . import _common
|
||||
from .parameters import (
|
||||
Button as _Button,
|
||||
Color as _Color,
|
||||
Direction as _Direction,
|
||||
Port as _Port,
|
||||
)
|
||||
|
||||
from .parameters import Direction as _Direction, Button as _Button
|
||||
if TYPE_CHECKING:
|
||||
from .parameters import Number as _Number
|
||||
|
||||
|
||||
class DCMotor(_DCMotor):
|
||||
pass
|
||||
class DCMotor(_common.DCMotor):
|
||||
"""LEGO® Powered Up motor without rotation sensors."""
|
||||
|
||||
|
||||
class Motor(_Motor):
|
||||
"""Generic class to control motors with built-in rotation sensors."""
|
||||
class Motor(_common.Motor):
|
||||
"""LEGO® Powered Up motor with rotation sensors."""
|
||||
|
||||
def reset_angle(self, angle: Optional[int]) -> None:
|
||||
"""reset_angle(angle=None)
|
||||
@@ -34,14 +37,13 @@ class Motor(_Motor):
|
||||
Arguments:
|
||||
angle (Number, deg): Value to which the angle should be reset.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Remote:
|
||||
"""LEGO® Powered Up Bluetooth Remote Control."""
|
||||
|
||||
light = _ColorLight()
|
||||
buttons = _Keypad(
|
||||
light = _common.ColorLight()
|
||||
buttons = _common.Keypad(
|
||||
(
|
||||
_Button.LEFT_MINUS,
|
||||
_Button.RIGHT_MINUS,
|
||||
@@ -52,9 +54,12 @@ class Remote:
|
||||
_Button.RIGHT_PLUS,
|
||||
)
|
||||
)
|
||||
addresss: Union[str, None]
|
||||
|
||||
def __init__(self, name=None, timeout=10000):
|
||||
"""When you instantiate this class, the hub will search for a remote
|
||||
def __init__(self, name: Optional[str] = None, timeout: int = 10000):
|
||||
"""Remote(name=None, timeout=10000)
|
||||
|
||||
When you instantiate this class, the hub will search for a remote
|
||||
and connect automatically.
|
||||
|
||||
The remote must be on and ready for a connection, as indicated by a
|
||||
@@ -63,137 +68,77 @@ class Remote:
|
||||
Arguments:
|
||||
name (str): Bluetooth name of the remote. If no name is given,
|
||||
the hub connects to the first remote that it finds.
|
||||
timeout (:ref:`time`): How long to search for the remote.
|
||||
timeout (Number, ms): How long to search for the remote.
|
||||
"""
|
||||
pass
|
||||
|
||||
def name(self, name=None):
|
||||
"""Gets or sets the Bluetooth name of the remote.
|
||||
@overload
|
||||
def name(self, name: str) -> None:
|
||||
...
|
||||
|
||||
If no name is given, this method returns the current name.
|
||||
@overload
|
||||
def name(self) -> str:
|
||||
...
|
||||
|
||||
def name(self, *args):
|
||||
"""name(name)
|
||||
name() -> str
|
||||
|
||||
Sets or gets the Bluetooth name of the remote.
|
||||
|
||||
Arguments:
|
||||
name (str): New Bluetooth name of the remote.
|
||||
name (str): New Bluetooth name of the remote. If no name is given,
|
||||
this method returns the current name.
|
||||
"""
|
||||
|
||||
|
||||
class TiltSensor:
|
||||
"""LEGO® Powered Up Tilt Sensor."""
|
||||
|
||||
def __init__(self, port):
|
||||
"""
|
||||
def __init__(self, port: _Port):
|
||||
"""TiltSensor(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def tilt(self):
|
||||
"""Measures the tilt relative to the horizontal plane.
|
||||
def tilt(self) -> Tuple[int, int]:
|
||||
"""tilt() -> Tuple[int, int]: deg
|
||||
|
||||
Measures the tilt relative to the horizontal plane.
|
||||
|
||||
Returns:
|
||||
(:ref:`angle`, :ref:`angle`): Tuple of pitch and roll angles.
|
||||
Tuple of pitch and roll angles.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class ColorDistanceSensor:
|
||||
class ColorDistanceSensor(_common.CommonColorSensor):
|
||||
"""LEGO® Powered Up Color and Distance Sensor."""
|
||||
|
||||
light = _ColorLight()
|
||||
light = _common.ColorLight()
|
||||
|
||||
def __init__(self, port):
|
||||
"""ColorDistanceSensor(port)
|
||||
def distance(self) -> int:
|
||||
"""distance() -> int: %
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def color(self):
|
||||
"""Scans the color of a surface.
|
||||
|
||||
You choose which colors are detected using the
|
||||
:meth:`.detectable_colors` method. By default, it detects
|
||||
``Color.RED``, ``Color.YELLOW``, ``Color.GREEN``, ``Color.BLUE``,
|
||||
``Color.WHITE``, or ``Color.NONE``.
|
||||
|
||||
:returns:
|
||||
Detected color.
|
||||
:rtype: :class:`Color <.parameters.Color>`
|
||||
"""
|
||||
pass
|
||||
|
||||
def ambient(self):
|
||||
"""Measures the ambient light intensity.
|
||||
|
||||
Returns:
|
||||
:ref:`percentage`: Ambient light intensity, ranging from 0 (dark)
|
||||
to 100 (bright).
|
||||
"""
|
||||
pass
|
||||
|
||||
def reflection(self):
|
||||
"""Measures the reflection of a surface.
|
||||
|
||||
Returns:
|
||||
:ref:`percentage`: Reflection, ranging from 0.0 (no reflection) to
|
||||
100.0 (high reflection).
|
||||
"""
|
||||
pass
|
||||
|
||||
def detectable_colors(self, colors):
|
||||
"""Configures which colors the :meth:`.color` method should detect.
|
||||
|
||||
Specify only colors that you wish to detect in your application.
|
||||
This way, the full-color measurements are rounded to the nearest
|
||||
desired color, and other colors are ignored. This improves reliability.
|
||||
|
||||
If you give no arguments, the currently chosen colors will be returned
|
||||
as a tuple.
|
||||
|
||||
Arguments:
|
||||
colors (list): Tuple of :class:`Color <.parameters.Color>` objects:
|
||||
the colors that you want to detect. You can pick
|
||||
standard colors such as ``Color.MAGENTA``, or provide your own
|
||||
colors like ``Color(h=348, s=96, v=40)`` for even
|
||||
better results. You measure your own colors with the
|
||||
:meth:`.hsv` method.
|
||||
"""
|
||||
pass
|
||||
|
||||
def hsv(self):
|
||||
"""Scans the color of a surface.
|
||||
|
||||
This method is similar to :meth:`.color`, but it gives the full range
|
||||
of hue, saturation and brightness values, instead of rounding it to the
|
||||
nearest detectable color.
|
||||
|
||||
:returns:
|
||||
Measured color. The color is described by a hue (0--359), a
|
||||
saturation (0--100), and a brightness value (0--100).
|
||||
:rtype: :class:`Color <.parameters.Color>`
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def distance(self):
|
||||
"""Measures the relative distance between the sensor and an object
|
||||
Measures the relative distance between the sensor and an object
|
||||
using infrared light.
|
||||
|
||||
Returns:
|
||||
:ref:`relativedistance`: Relative distance ranging from 0 (closest)
|
||||
to 100 (farthest).
|
||||
Distance ranging from 0% (closest) to 100% (farthest).
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class PFMotor(DCMotor):
|
||||
"""Control Power Functions motors with the infrared functionality of the
|
||||
:class:`ColorDistanceSensor <pybricks.pupdevices.ColorDistanceSensor>`."""
|
||||
|
||||
def __init__(self, sensor, channel, color, positive_direction=_Direction.CLOCKWISE):
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
sensor: ColorDistanceSensor,
|
||||
channel: int,
|
||||
color: _Color,
|
||||
positive_direction: _Direction = _Direction.CLOCKWISE,
|
||||
):
|
||||
"""PFMotor(sensor, channel, color, positive_direction=Direction.CLOCKWISE)
|
||||
|
||||
Arguments:
|
||||
sensor (ColorDistanceSensor):
|
||||
@@ -207,193 +152,111 @@ class PFMotor(DCMotor):
|
||||
positive_direction (Direction): Which direction the motor should
|
||||
turn when you give a positive duty cycle value.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class ColorSensor:
|
||||
class ColorSensor(_common.AmbientColorSensor):
|
||||
"""LEGO® SPIKE Color Sensor."""
|
||||
|
||||
lights = _LightArray(3)
|
||||
|
||||
def __init__(self, port):
|
||||
"""
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def color(self, surface=True):
|
||||
"""Scans the color of a surface or an external light source.
|
||||
|
||||
You choose which colors are detected using the
|
||||
:meth:`.detectable_colors` method. By default, it detects
|
||||
``Color.RED``, ``Color.YELLOW``, ``Color.GREEN``, ``Color.BLUE``,
|
||||
``Color.WHITE``, or ``Color.NONE``.
|
||||
|
||||
Arguments:
|
||||
surface (bool): Choose ``true`` to scan the color of objects
|
||||
and surfaces. Choose ``false`` to scan the color of
|
||||
screens and other external light sources.
|
||||
:returns:
|
||||
Detected color.
|
||||
:rtype: :class:`Color <.parameters.Color>`
|
||||
"""
|
||||
pass
|
||||
|
||||
def detectable_colors(self, colors):
|
||||
"""Configures which colors the :meth:`.color` method should detect.
|
||||
|
||||
Specify only colors that you wish to detect in your application.
|
||||
This way, the full-color measurements are rounded to the nearest
|
||||
desired color, and other colors are ignored. This improves reliability.
|
||||
|
||||
If you give no arguments, the currently chosen colors will be returned
|
||||
as a tuple.
|
||||
|
||||
Arguments:
|
||||
colors (list): Tuple of :class:`Color <.parameters.Color>` objects:
|
||||
the colors that you want to detect. You can pick
|
||||
standard colors such as ``Color.MAGENTA``, or provide your own
|
||||
colors like ``Color(h=348, s=96, v=40)`` for even
|
||||
better results. You measure your own colors with the
|
||||
:meth:`.hsv` method.
|
||||
"""
|
||||
pass
|
||||
|
||||
def hsv(self, surface=True):
|
||||
"""Scans the color of a surface or an external light source.
|
||||
|
||||
This method is similar to :meth:`.color`, but it gives the full range
|
||||
of hue, saturation and brightness values, instead of rounding it to the
|
||||
nearest detectable color.
|
||||
|
||||
Arguments:
|
||||
surface (bool): Choose ``true`` to scan the color of objects
|
||||
and surfaces. Choose ``false`` to scan the color of
|
||||
screens and other external light sources.
|
||||
|
||||
:returns:
|
||||
Measured color. The color is described by a hue (0--359), a
|
||||
saturation (0--100), and a brightness value (0--100).
|
||||
:rtype: :class:`Color <.parameters.Color>`
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def ambient(self):
|
||||
"""Measures the ambient light intensity.
|
||||
|
||||
Returns:
|
||||
:ref:`percentage`: Ambient light intensity, ranging from 0 (dark)
|
||||
to 100 (bright).
|
||||
"""
|
||||
pass
|
||||
|
||||
def reflection(self):
|
||||
"""Measures the reflection of a surface.
|
||||
|
||||
Returns:
|
||||
:ref:`percentage`: Reflection, ranging from 0.0 (no reflection) to
|
||||
100.0 (high reflection).
|
||||
"""
|
||||
pass
|
||||
lights = _common.LightArray(3)
|
||||
|
||||
|
||||
class UltrasonicSensor:
|
||||
"""LEGO® SPIKE Color Sensor."""
|
||||
|
||||
lights = _LightArray(3)
|
||||
lights = _common.LightArray(3)
|
||||
|
||||
def __init__(self, port):
|
||||
"""
|
||||
def __init__(self, port: _Port):
|
||||
"""UltrasonicSensor(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def distance(self):
|
||||
"""Measures the distance between the sensor and an object using
|
||||
def distance(self) -> int:
|
||||
"""distance() -> int: mm
|
||||
|
||||
Measures the distance between the sensor and an object using
|
||||
ultrasonic sound waves.
|
||||
|
||||
Returns:
|
||||
:ref:`distance`: Measured distance. If no valid distance was
|
||||
measured, it returns 2000 mm.
|
||||
Measured distance. If no valid distance was measured,
|
||||
it returns 2000 mm.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def presence(self):
|
||||
"""Checks for the presence of other ultrasonic sensors by detecting
|
||||
def presence(self) -> bool:
|
||||
"""presence() -> bool
|
||||
|
||||
Checks for the presence of other ultrasonic sensors by detecting
|
||||
ultrasonic sounds.
|
||||
|
||||
Returns:
|
||||
bool: ``True`` if ultrasonic sounds are detected,
|
||||
``False`` if not.
|
||||
``True`` if ultrasonic sounds are detected, ``False`` if not.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class ForceSensor:
|
||||
"""LEGO® SPIKE Force Sensor."""
|
||||
|
||||
def __init__(self, port):
|
||||
"""
|
||||
def __init__(self, port: _Port):
|
||||
"""ForceSensor(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def force(self):
|
||||
"""Measures the force exerted on the sensor.
|
||||
def force(self) -> float:
|
||||
"""force() -> float: N
|
||||
|
||||
Measures the force exerted on the sensor.
|
||||
|
||||
Returns:
|
||||
:ref:`force`: Measured force (up to approximately 10.00 N).
|
||||
Measured force (up to approximately 10.00 N).
|
||||
"""
|
||||
|
||||
def distance(self):
|
||||
"""Measures by how much the sensor button has moved.
|
||||
def distance(self) -> float:
|
||||
"""distance() -> float: mm
|
||||
|
||||
Measures by how much the sensor button has moved.
|
||||
|
||||
Returns:
|
||||
:ref:`distance`: How much the sensor button has
|
||||
moved (up to approximately 8.00 mm).
|
||||
Movement up to approximately 8.00 mm.
|
||||
"""
|
||||
|
||||
def pressed(self, force=3):
|
||||
"""Checks if the sensor button is pressed.
|
||||
def pressed(self, force: _Number = 3) -> bool:
|
||||
"""pressed(force=3) -> bool
|
||||
|
||||
Checks if the sensor button is pressed.
|
||||
|
||||
Arguments:
|
||||
force (:ref:`force`): Minimum force to be considered pressed.
|
||||
force (Number, N): Minimum force to be considered pressed.
|
||||
|
||||
Returns:
|
||||
bool: ``True`` if the sensor is pressed, ``False`` if it is not.
|
||||
``True`` if the sensor is pressed, ``False`` if it is not.
|
||||
"""
|
||||
|
||||
def touched(self):
|
||||
"""Checks if the sensor is touched.
|
||||
def touched(self) -> bool:
|
||||
"""touched() -> bool
|
||||
|
||||
Checks if the sensor is touched.
|
||||
|
||||
This is similar to :meth:`pressed`, but it detects slight movements of
|
||||
the button even when the measured force is still considered zero.
|
||||
|
||||
Returns:
|
||||
bool: ``True`` if the sensor is touched or pressed, ``False``
|
||||
``True`` if the sensor is touched or pressed, ``False``
|
||||
if it is not.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class ColorLightMatrix:
|
||||
"""
|
||||
LEGO® SPIKE 3x3 Color Light Matrix.
|
||||
"""
|
||||
|
||||
def __init__(self, port):
|
||||
"""
|
||||
def __init__(self, port: _Port):
|
||||
"""ColorLightMatrix(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the device is connected.
|
||||
@@ -401,8 +264,9 @@ class ColorLightMatrix:
|
||||
"""
|
||||
...
|
||||
|
||||
def on(self, colors):
|
||||
"""
|
||||
def on(self, color: Union[_Color, Collection[_Color]]) -> None:
|
||||
"""on(colors)
|
||||
|
||||
Turns the lights on.
|
||||
|
||||
Arguments:
|
||||
@@ -413,9 +277,10 @@ class ColorLightMatrix:
|
||||
"""
|
||||
...
|
||||
|
||||
def off(self):
|
||||
"""
|
||||
Turns all of the lights off.
|
||||
def off(self) -> None:
|
||||
"""off()
|
||||
|
||||
Turns all lights off.
|
||||
"""
|
||||
...
|
||||
|
||||
@@ -423,55 +288,54 @@ class ColorLightMatrix:
|
||||
class InfraredSensor:
|
||||
"""LEGO® Powered Up Infrared Sensor."""
|
||||
|
||||
def __init__(self, port):
|
||||
"""
|
||||
def __init__(self, port: _Port):
|
||||
"""InfraredSensor(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the sensor is connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def reflection(self):
|
||||
"""Measures the reflection of a surface using an infrared light.
|
||||
def reflection(self) -> int:
|
||||
"""reflection() -> int: %
|
||||
|
||||
Measures the reflection of a surface using an infrared light.
|
||||
|
||||
Returns:
|
||||
:ref:`percentage`: Reflection, ranging from 0.0 (no reflection) to
|
||||
100.0 (high reflection).
|
||||
Measured reflection, ranging from 0% (no reflection) to
|
||||
100% (high reflection).
|
||||
"""
|
||||
pass
|
||||
|
||||
def distance(self):
|
||||
"""Measures the relative distance between the sensor and an object
|
||||
def distance(self) -> int:
|
||||
"""distance() -> int: %
|
||||
|
||||
Measures the relative distance between the sensor and an object
|
||||
using infrared light.
|
||||
|
||||
Returns:
|
||||
:ref:`relativedistance`: Relative distance ranging from 0 (closest)
|
||||
to 100 (farthest).
|
||||
Distance ranging from 0% (closest) to 100% (farthest).
|
||||
"""
|
||||
pass
|
||||
|
||||
def count(self):
|
||||
"""Counts the number of objects that have passed by the sensor.
|
||||
def count(self) -> int:
|
||||
"""count() -> int
|
||||
|
||||
Counts the number of objects that have passed by the sensor.
|
||||
|
||||
Returns:
|
||||
int: Number of objects counted.
|
||||
Number of objects counted.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Light:
|
||||
"""LEGO® Powered Up Light."""
|
||||
|
||||
def __init__(self, port):
|
||||
"""
|
||||
def __init__(self, port: _Port):
|
||||
"""Light(port)
|
||||
|
||||
Arguments:
|
||||
port (Port): Port to which the device is connected.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def on(self, brightness: int = 100) -> None:
|
||||
def on(self, brightness: _Number = 100) -> None:
|
||||
"""on(brightness=100)
|
||||
|
||||
Turns on the light at the specified brightness.
|
||||
@@ -485,4 +349,3 @@ class Light:
|
||||
"""off()
|
||||
|
||||
Turns off the light."""
|
||||
pass
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2020-2022 The Pybricks Authors
|
||||
|
||||
from typing import Collection, List, Optional, Tuple, Union
|
||||
|
||||
from ._common import (
|
||||
Keypad,
|
||||
DCMotor as _DCMotor,
|
||||
ColorLight,
|
||||
LightArray,
|
||||
Motor as _Motor,
|
||||
Light as BaseLight,
|
||||
)
|
||||
|
||||
from .parameters import Color, Direction, Port
|
||||
|
||||
class Remote:
|
||||
light: ColorLight
|
||||
buttons: Keypad
|
||||
addresss: Union[str, None]
|
||||
def __init__(self, address: str = None, timeout: int = 10000): ...
|
||||
|
||||
class TiltSensor:
|
||||
def __init__(self, port: Port): ...
|
||||
def tilt(self) -> Tuple[int, int]: ...
|
||||
|
||||
class ColorDistanceSensor:
|
||||
light: ColorLight
|
||||
def __init__(self, port: Port): ...
|
||||
def color(self) -> Optional[Color]: ...
|
||||
def ambient(self) -> int: ...
|
||||
def reflection(self) -> int: ...
|
||||
def detectable_colors(self, colors: Collection[Color]) -> None: ...
|
||||
def hsv(self) -> Color: ...
|
||||
def distance(self) -> int: ...
|
||||
|
||||
class PFMotor(DCMotor):
|
||||
def __init__(
|
||||
self,
|
||||
sensor: ColorDistanceSensor,
|
||||
channel: int,
|
||||
color: Color,
|
||||
positive_direction: Direction = Direction.CLOCKWISE,
|
||||
): ...
|
||||
|
||||
class ColorSensor:
|
||||
lights: LightArray
|
||||
def __init__(self, port: Port): ...
|
||||
def color(self, surface: bool = True) -> Optional[Color]: ...
|
||||
def detectable_colors(self, colors: Collection[Color]) -> None: ...
|
||||
def hsv(self, surface: bool = True) -> Color: ...
|
||||
def ambient(self) -> int: ...
|
||||
def reflection(self) -> int: ...
|
||||
|
||||
class UltrasonicSensor:
|
||||
lights: LightArray
|
||||
def __init__(self, port: Port): ...
|
||||
def distance(self) -> int: ...
|
||||
def presence(self) -> bool: ...
|
||||
|
||||
class ForceSensor:
|
||||
def __init__(self, port: Port): ...
|
||||
def force(self) -> int: ...
|
||||
def distance(self) -> int: ...
|
||||
def pressed(self, force: int = 3) -> bool: ...
|
||||
def touched(self) -> bool: ...
|
||||
|
||||
class ColorLightMatrix:
|
||||
def __init__(self, port: Port) -> None: ...
|
||||
def on(self, color: Union[Color, List[Color]]) -> None: ...
|
||||
def off(self) -> None: ...
|
||||
|
||||
class InfraredSensor:
|
||||
def __init__(self, port: Port): ...
|
||||
def reflection(self) -> int: ...
|
||||
def distance(self) -> int: ...
|
||||
def count(self) -> int: ...
|
||||
|
||||
class Light(BaseLight):
|
||||
def __init__(self, port: Port): ...
|
||||
+87
-56
@@ -3,10 +3,16 @@
|
||||
|
||||
"""Robotics module for the Pybricks API."""
|
||||
|
||||
from ._common import Control as _Control
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Tuple, Optional, overload, TYPE_CHECKING
|
||||
|
||||
from . import _common
|
||||
from .parameters import Stop as _Stop
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .parameters import Number as _Number
|
||||
|
||||
|
||||
class DriveBase:
|
||||
"""A robotic vehicle with two powered wheels and an optional support
|
||||
@@ -25,7 +31,7 @@ class DriveBase:
|
||||
|
||||
"""
|
||||
|
||||
distance_control = _Control()
|
||||
distance_control = _common.Control()
|
||||
"""The traveled distance and drive speed are controlled by a PID
|
||||
controller. You can use this attribute to change its settings.
|
||||
See the :ref:`motor control <settings>` attribute for an overview of
|
||||
@@ -33,7 +39,7 @@ class DriveBase:
|
||||
functionality, but the settings apply to every millimeter driven by the
|
||||
drive base, instead of degrees turned by one motor."""
|
||||
|
||||
heading_control = _Control()
|
||||
heading_control = _common.Control()
|
||||
"""The robot turn angle and turn rate are controlled by a PID
|
||||
controller. You can use this attribute to change its settings.
|
||||
See the :ref:`motor control <settings>` attribute for an overview of
|
||||
@@ -42,7 +48,13 @@ class DriveBase:
|
||||
whole drive base (viewed from the top) instead of degrees turned by one
|
||||
motor."""
|
||||
|
||||
def __init__(self, left_motor, right_motor, wheel_diameter, axle_track):
|
||||
def __init__(
|
||||
self,
|
||||
left_motor: _common.Motor,
|
||||
right_motor: _common.Motor,
|
||||
wheel_diameter: _Number,
|
||||
axle_track: _Number,
|
||||
):
|
||||
"""DriveBase(left_motor, right_motor, wheel_diameter, axle_track)
|
||||
|
||||
Arguments:
|
||||
@@ -50,107 +62,126 @@ class DriveBase:
|
||||
The motor that drives the left wheel.
|
||||
right_motor (Motor):
|
||||
The motor that drives the right wheel.
|
||||
wheel_diameter (:ref:`dimension`): Diameter of the wheels.
|
||||
axle_track (:ref:`dimension`): Distance between the points where
|
||||
wheel_diameter (Number, mm): Diameter of the wheels.
|
||||
axle_track (Number, mm): Distance between the points where
|
||||
both wheels touch the ground.
|
||||
"""
|
||||
|
||||
def drive(self, speed, turn_rate):
|
||||
"""Starts driving at the specified speed and turn rate. Both values are
|
||||
def drive(self, speed: _Number, turn_rate: _Number) -> None:
|
||||
"""drive(speed, turn_rate)
|
||||
|
||||
Starts driving at the specified speed and turn rate. Both values are
|
||||
measured at the center point between the wheels of the robot.
|
||||
|
||||
Arguments:
|
||||
speed (:ref:`linspeed`): Speed of the robot.
|
||||
turn_rate (:ref:`speed`): Turn rate of the robot.
|
||||
speed (Number, mm/s): Speed of the robot.
|
||||
turn_rate (Number, deg/s): Turn rate of the robot.
|
||||
"""
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
"""Stops the robot by letting the motors spin freely."""
|
||||
pass
|
||||
def stop(self) -> None:
|
||||
"""stop()
|
||||
|
||||
def distance(self):
|
||||
"""Gets the estimated driven distance.
|
||||
Stops the robot by letting the motors spin freely."""
|
||||
|
||||
def distance(self) -> int:
|
||||
"""distance() -> int: mm
|
||||
|
||||
Gets the estimated driven distance.
|
||||
|
||||
Returns:
|
||||
:ref:`distance`: Driven distance since last reset.
|
||||
Driven distance since last reset.
|
||||
"""
|
||||
pass
|
||||
|
||||
def angle(self):
|
||||
"""Gets the estimated rotation angle of the drive base.
|
||||
def angle(self) -> int:
|
||||
"""angle() -> int: deg
|
||||
|
||||
Gets the estimated rotation angle of the drive base.
|
||||
|
||||
Returns:
|
||||
:ref:`angle`: Accumulated angle since last reset.
|
||||
Accumulated angle since last reset.
|
||||
"""
|
||||
pass
|
||||
|
||||
def state(self):
|
||||
"""Gets the state of the robot.
|
||||
def state(self) -> Tuple[int, int, int, int]:
|
||||
"""state() -> Tuple[int, int, int, int]
|
||||
|
||||
This returns the current :meth:`.distance`, the drive speed, the
|
||||
:meth:`.angle`, and the turn rate.
|
||||
Gets the state of the robot.
|
||||
|
||||
:returns: Distance, drive speed, angle, turn rate
|
||||
:rtype: (:ref:`distance`, :ref:`linspeed`, :ref:`angle`, :ref:`speed`)
|
||||
Returns:
|
||||
Tuple of distance, drive speed, angle, and turn rate of the robot.
|
||||
"""
|
||||
pass
|
||||
|
||||
def reset(self):
|
||||
"""Resets the estimated driven distance and angle to 0."""
|
||||
pass
|
||||
def reset(self) -> None:
|
||||
"""reset()
|
||||
|
||||
Resets the estimated driven distance and angle to 0."""
|
||||
|
||||
@overload
|
||||
def settings(
|
||||
self, straight_speed, straight_acceleration, turn_rate, turn_acceleration
|
||||
):
|
||||
"""Configures the speed and acceleration used
|
||||
self,
|
||||
straight_speed: Optional[_Number],
|
||||
straight_acceleration: Optional[_Number],
|
||||
turn_rate: Optional[_Number],
|
||||
turn_acceleration: Optional[_Number],
|
||||
) -> None:
|
||||
...
|
||||
|
||||
@overload
|
||||
def settings(self) -> Tuple[int, int, int, int]:
|
||||
...
|
||||
|
||||
def settings(self, *args):
|
||||
"""settings(straight_speed, straight_acceleration, turn_rate, turn_acceleration)
|
||||
settings() -> Tuple[int, int, int, int]
|
||||
|
||||
Configures the speed and acceleration used
|
||||
by :meth:`.straight`, :meth:`.turn`, and :meth:`.curve`.
|
||||
|
||||
If you give no arguments, this returns the current values as a tuple.
|
||||
|
||||
You can only change the settings while the robot is stopped. This is
|
||||
either before you begin driving or after you call :meth:`.stop`.
|
||||
|
||||
Arguments:
|
||||
straight_speed (:ref:`linspeed`): Straight-line speed of the robot.
|
||||
straight_acceleration (:ref:`linacceleration`): Straight-line
|
||||
straight_speed (Number, mm/s): Straight-line speed of the robot.
|
||||
straight_acceleration (Number, mm/s²): Straight-line
|
||||
acceleration and deceleration of the robot.
|
||||
turn_rate (:ref:`speed`): Turn rate of the robot.
|
||||
turn_acceleration (:ref:`acceleration`): Angular acceleration and
|
||||
turn_rate (Number, deg/s): Turn rate of the robot.
|
||||
turn_acceleration (Number, deg/s²): Angular acceleration and
|
||||
deceleration of the robot.
|
||||
"""
|
||||
pass
|
||||
|
||||
def straight(self, distance, then=_Stop.HOLD, wait=True):
|
||||
"""Drives straight for a given distance and then stops.
|
||||
def straight(self, distance: _Number, then=_Stop.HOLD, wait=True) -> None:
|
||||
"""straight(distance, then=Stop.HOLD, wait=True)
|
||||
|
||||
Drives straight for a given distance and then stops.
|
||||
|
||||
Arguments:
|
||||
distance (:ref:`distance`): Distance to travel
|
||||
distance (Number, mm): Distance to travel
|
||||
then (Stop): What to do after coming to a standstill.
|
||||
wait (bool): Wait for the maneuver to complete before continuing
|
||||
with the rest of the program.
|
||||
"""
|
||||
pass
|
||||
|
||||
def turn(self, angle, then=_Stop.HOLD, wait=True):
|
||||
"""Turns in place by a given angle and then stops.
|
||||
def turn(self, angle: _Number, then=_Stop.HOLD, wait=True) -> None:
|
||||
"""turn(angle, then=Stop.HOLD, wait=True)
|
||||
|
||||
Turns in place by a given angle and then stops.
|
||||
|
||||
Arguments:
|
||||
angle (:ref:`angle`): Angle of the turn.
|
||||
angle (Number, deg): Angle of the turn.
|
||||
then (Stop): What to do after coming to a standstill.
|
||||
wait (bool): Wait for the maneuver to complete before continuing
|
||||
with the rest of the program.
|
||||
"""
|
||||
pass
|
||||
|
||||
def curve(self, radius, angle, then=_Stop.HOLD, wait=True):
|
||||
"""Drives an arc along a circle of a given radius, by a given angle.
|
||||
def curve(
|
||||
self, radius: _Number, angle: _Number, then=_Stop.HOLD, wait=True
|
||||
) -> None:
|
||||
"""curve(radius, angle, then=Stop.HOLD, wait=True)
|
||||
|
||||
Drives an arc along a circle of a given radius, by a given angle.
|
||||
|
||||
Arguments:
|
||||
radius (:ref:`dimension`): Radius of the circle.
|
||||
angle (:ref:`angle`): Angle along the circle.
|
||||
radius (Number, mm): Radius of the circle.
|
||||
angle (Number, deg): Angle along the circle.
|
||||
then (Stop): What to do after coming to a standstill.
|
||||
wait (bool): Wait for the maneuver to complete before continuing
|
||||
with the rest of the program.
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2020-2021 The Pybricks Authors
|
||||
|
||||
from typing import Optional, Tuple, overload, Union
|
||||
|
||||
from ._common import Control, Motor
|
||||
from .parameters import Stop
|
||||
|
||||
class DriveBase:
|
||||
distance_control: Control
|
||||
heading_control: Control
|
||||
def __init__(
|
||||
self,
|
||||
left_motor: Motor,
|
||||
right_motor: Motor,
|
||||
wheel_diameter: Union[int, float],
|
||||
axle_track: Union[int, float],
|
||||
): ...
|
||||
def drive(self, speed: int, turn_rate: int) -> None: ...
|
||||
def stop(self) -> None: ...
|
||||
def distance(self) -> int: ...
|
||||
def angle(self) -> int: ...
|
||||
def state(self) -> Tuple[int, int, int, int]: ...
|
||||
def reset(self) -> None: ...
|
||||
@overload
|
||||
def settings(self) -> Tuple[int, int, int, int]: ...
|
||||
@overload
|
||||
def settings(
|
||||
self,
|
||||
straight_speed: Optional[int],
|
||||
straight_acceleration: Optional[int],
|
||||
turn_rate: Optional[int],
|
||||
turn_acceleration: Optional[int],
|
||||
) -> None: ...
|
||||
def straight(self, distance: int) -> None: ...
|
||||
def turn(self, angle: int) -> None: ...
|
||||
def curve(
|
||||
self, radius: int, angle: int, then: Stop = Stop.HOLD, wait: bool = True
|
||||
) -> None: ...
|
||||
+39
-28
@@ -1,17 +1,19 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2018-2020 The Pybricks Authors
|
||||
# Copyright (c) 2018-2022 The Pybricks Authors
|
||||
|
||||
"""Common tools for timing and data logging."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
def wait(time):
|
||||
"""Pauses the user program for a specified amount of time.
|
||||
|
||||
def wait(time: int) -> None:
|
||||
"""wait(time)
|
||||
|
||||
Pauses the user program for a specified amount of time.
|
||||
|
||||
Arguments:
|
||||
time (:ref:`time`): How long to wait.
|
||||
|
||||
time (Number, ms): How long to wait.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class StopWatch:
|
||||
@@ -19,45 +21,54 @@ class StopWatch:
|
||||
feature on your phone."""
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
...
|
||||
|
||||
def time(self):
|
||||
"""Gets the current time of the stopwatch.
|
||||
def time(self) -> int:
|
||||
"""time() -> int: ms
|
||||
|
||||
Gets the current time of the stopwatch.
|
||||
|
||||
Returns:
|
||||
:ref:`time`: Elapsed time.
|
||||
Elapsed time.
|
||||
"""
|
||||
pass
|
||||
|
||||
def pause(self):
|
||||
"""Pauses the stopwatch."""
|
||||
pass
|
||||
def pause(self) -> None:
|
||||
"""pause()
|
||||
|
||||
def resume(self):
|
||||
"""Resumes the stopwatch."""
|
||||
pass
|
||||
Pauses the stopwatch."""
|
||||
|
||||
def reset(self):
|
||||
"""Resets the stopwatch time to 0.
|
||||
def resume(self) -> None:
|
||||
"""resume()
|
||||
|
||||
Resumes the stopwatch."""
|
||||
|
||||
def reset(self) -> None:
|
||||
"""reset()
|
||||
|
||||
Resets the stopwatch time to 0.
|
||||
|
||||
The run state is unaffected:
|
||||
|
||||
* If it was paused, it stays paused (but now at 0).
|
||||
* If it was running, it stays running (but starting again from 0).
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class DataLog:
|
||||
"""Create a file and log data."""
|
||||
|
||||
def __init__(
|
||||
self, *headers, name="log", timestamp=True, extension="csv", append=False
|
||||
self,
|
||||
*headers: str,
|
||||
name: str = "log",
|
||||
timestamp: bool = True,
|
||||
extension: str = "csv",
|
||||
append: bool = False
|
||||
):
|
||||
"""
|
||||
"""DataLog(*headers, name='log', timestamp=True, extension='csv', append=False)
|
||||
|
||||
Arguments:
|
||||
headers (`col1`, `col2`, `...`): Column headers. These are the
|
||||
headers (str, str, ...): Column headers. These are the
|
||||
names of the data columns. For example, choose ``'time'`` and
|
||||
``'angle'``.
|
||||
name (str): Name of the file.
|
||||
@@ -70,12 +81,12 @@ class DataLog:
|
||||
data. If the file does not exist yet, an empty file will be
|
||||
created either way.
|
||||
"""
|
||||
pass
|
||||
|
||||
def log(self, *values):
|
||||
"""Saves one or more values on a new line in the file.
|
||||
def log(self, *values: Any) -> None:
|
||||
"""log(value1, value2, ...)
|
||||
|
||||
Saves one or more values on a new line in the file.
|
||||
|
||||
Arguments:
|
||||
values (object, object, `...`): One or more objects or values.
|
||||
values (object, object, ...): One or more objects or values.
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2020 The Pybricks Authors
|
||||
|
||||
from typing import Any
|
||||
|
||||
def wait(time: int) -> None: ...
|
||||
|
||||
class StopWatch:
|
||||
def time(self) -> int: ...
|
||||
def pause(self) -> None: ...
|
||||
def resume(self) -> None: ...
|
||||
def reset(self) -> None: ...
|
||||
|
||||
class DataLog:
|
||||
def __init__(
|
||||
self,
|
||||
*headers: str,
|
||||
name: str = "log",
|
||||
timestamp: bool = True,
|
||||
extension: str = "csv",
|
||||
append: bool = False
|
||||
): ...
|
||||
def log(self, *values: Any) -> None: ...
|
||||
@@ -25,14 +25,6 @@ This module implements pseudo-random number generators.
|
||||
from typing import Any, Optional, Sequence, overload
|
||||
|
||||
|
||||
[
|
||||
"random",
|
||||
"uniform",
|
||||
]
|
||||
|
||||
# bookkeeping
|
||||
|
||||
|
||||
def seed(a: Optional[int] = None) -> None:
|
||||
"""
|
||||
Initialize the random number generator.
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
This module provides a subset of the standard Python ``sys`` module.
|
||||
"""
|
||||
|
||||
from uio import FileIO
|
||||
from uio import FileIO as _FileIO
|
||||
|
||||
# REVISIT: most functions are excluded since they aren't useful for Pybricks
|
||||
|
||||
stdin: FileIO = FileIO()
|
||||
stdin: _FileIO = _FileIO()
|
||||
"""
|
||||
Stream object (:class:`uio.FileIO`) that receives input from a connected
|
||||
terminal, if any.
|
||||
@@ -25,7 +25,7 @@ Also see :func:`micropython.kbd_intr` to disable ``KeyboardInterrupt`` if you
|
||||
are passing binary data via ``stdin``.
|
||||
"""
|
||||
|
||||
stdout: FileIO = FileIO()
|
||||
stdout: _FileIO = _FileIO()
|
||||
"""
|
||||
Stream object (:class:`uio.FileIO`) that sends output to a connected terminal,
|
||||
if any.
|
||||
@@ -34,7 +34,7 @@ Reading may modify newline characters. Use ``usys.stdout.buffer`` instead if
|
||||
this is undesirable.
|
||||
"""
|
||||
|
||||
stderr: FileIO = FileIO()
|
||||
stderr: _FileIO = _FileIO()
|
||||
"""
|
||||
Alias for :data:`stdout`.
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user