Skip to content

Commit

Permalink
Use enumerations for input constants
Browse files Browse the repository at this point in the history
Also stop importing everything in nxt.sensor. This clobbers the name
space with duplicate names for the same object.
  • Loading branch information
schodet committed Dec 13, 2021
1 parent 69cb422 commit 9118179
Show file tree
Hide file tree
Showing 13 changed files with 478 additions and 339 deletions.
4 changes: 0 additions & 4 deletions docs/api/sensors/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ Work in progress...
.. automodule:: nxt.sensor
:members:

.. automodule:: nxt.sensor.common
:members:
:undoc-members:

.. automodule:: nxt.sensor.analog
:members:
:undoc-members:
Expand Down
59 changes: 52 additions & 7 deletions docs/migration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ use this code before calling any NXT-Python function::
import logging
logging.basicConfig(level=logging.DEBUG)

The :mod:`!nxt` module no longer exports name from sub-modules. In general,
NXT-Python now avoids to have two names for the same object.
The :mod:`!nxt` and :mod:`nxt.sensor` modules no longer exports name from
sub-modules. In general, NXT-Python now avoids to have two names for the same
object.

Output port constants are replaced by enumerations, using the :mod:`enum`
module:
Expand Down Expand Up @@ -72,6 +73,50 @@ NXT-Python 2 NXT-Python 3
You can now create :class:`nxt.motor.Motor` objects using
:meth:`nxt.brick.Brick.get_motor`, however direct creation still works.

Input port constants are replaced by enumerations, using the :mod:`enum`
module. The :mod:`!nxt.sensor.common` module has been removed, its content is
directly available in :mod:`nxt.sensor`:

.. py:currentmodule:: nxt.sensor
=============================== ============================
NXT-Python 2 NXT-Python 3
=============================== ============================
:data:`!PORT_1` :attr:`Port.S1`
:data:`!PORT_2` :attr:`Port.S2`
:data:`!PORT_3` :attr:`Port.S3`
:data:`!PORT_4` :attr:`Port.S4`
:attr:`!Type.NO_SENSOR` :attr:`Type.NO_SENSOR`
:attr:`!Type.SWITCH` :attr:`Type.SWITCH`
:attr:`!Type.TEMPERATURE` :attr:`Type.TEMPERATURE`
:attr:`!Type.REFLECTION` :attr:`Type.REFLECTION`
:attr:`!Type.ANGLE` :attr:`Type.ANGLE`
:attr:`!Type.LIGHT_ACTIVE` :attr:`Type.LIGHT_ACTIVE`
:attr:`!Type.LIGHT_INACTIVE` :attr:`Type.LIGHT_INACTIVE`
:attr:`!Type.SOUND_DB` :attr:`Type.SOUND_DB`
:attr:`!Type.SOUND_DBA` :attr:`Type.SOUND_DBA`
:attr:`!Type.CUSTOM` :attr:`Type.CUSTOM`
:attr:`!Type.LOW_SPEED` :attr:`Type.LOW_SPEED`
:attr:`!Type.LOW_SPEED_9V` :attr:`Type.LOW_SPEED_9V`
:attr:`!Type.HIGH_SPEED` :attr:`Type.HIGH_SPEED`
:attr:`!Type.COLORFULL` :attr:`Type.COLOR_FULL`
:attr:`!Type.COLORRED` :attr:`Type.COLOR_RED`
:attr:`!Type.COLORGREEN` :attr:`Type.COLOR_GREEN`
:attr:`!Type.COLORBLUE` :attr:`Type.COLOR_BLUE`
:attr:`!Type.COLORNONE` :attr:`Type.COLOR_NONE`
:attr:`!Type.COLOREXIT` :attr:`Type.COLOR_EXIT`
:attr:`!Mode.RAW` :attr:`Mode.RAW`
:attr:`!Mode.BOOLEAN` :attr:`Mode.BOOL`
:attr:`!Mode.TRANSITION_CNT` :attr:`Mode.EDGE`
:attr:`!Mode.PERIOD_COUNTER` :attr:`Mode.PULSE`
:attr:`!Mode.PCT_FULL_SCALE` :attr:`Mode.PERCENT`
:attr:`!Mode.CELSIUS` :attr:`Mode.CELSIUS`
:attr:`!Mode.FAHRENHEIT` :attr:`Mode.FAHRENHEIT`
:attr:`!Mode.ANGLE_STEPS` :attr:`Mode.ROTATION`
:attr:`!Mode.MASK` Removed
:attr:`!Mode.MASK_SLOPE` Removed
=============================== ============================


Text String or Binary String
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -131,6 +176,11 @@ From :mod:`nxt.error`:
- :exc:`!FileNotFound` has been renamed to :exc:`FileNotFoundError`.
- :exc:`!ModuleNotFound` has been renamed to :exc:`ModuleNotFoundError`.

Sensors:

- :class:`!nxt.sensor.generic.Color20` has been renamed to
:class:`nxt.sensor.generic.Color`.


Removed
^^^^^^^
Expand Down Expand Up @@ -186,11 +236,6 @@ From :class:`nxt.brick.Brick`:
- :meth:`~Brick.boot` now takes a argument to avoid accidental firmware
erasure.

Sensors:

- :class:`!nxt.sensor.generic.Color20` has been renamed to
:class:`nxt.sensor.generic.Color`.

Other:

- :class:`nxt.motcont.MotCont` methods accept tuple as argument to control
Expand Down
80 changes: 56 additions & 24 deletions nxt/brick.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import nxt.error
import nxt.motor
import nxt.sensor
import nxt.sensor.digital
from nxt.telegram import Opcode, Telegram

__all__ = ["Brick"]
Expand Down Expand Up @@ -271,7 +272,19 @@ def find_modules(self, pattern="*.*"):
finally:
self.module_close(handle)

get_sensor = nxt.sensor.get_sensor
def get_sensor(self, port):
"""Tries to detect the sensor type and return the correct sensor object.
:param nxt.sensor.Port port: Input port identifier.
:return: A sensor object.
:rtype: nxt.sensor.Sensor
:raises nxt.sensor.digital.SearchError: When sensor can not be identified.
Only work for digital sensors with identification information.
"""
base_sensor = nxt.sensor.digital.BaseDigitalSensor(self, port, False)
info = base_sensor.get_sensor_info()
return nxt.sensor.digital.find_class(info)(self, port, check_compatible=False)

def get_motor(self, port):
"""Return a motor object connected to one of the brick output port.
Expand Down Expand Up @@ -372,14 +385,17 @@ def set_output_state(
def set_input_mode(self, port, sensor_type, sensor_mode):
"""Set input port mode on the brick.
:param int port: Input port constant.
:param int sensor_type: Sensor type.
:param int sensor_mode: Sensor mode.
:param nxt.sensor.Port port: Input port identifier.
:param nxt.sensor.Type sensor_type: Sensor type.
:param nxt.sensor.Mode sensor_mode: Sensor mode.
.. warning:: This is a low level function, prefer to use a :mod:`nxt.sensor`
class.
"""
tgram = Telegram(Opcode.DIRECT_SET_IN_MODE, reply_req=False)
tgram.add_u8(port)
tgram.add_u8(sensor_type)
tgram.add_u8(sensor_mode)
tgram.add_u8(port.value)
tgram.add_u8(sensor_type.value)
tgram.add_u8(sensor_mode.value)
self._cmd(tgram)

def get_output_state(self, port):
Expand Down Expand Up @@ -439,15 +455,16 @@ def get_output_state(self, port):
def get_input_values(self, port):
"""Get input port values from the brick.
:param int port: Input port constant.
:param nxt.sensor.Port port: Input port identifier.
:return: A tuple with `port`, `valid`, `calibrated`, `sensor_type`,
`sensor_mode`, `raw_value`, `normalized_value`, `scaled_value`, and
`calibrated_value`. `rotation_count`.
:rtype: (int, int, int, int, int, int, int, int, int)
:rtype: (nxt.sensor.Port, bool, bool, nxt.sensor.Type, nxt.sensor.Mode, int,
int, int, int)
Return value details:
- **port** Input port constant.
- **port** Input port identifier.
- **valid** ``True`` if the value is valid, else ``False``.
- **calibrated** Always ``False``, there is no calibration in NXT firmware.
- **sensor_type** Sensor type.
Expand All @@ -457,15 +474,18 @@ def get_input_values(self, port):
- **scaled_value** Scaled value.
- **calibrated_value** Always normalized value, there is no calibration in NXT
firmware.
.. warning:: This is a low level function, prefer to use a :mod:`nxt.sensor`
class.
"""
tgram = Telegram(Opcode.DIRECT_GET_IN_VALS)
tgram.add_u8(port)
tgram.add_u8(port.value)
tgram = self._cmd(tgram)
port = tgram.parse_u8()
valid = tgram.parse_u8()
calibrated = tgram.parse_u8()
sensor_type = tgram.parse_u8()
sensor_mode = tgram.parse_u8()
port = nxt.sensor.Port(tgram.parse_u8())
valid = tgram.parse_bool()
calibrated = tgram.parse_bool()
sensor_type = nxt.sensor.Type(tgram.parse_u8())
sensor_mode = nxt.sensor.Mode(tgram.parse_u8())
raw_value = tgram.parse_u16()
normalized_value = tgram.parse_u16()
scaled_value = tgram.parse_s16()
Expand All @@ -485,12 +505,15 @@ def get_input_values(self, port):
def reset_input_scaled_value(self, port):
"""Reset scaled value for an input port on the brick.
:param int port: Input port constant.
:param nxt.sensor.Port port: Input port identifier.
This can be used to reset accumulated value for some sensor modes.
.. warning:: This is a low level function, prefer to use a :mod:`nxt.sensor`
class.
"""
tgram = Telegram(Opcode.DIRECT_RESET_IN_VAL)
tgram.add_u8(port)
tgram.add_u8(port.value)
self._cmd(tgram)

def message_write(self, inbox, message):
Expand Down Expand Up @@ -553,30 +576,36 @@ def keep_alive(self):
def ls_get_status(self, port):
"""Get status of last low-speed transaction to a brick input port.
:param int port: Input port constant.
:param nxt.sensor.Port port: Input port identifier.
:return: Number of bytes to read as a result of the transaction.
:rtype: int
:raises nxt.error.I2CPendingError: When transaction is still in progress.
:raises nxt.error.DirectProtocolError: When there is an error on the bus.
.. warning:: This is a low level function, prefer to use a :mod:`nxt.sensor`
class.
"""
tgram = Telegram(Opcode.DIRECT_LS_GET_STATUS)
tgram.add_u8(port)
tgram.add_u8(port.value)
tgram = self._cmd(tgram)
size = tgram.parse_u8()
return size

def ls_write(self, port, tx_data, rx_bytes):
"""Write data to a brick input port using low speed transaction.
:param int port: Input port constant.
:param nxt.sensor.Port port: Input port identifier.
:param bytes tx_data: Data to send.
:param int rx_bytes: Number of bytes to receive.
Function returns immediately. Transaction status can be retrieved using
:meth:`ls_get_status` and result must be read using :meth:`ls_read`.
.. warning:: This is a low level function, prefer to use a :mod:`nxt.sensor`
class.
"""
tgram = Telegram(Opcode.DIRECT_LS_WRITE)
tgram.add_u8(port)
tgram.add_u8(port.value)
tgram.add_u8(len(tx_data))
tgram.add_u8(rx_bytes)
tgram.add_bytes(tx_data)
Expand All @@ -585,16 +614,19 @@ def ls_write(self, port, tx_data, rx_bytes):
def ls_read(self, port):
"""Read result of low speed transaction.
:param int port: Input port constant.
:param nxt.sensor.Port port: Input port identifier.
:return: Data received.
:rtype: bytes
:raises nxt.error.I2CPendingError: When transaction is still in progress.
:raises nxt.error.DirectProtocolError: When there is an error on the bus.
The :meth:`ls_write` function must be called to initiate the transaction.
.. warning:: This is a low level function, prefer to use a :mod:`nxt.sensor`
class.
"""
tgram = Telegram(Opcode.DIRECT_LS_READ)
tgram.add_u8(port)
tgram.add_u8(port.value)
tgram = self._cmd(tgram)
size = tgram.parse_u8()
rx_data = tgram.parse_bytes(size)
Expand Down
Loading

0 comments on commit 9118179

Please sign in to comment.