Manage your fleet
Artemis is a fleet management system for ESP32 devices running the Toit platform. It connects your devices to the cloud and makes it possible to seamlessly update the firmware, containers, and configurations that run on your devices. It is free for up to ten devices and built to scale.
Artemis is the combination of an on-device service that communicates with a broker in the cloud — and the developer tooling to help orchestrate the devices. It is possible to host your own broker, so all your data and code remains under your control.
Artemis is designed to be reliable and robust. Configuration is treated as code, and none of the servers are critical. As long as the configuration is stored in a reliable system (typically Git), Artemis can recover from a full loss of all servers.
Installation
On your development machine, Artemis is a single command line tool (artemis
).
You can download it from here:
If you download an archive, you should unpack it and put the embedded artemis
or artemis.exe
binary
somewhere on your PATH
. The same applies when you extract the artemis
binary from the macOS artemis.dmg
file.
The Artemis command line tool is a standalone executable written in Toit. Use artemis help
for usage help.
Git
Artemis needs git
to be installed on your system. On most macOS and Linux systems,
git
is already installed. On Windows, you can download and install git
from
git-scm.com.
Signing up and logging in
All users must be authenticated. For OAuth-based authentication you can just sign up and log into Artemis as follows:
or
Alternatively, for email-based authentication, sign up with:
Then, after having confirmed the email address, log in with:
Usually, signing up by OAuth is more convenient, but email-based authentication can be useful
if you want to have multiple accounts. For example, with Google domains anything after
the "+" is discarded. So email+additional@gmail.com
is an alias for email@gmail.com
.
Creating an organization
Every device must belong to an organization. You can create as many organizations as
you want (and there will eventually also be a way to remove them again). You can add an
organization using artemis org add
like this:
The artemis org show
command shows you your organization ID, which is a UUID.
Once you create a new organization it is automatically set as default. You can switch to a different organization with
artemis org default YOUR-ORG-ID
, or by passing the organization id to the commands that need one.
You can add other users to your organization with artemis org members add THEIR-USER-ID
. The
user you want to add can find THEIR-USER-ID with artemis profile show
.
If you want to, you can also change the name in your profile with:
Getting started
Once you've downloaded the command line tool (artemis
),
signed up, and
created an organization,
you're ready to put Artemis on a device and manage it via the cloud.
First steps
Artemis manages fleets of devices. To get started, first you must create an empty fleet in a suitable directory. Go to the directory and run:
This creates three files: fleet.json
, devices.json
, and my-pod.yaml
.
The fleet.json
file holds some metadata and the list of devices in devices.json
is empty. The my-pod.yaml
file is the most interesting to get started.
Artemis lets you describe the functionality and configuration of your devices
in pods, which is a set of containers and the configuration
of the environment they need to run in. Pods can be specified through version control friendly
specification files, so let's start with the simplest
possible specification by putting the following contents into the my-pod.yaml
file:
# yaml-language-server: $schema=https://toit.io/schemas/artemis/pod-specification/v1.json $schema: https://toit.io/schemas/artemis/pod-specification/v1.json name: my-pod sdk-version: v2.0.0-alpha.168 artemis-version: v0.27.0 max-offline: 0s connections: - type: wifi ssid: YOUR WIFI SSID password: YOUR WIFI PASSWORD containers: {}
The first line is a comment and not required. It helps vscode to find the correct schema for the file. If the yaml extension is installed, you will get code completion and diagnostics this way.
If you fill in your WiFi credentials, you have a working specification for a pod
named my-pod
. To make the pod available to your fleet, you will need to upload
it to your broker:
This uploads my-pod
and gives is a few useful tags, so we can find it later. The
fleet has a default
group of devices and in the fleet.json
file, we can specify
that the group uses my-pod@latest
as its pod. Whenever we upload a pod, its latest
tag is automatically updated, so it can be convenient to just refer to that from
the group:
Instead of using the convenient latest
tag, it is often preferable to use tags that do not
change in the fleet.json
file. This makes it possible to reproduce and reason about the
fleet state at any revision of the fleet.json
file. So instead of using my-pod@latest
,
you can use a stable tag like my-pod@v1.0.2
or my-pod@20230515175710-broad-method
.
To get your functionality onto your device, you flash a device with firmware
my-pod@latest
by running:
This flashes the device over the USB serial port and puts both the Toit
platform and the Artemis service onto the device. Once flashed, you
can follow the behavior of your device by monitoring the serial port
using something like jag monitor
(included with Jaguar). It
shows something like this:
rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0030,len:184 load:0x40078000,len:12700 ho 0 tail 12 room 4 load:0x40080400,len:2916 entry 0x400805c4 [toit] INFO: starting <v2.0.0-alpha.69> [toit] INFO: using SPIRAM for heap metadata. [artemis] INFO: starting {device: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} [artemis.scheduler] INFO: job started {job: synchronize} [artemis.synchronize] INFO: connecting [wifi] DEBUG: connecting [wifi] DEBUG: connected [wifi] INFO: network address dynamically assigned through dhcp {ip: 192.168.86.31} [wifi] INFO: dns server address dynamically assigned through dhcp {ip: [192.168.86.1]} [network] INFO: opened [artemis.synchronize] INFO: connected to network [artemis.synchronize] INFO: connected to broker [artemis.synchronize] INFO: synchronized
Once you see that the device succesfully connect to the cloud, you should be ready to check its state:
Artemis also added your device to your fleet as part of running artemis serial flash
,
so you can now check the status of your entire fleet by running:
Great! With a little help from the Artemis service and developer tooling, you have a cloud-managed device capable of running high-level code.
Tinkering with your device
Artemis allows you to change and tinker with the current state of a device without requiring a full firmware update. This makes it possible to change the behavior of a device by adding new functionality (drivers or applications) or by changing configurations.
Such incremental changes are great for development; especially as they are faster to get onto the device and do not even require restarting the device. However, these changes are lost at the next firmware upgrade.
Controlling synchronization
Devices managed by Artemis need to connect to the cloud to receive updated information. The frequency at which they synchronize can be configured by the user.
Devices that connect frequently or all the time are easy
to interact with and manage, but they spend a lot of power on staying connected
all the time. The pod specification in the example my-pod.yaml
does not specify
how often to connect, so Artemis assumes that you want an interactive device.
If you don't need your device to stay connected all the time, you can give it a 'max-offline' setting. This tells the Artemis service that it is okay to be offline for 5m, 1h30m, or 24h without necessarily connecting to the Internet.
You can set this through:
If you monitor the output of your device, you'll see that the device goes to sleep between its cloud synchronizations.
You can go back to the original setting, where the device tries to stay online all the time by giving it a 'max-offline' setting of 0s:
Installing code
Artemis makes it easy to install and uninstall new code on your devices. The code that you install runs in containers, so they are isolated from the rest of the system and can be started and stopped independently of the other parts of the system.
To install new code on your device, you can install a new named container based on a Toit source file:
The container name hello
does not have to match the source file
name hello.toit
and you will use the container name to refer to
the installed container later. There can only be one container with
a given name on a device, so installing another one will replace
the original.
By default containers will run when installed and whenever the device boots, but you can control this behavior by specifying the triggers on the command line. If you only want to run when booting, you can do:
You can also get Artemis to run your containers on a schedule
by triggering them at a specified interval. As an example, you can
install the hello
container and get it to run every 10s
like this:
Any arguments you pass to artemis device container install
after the
source file will be passed as string arguments to main
. If you put
this in args.toit
:
and run:
you should see arguments = [foo, bar]
printed.
Finally, you can always uninstall a container again using:
Updating a single device
If you want to update to a new version of the Toit SDK or benefit from the latest Artemis release, you can do an over-the-air firmware update. Such updates are pushed to the broker in a compressed form and picked up by the device.
Similar to artemis serial flash
, the over-the-air update command also
uses pods, so the common workflow is to change your pod specification file
to reflect the state you want your device in, and then update it to
that through:
You can specify which device to update using a device-id flag (-d
), but most
of the time you just use the default ID that was either set
during flashing, or that can be set with artemis device default
.
Rolling out changes to a fleet
If you've modified the my-pod.yaml
file and you want to make the changes available
to your fleet of devices, you can upload the latest version of your pod using:
If your fleet.json
uses my-pod@latest
, you can ask the fleet
to roll out the changes to your devices using:
If you changed the pod reference in fleet.json
to use a stable tag, then
you need to update that before you run artemis fleet roll-out
:
Because your pods encapsulate the fully configured firmware, this makes it easy to upgrade your containers, the Artemis service, and even the Toit SDK and its associated virtual machine.