Beginnings for a reuseable desktop interface for field-programming of Arduino devices.
Pyes
Pyes is a desktop application for programming embedded devices. It is currently in release 0.1.0.
Its source code can be found at https://github.com/simzes/pyes. Pyes is available with a BSD license; see the repository for more details.
Overview
Pyes is a desktop application that supports straightforward interaction with embedded devices. (Pyes stands for program-your-embedded-system.) It borrows from user interface concepts common in desktop computing, such as clicking on icons to open files, and makes these available for use with embedded devices; with pyes, clicks on icons upload applications to a tethered embedded device, in a sense “opening” the file on the device. This can make embedded devices approachable and usable.
Many embedded devices support configuration, but with interfaces that are complex or confusing for non-technical or untrained users. These sometimes involve button presses and holds, lights, and beeps that aid in navigating through a menu structure. Some devices might provide small screens, with limited visibility and navigation. These interfaces are limited because the devices are limited; the hardware and software to support these can take considerable time to develop, and take up significant resources on the device. With pyes, interactivity is implemented on the desktop-side, removing or reducing on-device resources.
Pyes is provided as an application template; it is filled in with a provider’s details and any customizations. Pyes supports uploading of a provided catalog onto any supported board; this catalog can be updated remotely. Facilities for customization are currently primitive, and brittle with any upstream changes to resource files; this will be addressed in the future.
Pyes is written in javascript, and is built on top of vue and node. Electron provides the desktop application framework; this packages the javascript code into a desktop application and installer that works on all platforms.
Pyes supports a number of boards in the Arduino environment. Internally, pyes relies on avrgirl-arduino for flashing arduino boards, and is limited to the boards supported by this package. See: https://github.com/noopkat/avrgirl-arduino#how-do-i-use-it.
Pyes is currently in release version 0.1.0; its development is just beginning. See the future features and release map below for information on future plans.
Gallery
Demo landing page
Each program becomes a titled icon you can click and select.
Landing page after failed upload
When an icon is selected, its description fills in the sidebar. Above the description is feedback from a failed upload (no leonardo was plugged in).
Main Components
Important Files
-
config.json (
static/config.json
)The config file holds all customizable behavior outside of editing source code. This is a few details about the application window, and the remote catalog’s github location.
-
The package file is used by yarn to describe the application’s dependencies, and by electron-builder to package the application into an executable and installer. This is where the application’s program name and details for registering with the desktop system are found.
-
The index.js file is the application’s main process. It starts the interface process, loads all content from disk and the remote catalog, and handles uploads.
-
App.vue (
src/renderer/App.vue
)The interface code is entirely contained in the App.vue file; the html at the top, the vue instance’s javascript in the middle, and the css at the bottom.
-
index.json (
static/catalog/index.json
)The index describes the catalog rooted in its base directory. It lists each program available, and their resources, and some details about the catalog source. The same catalog format for the remote catalog’s index file.
-
The images in this folder are the icons for the app for each system; because of slight differences in requirements, one is present for each system.
Main Process
The main process code is located in src/main/index.js
. It is responsible for starting the renderer/interface process, loading the catalog, updating the remote catalog, and performing device uploads.
Interface Process
The interface process (renderer process, in electron terms) is located in src/renderer/App.vue
, where a vue instance links with html and css to create the interface’s webpage. On start-up, it requests the catalog from the main process, and displays it. It responds to user navigation requests, and requests uploads of catalog.
Configuration
Pyes’s behavior can be modified by changing the configuration file in static/config.json
. The config file example below has been annotated to explain behaviors:
{
"window": { // config values for the application window's behavior
"title": "your title here (from config)", // the window frame's title
"width": 900, // the initial width of the window
"height": 600 // the initial height of the window
},
"remote_catalog": { // config values for the remote catalog
// if stanza is completely absent, no remote updates are enabled
"enable_updates": true, // default is true; if set to false, updates are disabled
"username": "simzes", // github username/repository/branch where the remote catalog is
"repository": "test-bitty-catalog",
"branch": "test-pyes"
}
}
The default version of the pyes configuration is here: https://github.com/simzes/pyes/blob/master/static/config.json.
Catalog
A catalog defines a collection of programs presented to the user, what arduino board works with these programs, and other details about the author and source.
For each program, called an “entry”, several pieces of information tell the user about the program. These are an icon, its title, and an extended description. The icon is any image type that an html <img src="...">
element can use as its source. The description is a markdown file, shown in the selection sidebar when selected. A path to the binary file tells pyes which file to upload.
By convention, resources for each program are located in a unique folder, with the icon/description/binary files located relative to this. An example annotated program entry is below:
{
"path": "donkey", // path from catalog base to this entry
"title": "Wish I was a donkey", // program title (displayed under icon)
"icon": "donkey.jpg", // relative path to the icon file
"description": "donkey.md", // path to the markdown file
"binary": "donkey.hex" // path to the binary
}
The "upload"
stanza tells avrgirl which arduino board to use. The full list is here: https://github.com/noopkat/avrgirl-arduino#how-do-i-use-it
"upload": {
"board": "leonardo"
}
Finally, several details are present in the "source"
stanza; for remote updates to occur, the version field must change with catalog changes:
"source": {
"name": "name of the catalog",
"version": "0.1.0",
"homepage": "wheretogo.com",
"license": "type of license",
"author": "simzes",
"brief": "stuff that will display if there's no markdown",
"description": "landing.md"
}
A complete example of a catalog index is here: https://github.com/simzes/pyes/blob/master/static/catalog/index.json.
Tasks and Workflows
Downloading and setting up pyes
Pyes should be downloaded as a git clone. To do this, create a new directory for your application, and inside it run: git clone https://github.com/simzes/pyes.git .
After this download, install the tools pyes needs to run and build; at a minimum, these are git, node and yarn. Windows and mac environments may need additional setup to enable developer modes. For mac, be sure to install xcode; there are some instructions here.
Once these have been installed, run yarn install
to install all node and electron dependencies.
Finally, run yarn dev
to run the developer application instance. If all is well, an application window with the default catalog will appear.
Building pyes
Once pyes has been downloaded, its dependencies installed, and yarn dev
successfully runs the developer application, pyes can be built into a desktop installer. At this time, cross-platform builds are not supported, and each platform build must be carried out on that platform.
To build pyes into an installer, run: yarn build-<platform>
where <platform>
is “mac”, “linux”, or “windows”. If all is well, this will produce an installer executable in build/
.
Because of some library limitations, the command yarn run electron-rebuild
may need to be run before yarn build
.
Filling in details for an application
Several fields can be customized in package.json
. These are the application name, author, homepage, and description, among others. The configuration file, in static/config.json
specifies the app’s displayed window title in the window/title
field.
Customizing System Icons
Pyes has a default icon of a smiling paperclip over a green background. This can be replaced.
In icons/
, one icon each is present and named for mac, windows, and linux. These names are referenced in package.json
; while these parameters may be renamed, it may be easier to rename or link the image into the currently named location.
Currently, only square icons are supported well; this can be changed in the css. (As is, rectangular icons are squished into a square, ignoring the aspect ratio.)
Because of icon ugliness across platforms, getting things right is tricky. This recipe works well to copy one icon into a file per platform:
- start with an icon in
.png
format, and make its canvas size 512x512 pixels. (The 256x256 and 1024x1024 sizes also work.) You may need to scale and crop the image to do this. Details vary widely between photo editing applications; over here, the gimp program worked with:- scaling the image setting the smaller leg as the desired pixel size (Image>Scale Image)
- cropping to a rough square (rectangular select, Image>Crop to Selection)
- setting the canvas size (Image>Canvas Size) in both dimensions (press enter after each).
- copy this now-square icon into both
icon/icon.png
andicon/linux_icon512x512.png
. (If you used a different size, use this instead of...512x512.png
.) - convert the icon to
.ico
andicns
, and copy these images intowindows_icon.icns
andmac_icon.ico
. Some image editors support.icons
, but few support.ico
. This online tool supports both these conversions: https://iconverticons.com/online/.
Customizing CSS
Pyes’ CSS is specified at the bottom of App.vue (src/renderer/App.vue
).
The application window is laid out with this scheme; here, css class names are followed by the element type, with a description of its contents:
body
: the root element of the window. (Seesrc/index.ejs
for the html frame.).appWindow
:<div>
un-annotated css, but the parent of all elements listed below..catalogPane
:<div>
program catalog.entryTile
:<div>
program entry.entryImage
:<img>
program icon.entryTitle
:<h3>
program title
.selectedEntryTile
:<div>
selected program entry class; applied in addition to.entryTile
, when a tile is selected.
.selectionPane
:<div>
selected program and upload button.uploadBlock
:<div>
upload button and feedback.uploadButton
:<button>
upload button.uploadText
:<h3>
with “Upload” text.uploadFeeback
:<div>
user feedback in “Loading…” text (feedback is displayed in an unclassed<p>
)
.selectionTile
:<div>
selected program details.selectionTitle
:<h3>
selected program title.selectionDescription
:<div>
selected program description, containing converted markdown or text.
Visually, this looks like this:
Setting up a preinstalled catalog
The preinstalled catalog is sourced from the static/catalog
directory; this is built into installed applications, and shown to users until a remote catalog is downloaded.
Catalog entries must be registered in the catalog’s index.json
file, and placed in subdirectories of static/catalog
.
Linking a remote catalog
A remote catalog can be linked into the application in the "remote_catalog"
object, found in static/config.json
; this specifies the github user, repository, and branch where the remote catalog is located. The index.json
file must be in the base directory of this repository, and match the relative directory structure used in the preinstalled catalog.
Updating a remote catalog
Pyes checks for remote catalog updates when it starts up, and downloads it whenever the remote’s version differs from the catalog located on disk. If the catalog is valid, it is displayed to the user when the application starts up next.
To update a catalog, make any modifications to the catalog’s contents and index, and update the version listed in the index before pushing to github.
Testing a remote catalog update
It’s a good idea to test a remote catalog before pushing it out to user applications. This can be done in two ways; both are recommended. For both, any issues will show up in the application’s output. This can be viewed by running the application from the command line.
- Test the remote catalog update as a preinstalled catalog.
To do this, copy the directory contents into the application’s
static/catalog/
directory. Then, with the configuration parameterremote_catalog/enable_updates
set tofalse
, run the application in developer and installed modes. If the desired catalog appears, it is all set. (The modifications to the catalog can be undone by runninggit checkout static/catalog
.) - Test the remote catalog update in a test branch
Pyes can use a different github branch as its remote catalog, allowing a test branch can be tested separately before all user applications. To do this, create a github branch containing the catalog updates; instead of pushing to the branch listed in the user application configs, push to a new remote branch. Then, with this branch listed in the config parameter
remote_catalog/<branch>
(andenable_updates
set to true), run the development and installed application; on its second launch, the application should list the catalog.
Future Features and Release Roadmap
Past Releases and Key Features
0.1.0
-
One catalog is displayed in the interface, with selections displaying additional info in the sidebar. Catalogs declare their board type.
-
Installed applications are configured to track a github branch for updates, and download and show these instead of the preinstalled catalog.
Planned Future Releases and Features
0.2.0
-
basic catalog info
The catalog information is not currently displayed; this would add an info icon, and a page that allows viewing of this information.
-
catalog branch/tag/commit access through the application interface
The ability to release a catalog variant to a separate branch, and allow a user to change the catalog view, will support device prototypers in customizing their software for users.
-
auto-generation of catalog indices
The catalog index is picky, and mostly follows a straightforward pattern. A tool to generate the index would make catalogs easier to work with.
-
command-line validation of catalog
The process for validating a catalog is currently manual. A tool to check this will make the release process easier.
Future Features
-
provider build tools
The catalog must currently be manually sourced through the arduino IDE: after a program source is changed, a program binary must be accessed from the IDE or its build space, and copied into the catalog. For a larger catalog, this can be time-consuming.
This feature would support automated production of compiled binaries.
-
zipped catalog
The process for locating and downloading catalog entry files is complicated and restricts inclusion of other resources; each entry has only three file resources, and any others, such as an image referenced in a markdown description, must be hosted elsewhere. (Then they also can’t be accessed offline.)
Supporting a catalog placed in a single zip file would make it straightforward to reference other resources, relative to a catalog’s base directory.
-
internal catalog resource serving
Currently, all files served in the interface are referenced with fully-qualified file paths; this qualification is done by the main process, and prevents the catalog issuer from including other resources as the main process must know about them. Spawning a small web server inside the main process would allow straightforward serving of relative catalog resources.
-
full screen info
Program info is limited to the sidebar; making this optionally full-screen makes learning about a program easier. This feature would add a full-screen icon to the sidebar.
-
catalog folder navigation
Programs are displayed in a flat directory. Sometimes, logical grouping in a directory structure can be useful.
-
application updates
Electron provides built-in support for updating applications and running a release server. This can be built into the pyes template.
-
third-party and additional catalogs
For some devices, a community of programs may be useful and appropriate; this would allow other users to share device customizations.
-
configuration of programs over serial
Fixed program binaries are useful, but many programs need configuration. This extension would allow programs to declare a configuration form, and receive changes over USB. Device code to support receiving/sending current configuration values can be generated from this configuration declaration.
-
mount code in and out
Some users may want to make their own modifications to the source code; because electron data is hidden in a separate folder, these programs are more accessible if they are linked into a user location. Alternately, on-disk catalogs/programs can be linked into pyes’s interface.
-
configuration of programs via compiled-in macros/values
Many programs can’t support permanent storage of values received over serial; adding desktop support for compilation would significantly complicate pyes’s installation. Release of source code, instead of program binaries, may also not fit some use-cases. As a partial compromise, this feature adds server-side support for compiling configurations into a program, and returning the resulting binary.
-
css/vue support for appearance customization
Current use of html, vue, and css limits a user to editing these applications. This would allow use of plug-in components for setting different configuration values.
-
manual refresh of catalog and user notification
In 0.1.0, the catalog refresh happens in the background whenever the application is open, and updates are presented to the user when it is next opened.
This feature would add a button for manual refresh of a catalog, and live updates through the interface. It would also add options so the provider can specify a default type (auto/manual-only/update notification/user-editable).
-
generic http catalog
The resource location model used in the github catalog scheme supposes a particular way of locating files; an http catalog would allow full http references, instead of a relative folder reference valid only for github.
-
console/device interaction
Many consoles provide meaningful feedback through the serial interface; serial support can be enabled and allow the user to see what is going on.
-
device provisioning records
Sometimes it is useful to have a record of what is on each device. This feature would support keeping records of the device’s status: which program was loaded, how it was configured, etc.
-
Add arduino binary to the electron, or support using arduino in-place
Being unable to compile on desktops presents a significant limitation to this software. While electron app’s are easy to install for pure-node codebases, it has some support for adding third-party executables. This feature would either include arduino as an installed dependency, or interact with a local arduino installation to support compilation on the desktop.
-
support for more boards
Avrgirl-arduino is a great library! But there are some common boards (the SAMD21/51, some STM32s, and the ESP32/8266 mcus) that would be great to add support for in the library.
-
server-side sending of console data
Many remote support sessions for embedded systems invariably involve reading or copy/pasting serial output into an email; this would support uploads of serial sessions to a remote server.
-
circuit/micropython support
This environment is gaining in popularity; because these devices present as mass storage devices, they may also be straightforward to support.
-
plug-in support
There are many other environments that can be supported if pyes can bundle other programs and support plug-in scripts.
-
composite interactions
Some microcontroller programs need additional provisioning support other than program binary uploading; with circuitpython, code can be loaded in a piecemeal fashion. With arduino environments, additional setup can occur when memory segments are filled-in with per-instance data, a serial session occurs after provisioning, or a configuration program is loaded and run before the final program. Other boards have more than one device.
All these features can be supported by allowing icons to correspond to a more general notion of some device interaction, and for a series of interactions to comprise programming.