Electric UI Overview

Why another UI solution?

The bulk of existing PC-Micro interaction products fall into two main groups:

  • The microcontroller and UI communicate through an offsite server (Blynk, Cayenne).
  • The UI/Host controls the microcontroller (Firmata, Johnny-Five, LabView are typical examples of this model)

Both of these approaches have some strong drawbacks including high-latency, clunky configuration processes, or have a misguided reliance on server-side compute. Most hardware products shouldn't require an internet connection to function, and should be able to function without the presence of any host.

Electric UI is for local interaction with real-time hardware devices, and it's extensible nature allows for integration with existing communication protocols and transports as needed.

microcontroller-with-coloured-arrows

We also don't feel existing products have struck the right value proposition by dictating hardware designs to meet their internet requirement, force usage of their own backends, or restrict development to drag-drop interfaces which result in poor end-user experiences.

Electric UI is for building professional grade tools, but also feels at home in hobby projects.

The embedded system is the host

Electric UI primarily operates with an asyncronous data-driven model as hardware products focus on the interaction with the physical world, such as displaying a temperature reading, graphing motor speed, or visualizing a complex robotic mechanism.

We treat the embedded system as the 'server' which holds the ground-truth data and state information. Where possible, the user interface should be stateless.

When using our bundled serial protocol intended for serial/USB connections or wrapped into a websockets payload, we provide some minimal metadata including a human readable message ID and three header bytes. The electricui-serial-protocol is intended for single slave transports in directly connected contexts, with a focus on responsiveness and low implementation weight for minimal systems.

While the bundled hardware implementation is simplistic, the user interface side is less hardware constrained and we use this extra power to ensure the ui-to-hardware behaviour is robust by offering self-healing connection management, support for simultaneous connections across a range of physical links (and protocols) with auto-failover and routing functionality, full and partial updates on larger data structures, and performs outbound message aggregation to reduce bandwidth usage.

Memory Model

To ensure Electric UI is easy to integrate with existing projects, maintain a slim profile where needed, and minimise boilerplate on the embedded device, the payloads sent to the UI follow the memory model of your embedded platform. Encoders and decoders running on the UI side handle custom structures/types and provide extra syntactic sugar.

This model enables the UI side to handle data with native language type safety and abstractions, while allowing developers to add compression, encryption or abstraction layers as deemed necessary without sacrificing any protocol or ecosystem benefits.

Stateless user interfaces

During initial connection handshakes, the UI queries the microcontroller's variables and maintains an abstract representation of transformed data, and allows it's state model to update over time as the user interacts with the hardware or UI.

By treating the user interface as a stateless window into the microcontroller's given state, and gracefully updating variables when the microcontroller or user change data, the system is able to handle connection errors or dropouts, and dodge issues with UI element state falling out of sync with the hardware.

Some of the neat benefits of a stateless design is how the user interface rendering behaviour reacts to changing data. As a user interface consists of a heirachy of UI components, a tree shaped data structure is formed representing the layout.

As state is mutated by the hardware or user during usage, a component which specifically needs only one element of state will not re-render or process unless it's state is modified. By following the state-tree, we can refresh only the relevant parts of the user interface, reducing runtime overheads.

Device Discovery and Connections

The most important part of an end-user's experience is ease of setup and consistency when connecting to their new product. While other IoT-centric solutions often punch through NAT and rely on 'the cloud' to provide easy connections, Electric UI handles the trickier parts of local hardware discovery for you.

While details differ based on the OS and transport in use, Electric UI's configurable hinting system lets you specify your expected hardware configuration, and it will find devices connected over serial ports, available as unpaired Bluetooth devices, unconfigured WiFi ad-hoc devices, or nodes on the local network. This provides some neat features:

  • Immediate discovery and management of directly connected hardware,
  • Home-friendly wireless network discovery features,
  • Cross-transport hints provide immediate resolutions for multi-transport configurations,
  • First-time users can use RFID tags, QR codes, Bluetooth or novel pairing approaches to bootstrap hints for more complex transports,
  • Non-volatile hints allow faster re-connections for commonly used devices,

Generic Components and React

A set of provided components covers common UI tasks, and helpers and examples allow for custom designs when needed. Advanced components provide complex visualizations from simple input data, and user-space transforms allow for intuitive labelling and manipulation.

The component based model allows for the same style of API surface, regardless of the component complexity, and use of properties for control over behaviour or visual style makes it easy to declaratively build layouts.

Where to now?

For a deeper technical explanation on how the bits work, check out the respective documentation: