Browse Source

update docs

Oliver Fabel 1 year ago
parent
commit
8db9d9a213
6 changed files with 657 additions and 8 deletions
  1. 16 1
      docs/pages/conf.py
  2. 65 6
      docs/pages/reference.rst
  3. 47 0
      flipperzero/_uart.py
  4. 366 0
      flipperzero/io.py
  5. 162 0
      flipperzero/logging.py
  6. 1 1
      lib/micropython

+ 16 - 1
docs/pages/conf.py

@@ -5,11 +5,26 @@ import sys
 base = pathlib.Path(__file__).parent.parent.parent
 root = base.__str__()
 flipperzero = base.joinpath('flipperzero').__str__()
-now = datetime.datetime.now()
 
 sys.path.append(root)
 sys.path.append(flipperzero)
 
+def copy_dict(source, target):
+    for key, value in source.__dict__.items():
+        target.__dict__[key] = value
+
+import flipperzero.logging
+import logging
+
+copy_dict(flipperzero.logging, logging)
+
+import flipperzero.io
+import io
+
+copy_dict(flipperzero.io, io)
+
+now = datetime.datetime.now()
+
 project = 'uPython'
 copyright = str(now.year) + ', Oliver Fabel'
 author = 'Oliver Fabel'

+ 65 - 6
docs/pages/reference.rst

@@ -416,7 +416,62 @@ Classes
 ~~~~~~~
 
 .. autoclass:: flipperzero.UART
-   :members: read, readline, readlines, write, flush
+   :members: read, readline, readlines, write, flush, close, __enter__, __exit__, __del__
+
+Logging
+-------
+
+Log messages to the Flipper's own logging backend.
+Check out the `Flipper Zero docs <https://docs.flipper.net/development/cli#_yZ2E>`_ on how to reveal them in the CLI.
+Be aware, that you can't change Flipper's global log level from within your script.
+Change the `corresponding settings <https://docs.flipper.net/basics/settings#d5TAt>`_ instead or use the **log** command in the CLI with the desired log level as the first argument.
+
+Levels
+~~~~~~
+
+.. autodata:: logging.TRACE
+.. autodata:: logging.DEBUG
+.. autodata:: logging.INFO
+.. autodata:: logging.WARN
+.. autodata:: logging.ERROR
+.. autodata:: logging.NONE
+.. autodata:: logging.level
+
+Functions
+~~~~~~~~~
+
+.. autofunction:: logging.setLevel
+.. autofunction:: logging.getEffectiveLevel
+.. autofunction:: logging.trace
+.. autofunction:: logging.debug
+.. autofunction:: logging.info
+.. autofunction:: logging.warn
+.. autofunction:: logging.error
+.. autofunction:: logging.log
+
+I/O
+---
+
+Constants
+~~~~~~~~~
+
+.. autodata:: io.SEEK_SET
+.. autodata:: io.SEEK_CUR
+.. autodata:: io.SEEK_END
+
+Functions
+~~~~~~~~~
+
+.. autofunction:: io.open
+
+Classes
+~~~~~~~
+
+.. autoclass:: io.BinaryFileIO
+   :members: name, read, readline, readlines, readable, writable, write, flush, seek, tell, close, __enter__, __exit__, __del__
+
+.. autoclass:: io.TextFileIO
+   :members: name, read, readline, readlines, readable, writable, write, flush, seek, tell, close, __enter__, __exit__, __del__
 
 Built-In
 --------
@@ -424,17 +479,21 @@ Built-In
 The functions in this section are `not` part of the ``flipperzero`` module.
 They're members of the global namespace instead.
 
-.. py:function:: print(*objects, sep=' ', end='\n', file=None, flush=False) -> None
+.. py:function:: print(*objects, sep=' ', end='\n') -> None
 
    The standard Python `print <https://docs.python.org/3/library/functions.html#print>`_ function.
+   Where the output of this function will be redirected depends on how the script is invoked:
+
+      * When invoked from the UI, the output will be sent to the Flipper's log buffer.
+        Check out the `Flipper Zero docs <https://docs.flipper.net/development/cli#_yZ2E>`_ on how to view them in the CLI interface.
+      * In the REPL, the output will be sent to the standard output buffer.
+      * When invoked by the **py** command, the output will be sent to the standard output buffer.
 
    :param objects: The objects to print (mostly a single string).
    :param sep: The separator to use between the objects.
    :param end: The line terminator character to use.
 
    .. versionadded:: 1.0.0
+   .. versionchanged:: 1.5.0
 
-   .. attention::
-      
-      This function prints to the internal log buffer.
-      Check out the `Flipper Zero docs <https://docs.flipper.net/development/cli#_yZ2E>`_ on how to reveal them in the CLI interface.
+      Output redirection, based on script invocation.

+ 47 - 0
flipperzero/_uart.py

@@ -29,6 +29,15 @@ class UART:
 
         with f0.open(f0.UART_MODE_USART, 115200) as uart:
             lines = [line for line in uart]
+    
+    An :class:`UART` instance can be used with a `context manager <https://docs.python.org/3/reference/datamodel.html#with-statement-context-managers>`_:
+
+    .. code-block::
+
+        import flipperzero as f0
+
+        with f0.open(f0.UART_MODE_USART, 115200) as uart:
+            ...
 
     .. hint::
 
@@ -94,6 +103,44 @@ class UART:
         '''
         Flush the transmission buffer to the underlying UART connection.
         This method blocks until all data is sent.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def close(self) -> None:
+        '''
+        Close the UART connection.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def __enter__(self) -> 'UART':
+        '''
+        This method is invoked, when the instance enters a runtime context.
+
+        :returns: The :class:`UART` connection.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def __exit__(self, *args, **kwargs) -> None:
+        '''
+        This method is invoked, when the instance leavs a runtime context.
+        This basically calls :meth:`close` on the instance.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def __del__(self) -> None:
+        '''
+        This method is invoked, when the garbage collector removes the object.
+        This basically calls :meth:`close` on the instance.
+
+        .. versionadded:: 1.5.0
         '''
         pass
 

+ 366 - 0
flipperzero/io.py

@@ -0,0 +1,366 @@
+import typing
+import io
+
+_open = io.open
+
+SEEK_SET: int = 0
+'''
+Set the pointer position relative to the beginning of the stream.
+
+.. versionadded:: 1.5.0
+'''
+
+SEEK_CUR: int = 1
+'''
+Set the pointer position relative to the current position.
+
+.. versionadded:: 1.5.0
+'''
+
+SEEK_END: int = 2
+'''
+Set the pointer position relative to the end of the stream.
+
+.. versionadded:: 1.5.0
+'''
+
+class BinaryFileIO:
+    '''
+    Represents a file, opened in binary mode.
+
+    .. versionadded:: 1.5.0
+    '''
+
+    name: str
+    '''
+    The name of the file.
+
+    .. versionadded:: 1.5.0
+    '''
+
+    readable: bool
+    '''
+    Read-only attribute, indicating if the file is readable.
+    
+    .. versionadded:: 1.5.0
+    '''
+
+    writable: bool
+    '''
+    Read-only attribute, indicating if the file is writable.
+    
+    .. versionadded:: 1.5.0
+    '''
+
+    def read(self, size: int = -1) -> bytes:
+        '''
+        Read from the file. 
+        The method will read up to ``size`` bytes and return them.
+        If ``size`` is not specified, all content up to EOF will be returned.
+        If the internal pointer is already at EOF, an empty byte string ``b''`` will be returned.
+
+        :param size: The maximum number of bytes to read.
+        :returns: Up to ``size`` bytes.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def readline(self, size: int = -1) -> bytes:
+        '''
+        Read and return one line from the file.
+        If ``size`` is specified, at most ``size`` bytes will be read.
+        The line terminator is defined as ``b'\\n'``.
+        The new line character is included in the return value.
+        If the internal pointer is at EOF, an empty byte string ``b''`` will be returned.
+
+        :param size: The maximum number of bytes to read.
+        :returns: Up to ``size`` bytes.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def readlines(self) -> typing.List[bytes]:
+        '''
+        Read and return a list of lines from the file.
+        The line terminator is defined as ``b'\\n'``.
+        The new line character is included in the return value.
+        If the internal pointer is at EOF, an empty list will be returned.
+
+        :returns: A list of bytes.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def write(self, data: bytes) -> int:
+        '''
+        Write the given bytes to the file.
+        The number of written bytes will be returned.
+        This can be less than the length of the provided data.
+
+        :param data: The data to write.
+        :returns: The number of bytes written.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def flush(self) -> None:
+        '''
+        Write the contents of the file buffer to the file on the SD card.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def seek(self, offset: int, whence: int = SEEK_SET) -> int:
+        '''
+        Set the pointer position by the given ``offset``, relative to the position indicated by ``whence``.
+        The new absolute position will be returned.
+
+        :param offset: The offset to use.
+        :param whence: How to interpret the offset (e.g. :const:`SEEK_SET`).
+        :returns: The new absolute position.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def tell(self) -> int:
+        '''
+        Get the current pointer position.
+
+        :returns: The absolute position of the pointer.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def close(self) -> None:
+        '''
+        Close the file handle.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def __enter__(self) -> 'BinaryFileIO':
+        '''
+        This method is invoked, when the instance enters a runtime context.
+
+        :returns: The :class:`BinaryFileIO` instance.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def __exit__(self, *args, **kwargs) -> None:
+        '''
+        This method is invoked, when the instance leavs a runtime context.
+        This basically calls :meth:`close` on the instance.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def __del__(self) -> None:
+        '''
+        This method is invoked, when the garbage collector removes the object.
+        This basically calls :meth:`close` on the instance.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+class TextFileIO:
+    '''
+    Represents a file, opened in text mode.
+
+    .. versionadded:: 1.5.0
+    '''
+
+    name: str
+    '''
+    The name of the file.
+
+    .. versionadded:: 1.5.0
+    '''
+
+    readable: bool
+    '''
+    Read-only attribute, indicating if the file is readable.
+    
+    .. versionadded:: 1.5.0
+    '''
+
+    writable: bool
+    '''
+    Read-only attribute, indicating if the file is writable.
+    
+    .. versionadded:: 1.5.0
+    '''
+
+    def read(self, size: int = -1) -> str:
+        '''
+        Read from the file. 
+        The method will read up to ``size`` characters and return them.
+        If ``size`` is not specified, all content up to EOF will be returned.
+        If the internal pointer is already at EOF, an empty string will be returned.
+
+        :param size: The maximum number of characters to read.
+        :returns: Up to ``size`` characters.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def readline(self, size: int = -1) -> str:
+        '''
+        Read and return one line from the file.
+        If ``size`` is specified, at most ``size`` characters will be read.
+        The line terminator is defined as ``'\\n'``.
+        The new line character is included in the return value.
+        If the internal pointer is at EOF, an empty string will be returned.
+
+        :param size: The maximum number of characters to read.
+        :returns: Up to ``size`` characters.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def readlines(self) -> typing.List[str]:
+        '''
+        Read and return a list of lines from the file.
+        The line terminator is defined as ``'\\n'``.
+        The new line character is included in the return value.
+        If the internal pointer is at EOF, an empty list will be returned.
+
+        :returns: A list of strings.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def write(self, data: str) -> int:
+        '''
+        Write the given string to the file.
+        The number of written characters will be returned.
+        This can be less than the length of the provided data.
+
+        :param data: The data to write.
+        :returns: The number of characters written.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def flush(self) -> None:
+        '''
+        Write the contents of the file buffer to the file on the SD card.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def seek(self, offset: int, whence: int = SEEK_SET) -> int:
+        '''
+        Set the pointer position by the given ``offset``, relative to the position indicated by ``whence``.
+        The new absolute position will be returned.
+
+        :param offset: The offset to use.
+        :param whence: How to interpret the offset (e.g. :const:`SEEK_SET`).
+        :returns: The new absolute position.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def tell(self) -> int:
+        '''
+        Get the current pointer position.
+
+        :returns: The absolute position of the pointer.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def close(self) -> None:
+        '''
+        Close the file handle.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def __enter__(self) -> 'TextFileIO':
+        '''
+        This method is invoked, when the instance enters a runtime context.
+
+        :returns: The :class:`BinaryFileIO` instance.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def __exit__(self, *args, **kwargs) -> None:
+        '''
+        This method is invoked, when the instance leavs a runtime context.
+        This basically calls :meth:`close` on the instance.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+    def __del__(self) -> None:
+        '''
+        This method is invoked, when the garbage collector removes the object.
+        This basically calls :meth:`close` on the instance.
+
+        .. versionadded:: 1.5.0
+        '''
+        pass
+
+def open(path: str, mode: str, *args, **kwargs) -> BinaryFileIO | TextFileIO:
+    '''
+    Open a file on the file system with the specified mode.
+    The file path must always be absolute, beginning with ``/ext``.
+    The following modifiers are available:
+
+    .. list-table::
+        :header-rows: 1
+        :width: 90%
+
+        * - Character
+          - Description
+        * - ``'r'``
+          - Open for reading.
+            This is the default.
+            Will fail, if the file not exists.
+        * - ``'w'``
+          - Open for writing, truncating an existing file first.
+        * - ``'b'``
+          - Open the file in binary mode. 
+            The return value will be a :class:`BinaryFileIO` instance.
+        * - ``'t'``
+          - Open the in text mode.
+            This is the default.
+            The return value will be a :class:`TextFileIO` instance.
+        * - ``'+'``
+          - Open for reading and writing.
+            Will create the file, if it not exists.
+            The pointer will be placed at the end of the file.
+    
+    The modifiers can be combined, e.g. ``'rb+'`` would open a file for reading and writing in binary mode.
+
+    :param path: The path to the file to open.
+    :param mode: How the file should be opened.
+    :param args: Is ignored at the moment.
+    :param kwargs: Is ignored at the moment.
+
+    .. versionadded:: 1.5.0
+    '''
+    return io._open(path, mode, *args, **kwargs)

+ 162 - 0
flipperzero/logging.py

@@ -0,0 +1,162 @@
+import typing
+
+TRACE: int = 6
+'''
+Constant value for the `trace` log level.
+
+.. versionadded:: 1.5.0
+'''
+
+DEBUG: int = 5
+'''
+Constant value for the `debug` log level.
+
+.. versionadded:: 1.5.0
+'''
+
+INFO: int = 4
+'''
+Constant value for the `info` log level.
+
+.. versionadded:: 1.5.0
+'''
+
+WARN: int = 3
+'''
+Constant value for the `warn` log level.
+
+.. versionadded:: 1.5.0
+'''
+
+ERROR: int = 2
+'''
+Constant value for the `error` log level.
+
+.. versionadded:: 1.5.0
+'''
+
+NONE: int = 1
+'''
+Constant value for logging disabled.
+
+.. versionadded:: 1.5.0
+'''
+
+level: int
+'''
+The threshold log level, as set by the :func:`setLevel` function.
+The initial value is set to the :const:`INFO` level.
+
+.. versionadded:: 1.5.0
+
+.. hint::
+
+    Don't change the value of this variable, use :func:`setLevel` instead.
+'''
+
+def setLevel(level: int) -> None:
+    '''
+    Set the current log level of the application.
+
+    :param level: The log level to set (e.g. :const:`INFO`).
+
+    .. versionadded:: 1.5.0
+
+    .. hint::
+
+        This doesn't change the Flipper's effective log level settings.
+        Check out the Flipper's `documentation <https://docs.flipper.net/basics/settings#d5TAt>`_ for details on this topic.
+    '''
+    pass
+
+def getEffectiveLevel() -> int:
+    '''
+    Get the effective log level from the Flipper's settings.
+
+    :returns: The effective log level.
+
+    .. versionadded:: 1.5.0
+    '''
+    pass
+
+def trace(message: str, *args) -> None:
+    '''
+    Log a message with level :const:`TRACE`.
+    The ``message`` argument can be a format string with ``%`` placeholders.
+    No % formatting operation is performed when ``args`` is empty.
+
+    :param message: The message to log.
+    :param args: Values for the % formatting.
+
+    .. versionadded:: 1.5.0
+
+    .. code-block::
+
+        import logging
+
+        value = 42
+
+        logging.trace('value is %d', value)
+    '''
+    pass
+
+def debug(message: str, *args) -> None:
+    '''
+    Log a message with level :const:`DEBUG`.
+    See :func:`trace` for details on the usage.
+
+    :param message: The message to log.
+    :param args: Values for the % formatting.
+
+    .. versionadded:: 1.5.0
+    '''
+    pass
+
+def info(message: str, *args) -> None:
+    '''
+    Log a message with level :const:`INFO`.
+    See :func:`trace` for details on the usage.
+
+    :param message: The message to log.
+    :param args: Values for the % formatting.
+
+    .. versionadded:: 1.5.0
+    '''
+    pass
+
+def warn(message: str, *args) -> None:
+    '''
+    Log a message with level :const:`WARN`.
+    See :func:`trace` for details on the usage.
+
+    :param message: The message to log.
+    :param args: Values for the % formatting.
+
+    .. versionadded:: 1.5.0
+    '''
+    pass
+
+def error(message: str, *args) -> None:
+    '''
+    Log a message with level :const:`ERROR`.
+    See :func:`trace` for details on the usage.
+
+    :param message: The message to log.
+    :param args: Values for the % formatting.
+
+    .. versionadded:: 1.5.0
+    '''
+    pass
+
+def log(level: int, message: str, *args) -> None:
+    '''
+    Log a message with the given log level.
+    See :func:`trace` for details on the usage.
+
+    :param level: The log level to use (e.g. :const:`INFO`).
+    :param message: The message to log.
+    :param args: Values for the % formatting.
+
+    .. versionadded:: 1.5.0
+    '''
+    pass

+ 1 - 1
lib/micropython

@@ -1 +1 @@
-Subproject commit a9aec44c88a78f16160beabb81474c741287a486
+Subproject commit 29091048ae9a613070da21b373062a450f7ecd08