1.. _module-pw_console-embedding: 2 3=============== 4Embedding Guide 5=============== 6 7------------- 8Using embed() 9------------- 10``pw console`` is invoked by calling ``PwConsoleEmbed().embed()`` in your 11own Python script. For a complete example of an embedded device console script see 12:bdg-link-primary-line:`pw_system/py/pw_system/console.py <https://cs.opensource.google/pigweed/pigweed/+/main:pw_system/py/pw_system/console.py>`. 13 14.. automodule:: pw_console.embed 15 :members: PwConsoleEmbed 16 :undoc-members: 17 :show-inheritance: 18 19.. _module-pw_console-embedding-logstore: 20 21.. autoclass:: pw_console.log_store.LogStore 22 :members: __init__ 23 :undoc-members: 24 :show-inheritance: 25 26.. _module-pw_console-embedding-plugins: 27 28Adding Plugins 29============== 30User plugin instances are created before starting-up and passed to the Pigweed 31Console embed instance. Typically, a console is started by creating a 32``PwConsoleEmbed()`` instance, calling customization functions, then calling 33``.embed()`` as shown in `Using embed()`_. Adding plugins functions similarly by 34calling ``add_top_toolbar``, ``add_bottom_toolbar`` or 35``add_window_plugin``. For example: 36 37.. code-block:: python 38 39 # Create plugin instances 40 user_toolbar1 = DeviceStatusToolbar(device=client.client.channel(1)) 41 user_toolbar2 = BandwithToolbar() 42 user_device_window = CustomWindowPlugin() 43 44 console = PwConsoleEmbed( 45 global_vars=local_variables, 46 loggers={ 47 'Device Logs': [logging.getLogger('rpc_device')], 48 'Host Logs': [logging.getLogger()], 49 }, 50 ... 51 ) 52 53 # Add toolbar plugins 54 console.add_top_toolbar(user_toolbar1) 55 console.add_bottom_toolbar(user_toolbar2) 56 57 # Add Window plugins 58 console.add_window_plugin(user_device_window) 59 60 # Start the console 61 console.embed() 62 63------------------- 64Adding Log Metadata 65------------------- 66``pw_console`` can display log messages in a table with justified columns for 67metadata fields provided by :ref:`module-pw_log_tokenized`. 68 69It is also possible to manually add values that should be displayed in columns 70using the ``extra`` keyword argument when logging from Python. See the `Python's 71logging documentation`_ for how ``extra`` works. A dict of name, value pairs can 72be passed in as the ``extra_metadata_fields`` variable. For example, the 73following code will create a log message with two custom columns titled 74``module`` and ``timestamp``. 75 76.. code-block:: python 77 78 import logging 79 80 LOG = logging.getLogger('log_source_1') 81 82 LOG.info( 83 'Hello there!', 84 extra={ 85 'extra_metadata_fields': { 86 'module': 'cool', 87 'timestamp': 1.2345, 88 } 89 } 90 ) 91 92 93--------------------- 94Debugging Serial Data 95--------------------- 96``pw_console`` is often used to communicate with devices using `pySerial 97<https://pythonhosted.org/pyserial/>`_ and it may be necessary to monitor the 98raw data flowing over the wire to help with debugging. ``pw_console`` provides a 99simple wrapper for a pySerial instances that log data for each read and write 100call. 101 102.. code-block:: python 103 104 # Instead of 'import serial' use this import: 105 from pw_console.pyserial_wrapper import SerialWithLogging 106 107 serial_device = SerialWithLogging('/dev/ttyUSB0', 115200, timeout=1) 108 109With the above example each ``serial_device.read`` and ``write`` call will 110create a log message to the ``pw_console.serial_debug_logger`` Python 111logger. This logger can then be included as a log window pane in the 112``PwConsoleEmbed()`` call. 113 114.. code-block:: python 115 116 import logging 117 from pw_console import PwConsoleEmbed 118 119 console = PwConsoleEmbed( 120 global_vars=globals(), 121 local_vars=locals(), 122 loggers={ 123 'Host Logs': [ 124 # Root Python logger 125 logging.getLogger(''), 126 # Your current Python package logger. 127 logging.getLogger(__package__) 128 ], 129 'Device Logs': [ 130 logging.getLogger('usb_gadget') 131 ], 132 'Serial Debug': [ 133 # New log window to display serial read and writes 134 logging.getLogger('pw_console.serial_debug_logger') 135 ], 136 }, 137 app_title='CoolConsole', 138 ) 139 # Then run the console with: 140 console.embed() 141 142.. figure:: images/serial_debug.svg 143 :alt: Serial debug pw_console screenshot. 144 145 Screenshot of issuing an Echo RPC with serial debug logging. 146 147 148.. _Python's logging documentation: https://docs.python.org/3/library/logging.html#logging.Logger.debug 149