IoT Platform Design Doc: Virtual Devices

Marko Mikulicic, Oct 04, 2016 09:54 AM

How often do you want to test something and need hardware? How often do you then not have the right hardware to hand? Well, we hear your pain. This is why the cloud of Mongoose IoT Platform comes with a virtual device. It allows you to test a potential IoT integration without needing a physical device.  

In our newest design doc, our engineering team runs through our process behind designing this virtual device. Remember, this is not product documentation but the original document the team used to run through the process and make decisions.  

Disclaimer: This document refers features that have been put on hold (Cloud IDE and Mongoose IOT JavaScript) waiting for better times. The engineering team wants to share a few notes about this feature even if it's no longer deployed.

Parasite virtual devices




1. an organism which lives in or on another organism (its host) and benefits by deriving nutrients at the other's expense.



Design a virtual device that the user can play with in our Cloud IDE when she has no real device yet. 

Provide only a JS environment and some basic virtual IO (e.g. a fake LED). 

The main goal is to familiarise with the device API and the networking API between the device and the custom web app the user is building.

To simplify security (e.g. avoid complicated sandboxing) while actually providing full networking capabilities, we simply run this virtual device inside the user’s browser.



We support a few platforms. The user doesn’t necessarily have a compatible physical device yet. If she perceives that our platform has potential to be useful, she might want to buy a real device and try the real thing.  

Reading random claims in the product documentation and walking through examples might not work well for many practical-minded people. Furthermore, everybody has a different take on what is a simple doc; making a universally good doc is hard. An explorative system is a nice complement to a doc. 

We discussed about providing a virtual device feature a few times already. But, always dismissed it as a hard problem since it involved executing arbitrary user code on our servers. Security is hard and it takes time and focus to get right. We don't even know whether virtual devices are important; it's just a bet. Thus want to invest a reasonable amount of time in making this feature and we'll accept some limitations as a trade-off.



The basic idea is to make what essentially is a Mongoose IoT Platform port to the “JavaScript platform, browser flavour”. 

We have to implement the core Mongoose IoT Platform API in plain JavaScript and make it do something sensible. 

The funny thing is that this device is actually real. You can even pass the ID to another user who has rights to your project. We can even allow the user to create more than one instance of these fake devices and demonstrate M2M communication.


One thing this design doc is not about is persistent virtual devices. The virtual device lives in the browser and it’s tied to a user session. It will disappear as soon as the user closes the tab. This document doesn’t go in detail about how we present the virtual device to the user.  

We here assume that whenever a user opens the cloud “build” UI, a new parasite virtual device is created and it runs no code. It’s ID is the user ID (same as the UI’s own clubby connection). 

This simplifies many aspects including managing lifecycle and authentication. However,  a downside of this approach is that since the device is not registered as a device we don’t show a dashboard for it and even if we did, the dashboard would be bound to the user ID and we could only have one virtual device metric store per user. I think it’s ok for starters.


Dummy APIs for GC.GC, GC.stat, WDT, print etc - basically they should do nothing or the obvious thing.


Since the main goal of this is to show off our cloud IDE, all console output should go through the cloud log API as if it were a real device.

UART: nop-shim

GPIO: send/receive messages to/from a UI component that shows an image of a fake board with some pins and allows the user to interact with it.


No work necessary. We can let the user use the plain WebSocket object provided by the browser.

We need a shim that exposes node.js Http API and our own Mongoose IoT Platform specific extensions, too. 

We can either write our own or use Browserify (e.g.


The JS clubby implementation used by the main UI should do the trick. We should fix any possible API mismatch. 

The virtual device will use the same device ID as the UI connection, but with a different component, as to not interfere with the UI. The allocated id+component will be known by the UI, so it can present it to the user.


The Sys.conf object will be prepopulated by the UI when spawning the virtual device. We could provide some persistency using browser’s local storage. The device id/psk should be overwritten at every device start, so that the user doesn’t brick it’s own virtual device.


Detailed Design

Blocking behaviour

Want to have some fun ? Try this in your browser’s console:

while(true) console.log("good luck");

On Chrome the browser’s tab will freeze and there is no way to stop it from the console itself. Closing the tab doesn’t work either; you have to go to the task manager and kill the tab. This is obviously not good; we cannot just run user JS code inside the browser window.

Enter web workers: run some JS in a different thread, separated from the UI. The UI can start and terminate webworkers. by almost all modern browsers (including iOS safari), except Opera Mini.

Web Workers communicate to main thread via message passing:

worker.onmessage = function(e) { console.log("got event from web worker", e);


The web workers can make their own Ajax and WebSocket connections.

While the CPU isolation seems pretty good, a web worker can still interfere a bit with the browser’s responsivity if it logs a lot to console, as demonstrated by the "while(true) console.log" snippet above.

  Download Mongoose IoT Platform - Firmware