pw_web: Add docs and few examples for getting started with pigweedjs

Change-Id: I02b7453d8318c59583c5feb73d0e19e9357c8cf5
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/110114
Pigweed-Auto-Submit: Asad Memon <asadmemon@google.com>
Reviewed-by: Anthony DiGirolamo <tonymd@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
diff --git a/pw_web/docs.rst b/pw_web/docs.rst
index c102425..a6eddf9 100644
--- a/pw_web/docs.rst
+++ b/pw_web/docs.rst
@@ -4,24 +4,155 @@
 pw_web
 ---------
 
-Pigweed provides an NPM package with modules to build web UIs for Pigweed
+Pigweed provides an NPM package with modules to build web apps for Pigweed
 devices.
 
 Also included is a basic React app that demonstrates using the npm package.
 
+Getting Started
+===============
 
-Available Modules
-=============================
-Following Pigweed modules are included in the NPM package:
+Installation
+-------------
+If you have a bundler set up, you can install ``pigweedjs`` in your web application by:
 
-- `pw_hdlc <https://pigweed.dev/pw_hdlc/#typescript>`_
-- `pw_rpc <https://pigweed.dev/pw_rpc/ts/>`_
-- `pw_tokenizer <https://pigweed.dev/pw_tokenizer/#typescript>`_
-- `pw_transfer <https://pigweed.dev/pw_transfer/#typescript>`_
+.. code:: bash
+
+   $ npm install --save pigweedjs
+
+
+After installing, you can import modules from ``pigweedjs`` in this way:
+
+.. code:: javascript
+
+   import { pw_rpc, pw_tokenizer, Device, WebSerial } from 'pigweedjs';
+
+Import Directly in HTML
+^^^^^^^^^^^^^^^^^^^^^^^
+
+If you don't want to set up a bundler, you can also load Pigweed directly in
+your HTML page by:
+
+.. code:: html
+
+   <script src="https://unpkg.com/pigweedjs@0.0.5/dist/index.umd.js"></script>
+   <script>
+     const { pw_rpc, pw_hdlc, Device, WebSerial } from Pigweed;
+   </script>
+
+Getting Started
+---------------
+Easiest way to get started is to build pw_system demo and run it on a STM32F429I
+Discovery board. Discovery board is Pigweed's primary target for development.
+Refer to :ref:`target documentation<target-stm32f429i-disc1-stm32cube>` for
+instructions on how to build the demo and try things out.
+
+``pigweedjs`` provides a ``Device`` API which simplifies common tasks. Here is
+an example to connect to device and call ``EchoService.Echo`` RPC service.
+
+.. code:: html
+
+   <h1>Hello Pigweed</h1>
+   <button onclick="connect()">Connect</button>
+   <button onclick="echo()">Echo RPC</button>
+   <br /><br />
+   <code></code>
+   <script src="https://unpkg.com/pigweedjs@0.0.5/dist/index.umd.js"></script>
+   <script src="https://unpkg.com/pigweedjs@0.0.5/dist/protos/collection.umd.js"></script>
+   <script>
+     const { Device } = Pigweed;
+     const { ProtoCollection } = PigweedProtoCollection;
+
+     const device = new Device(new ProtoCollection());
+
+     async function connect(){
+       await device.connect();
+     }
+
+     async function echo(){
+       const [status, response] = await device.rpcs.pw.rpc.EchoService.Echo("Hello");
+       document.querySelector('code').innerText = "Response: " + response;
+     }
+   </script>
+
+pw_system demo uses ``pw_log_rpc``; an RPC-based logging solution. pw_system
+also uses pw_tokenizer to tokenize strings and save device space. Below is an
+example that streams logs using the ``Device`` API.
+
+.. code:: html
+
+   <h1>Hello Pigweed</h1>
+   <button onclick="connect()">Connect</button>
+   <br /><br />
+   <code></code>
+   <script src="https://unpkg.com/pigweedjs@0.0.5/dist/index.umd.js"></script>
+   <script src="https://unpkg.com/pigweedjs@0.0.5/dist/protos/collection.umd.js"></script>
+   <script>
+     const { Device, pw_tokenizer } = Pigweed;
+     const { ProtoCollection } = PigweedProtoCollection;
+     const tokenDBCsv = `...` // Load token database here
+
+     const device = new Device(new ProtoCollection());
+     const detokenizer = new pw_tokenizer.Detokenizer(tokenDBCsv);
+
+     async function connect(){
+       await device.connect();
+       const call = device.rpcs.pw.log.Logs.Listen((msg) => {
+         msg.getEntriesList().forEach((entry) => {
+           const frame = entry.getMessage();
+           const detokenized = detokenizer.detokenizeUint8Array(frame);
+           document.querySelector('code').innerHTML += detokenized + "<br/>";
+         });
+       })
+     }
+   </script>
+
+The above example requires a token database in CSV format. You can generate one
+from the pw_system's ``.elf`` file by running:
+
+.. code:: bash
+
+   $ pw_tokenizer/py/pw_tokenizer/database.py create \
+   --database db.csv out/stm32f429i_disc1_stm32cube.size_optimized/obj/pw_system/bin/system_example.elf
+
+You can then load this CSV in JavaScript using ``fetch()`` or by just copying
+the contents into the ``tokenDBCsv`` variable in the above example.
+
+Modules
+=======
+
+Device
+------
+Device class is a helper API to connect to a device over serial and call RPCs
+easily.
+
+To initialize device, it needs a ``ProtoCollection`` instance. ``pigweedjs``
+includes a default one which you can use to get started, you can also generate
+one from your own ``.proto`` files using ``pw_proto_compiler``.
+
+``Device`` goes through all RPC methods in the provided ProtoCollection. For
+each RPC, it reads all the fields in ``Request`` proto and generates a
+JavaScript function that accepts all the fields as it's arguments. It then makes
+this function available under ``rpcs.*`` namespaced by its package name.
+
+Device has following public API:
+
+- ``constructor(ProtoCollection, WebSerialTransport <optional>, rpcAddress <optional>)``
+- ``connect()`` - Shows browser's WebSerial connection dialog and let's user
+  make device selection
+- ``rpcs.*`` - Device API enumerates all RPC services and methods present in the
+  provided proto collection and makes them available as callable functions under
+  ``rpcs``. Example: If provided proto collection includes Pigweed's Echo
+  service ie. ``pw.rpc.EchoService.Echo``, it can be triggered by calling
+  ``device.rpcs.pw.rpc.EchoService.Echo("some message")``. The functions return
+  a ``Promise`` that resolves an array with status and response.
+
+WebSerialTransport
+------------------
 
 To help with connecting to WebSerial and listening for serial data, a helper
-class is also included under ``WebSerial.WebSerialTransport``. Here is an example
-usage:
+class is also included under ``WebSerial.WebSerialTransport``. Here is an
+example usage:
 
 .. code:: javascript
 
@@ -44,23 +175,25 @@
      }
    });
 
-Installation
-=============
 
-You can install ``pigweedjs`` in your web application by:
+Individual Modules
+==================
+Following Pigweed modules are included in the NPM package:
+
+- `pw_hdlc <https://pigweed.dev/pw_hdlc/#typescript>`_
+- `pw_rpc <https://pigweed.dev/pw_rpc/ts/>`_
+- `pw_tokenizer <https://pigweed.dev/pw_tokenizer/#typescript>`_
+- `pw_transfer <https://pigweed.dev/pw_transfer/#typescript>`_
+
+Web Console
+===========
+
+Pigweed includes a web console that demonstrates `pigweedjs` usage in a
+React-based web app. Web console includes a log viewer and a REPL that supports
+autocomplete. Here's how to run the web console locally:
 
 .. code:: bash
 
-   $ npm install --save pigweedjs
-
-
-Getting Started
-================
-
-After installing, you can import modules from ``pigweedjs`` in this way:
-
-.. code:: javascript
-
-   import { pw_rpc, pw_tokenizer } from 'pigweedjs';
-
-Click on each module above to see its usage.
+   $ cd pw_web/webconsole
+   $ npm install
+   $ npm run dev