The poststation-cli tool

For this next section, we'll use the Command Line Interface tool, poststation-cli. Make sure that:

  1. You've installed the CLI tool
  2. Your poststation server is still running with a simulator device

In a new window, we can verify that we can connect to the server by running the "list devices" command:

$ poststation-cli ls

# Devices

| serial           | name       | interface | connected |
| :--------------- | ---------: | :-------- | :-------- |
| 563BF78B6A56DF04 | QUIRKY-344 | usb       | yes       |

This prints out a table of the devices currently known by poststation.

We can see the same simulator device from the previous chapter, and it is also showing as currently connected.

Top level commands

You can print help with poststation-cli --help:

$ poststation-cli --help
A CLI tool for poststation

Usage: poststation-cli [OPTIONS] <COMMAND>

Commands:
  ls      List devices
  folder  Show paths for configuration, database storage, and the CA certificate for external usage
  device  Interact with a specific device
  help    Print this message or the help of the given subcommand(s)

Options:
  -s, --server <SERVER_ADDR>  A path to the server. Defaults to `127.0.0.1:51837`
      --insecure              When set, a plaintext connection will be made with the server
      --timings               Print timing information
  -h, --help                  Print help
  -V, --version               Print version

We've seen the output of ls already, we'll now focus on the device command, which is the primary way of interacting with connected devices.

The device command

We can see all of the device subcommands with --help:

$ poststation-cli device --help
Interact with a specific device

Usage: poststation-cli device [SERIAL] <COMMAND>

Commands:
  types       View all types used for communicating with a given device
  endpoints   View all endpoints available for communicating with a given device
  topics-out  View all topics published by a given device
  topics-in   View all topics handled by a given device
  logs        View the most recent logs from a given device
  logs-range  View the selected range of logs from a given device
  proxy       Proxy message to device endpoint
  publish     Publish a topic message to a device
  listen      Listen to a given "topic-out" path from a device
  help        Print this message or the help of the given subcommand(s)

Arguments:
  [SERIAL]  Device Serial Number or Name. Can be set via POSTSTATION_SERIAL env var

Options:
  -h, --help  Print help

Here we can fully interact with our device:

  • types will print the types known to the device on all endpoints/topics
  • endpoints will print information about the device's endpoints
  • topics-out will print all topics sent TO the client FROM the server
  • topics-in will print all topics sent TO the server FROM the client
  • logs will print the most recent logs, and logs-range can be used to print a specific range of logs
  • proxy is used to send an endpoint request and get the response from the device
  • publish is used to send a topics-in message to the device
  • listen is used to receive topics-out messages from the device

Common patterns

These device commands each take a common "kinds" of arguments.

Serial Number

We will need to specify what device we want to interact with. We can use the full serial number of our device, in hex format:

$ poststation-cli device 563BF78B6A56DF04 endpoints

Endpoints offered by device 563BF78B6A56DF04

* 'postcard-rpc/ping' => async fn(u32) -> u32
* 'postcard-rpc/schemas/get' => async fn(()) -> SchemaTotals
* 'poststation/unique_id/get' => async fn(()) -> u64
* 'simulator/picoboot/reset' => async fn(())
* 'simulator/status_led/set' => async fn(Rgb8)
* 'simulator/status_led/get' => async fn(()) -> Rgb8

However for convenience, the CLI also supports "fuzzy" matching, on part of the serial number, or on part of the short name.

For example, we can also use the last four digits of the serial number:

$ poststation-cli device DF04 types

Types used by device 563BF78B6A56DF04

* struct Key([u8; 8])
* struct Rgb8 { r: u8, g: u8, b: u8 }
* enum OwnedSchemaData { Type(Schema), Endpoint{ path: String, request_key: Key, response_key: Key}, Topic{ path: String, key: Key, direction: TopicDirection} }
* [u8; 8]
* struct Temperature { temp: f64 }
* enum TopicDirection { ToServer, ToClient }
* struct SchemaTotals { types_sent: u32, endpoints_sent: u32, topics_in_sent: u32, topics_out_sent: u32, errors: u32 }

Or we can use part of the short name, "QUIRKY-344":

$ poststation-cli device quirky topics-out

Topics offered by device 563BF78B6A56DF04

* 'postcard-rpc/schema/data' => Channel<OwnedSchemaData>
* 'postcard-rpc/logging' => Channel<String>
* 'simulator/temperature' => Channel<Temperature>

Path

When we need to specify the path, we can also use "fuzzy" matching. For example, instead of using simulator/status_led/get, we can just say led/get:

$ poststation-cli device quirky proxy led/get '{}'
Response: '{"b":30,"g":20,"r":10}'

However if we aren't specific enough, then we will get an error instead:

$ poststation-cli device quirky proxy led
Given 'led', found:

* 'simulator/status_led/set' => async fn(Rgb8)
* 'simulator/status_led/get' => async fn(()) -> Rgb8

Error: Too many matches, be more specific!

Values

Since postcard is a binary format, the CLI will automatically translate all messages to and from JSON, to make it possible to type on the command line.

As we saw above with device quirky proxy led/get, the CLI printed out:

{"b":30,"g":20,"r":10}

If we want to send a command, we will also need to provide JSON. You may want to use single quotes on your shell, to avoid needing to escape " double quotes.

$ poststation-cli device quirky proxy led/set '{"r": 20, "g": 30, "b": 40}'
Response: 'null'

If an endpoint or topic-in takes () as a value, we can also omit the value entirely. For example, these two commands do the same thing:

$ poststation-cli device quirky proxy led/get '{}'
Response: '{"b":30,"g":20,"r":10}'

$ poststation-cli device quirky proxy led/get
Response: '{"b":30,"g":20,"r":10}'

Don't forget that JSON requires keys to be strings! If you forget this, you'll get an error when poststation trys to convert this:

$ poststation-cli device quirky proxy led/set '{r: 20, g: 30, b: 40}'
Error: 'Dynamic("provided JSON does not match the expected schema for this endpoint")'

Next up

In the next section, we'll explore using the SDK crate, poststation-sdk.