IoT Platform Design Doc: Virtual Devices

DZone 's Guide to

IoT Platform Design Doc: Virtual Devices

The Mongoose IoT Platform comes with a virtual device that allows you to test a potential IoT integration without needing an actual physical device. Let's look into the design process behind the creation of this feature.

· IoT Zone ·
Free Resource

How often do you want to test something and need hardware? How often do you then not have the right hardware on hand? Well, we hear your pain. This is why the 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) while waiting for better times. The engineering team wants to share a few notes about this feature regardless.

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 within 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 familiarize yourself 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 the 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 a simple doc is; making a universally good doc is hard. An explorative system is a nice complement to a doc. 

We discussed providing a virtual device feature a few times already. But we always dismissed it as a hard problem, as it involved executing arbitrary user code on our servers. Security is hard and it takes time and focus to get it right. We don't even know whether virtual devices are important; it's just a bet. Thus, we 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 is, essentially, a Mongoose IoT Platform port to the “JavaScript platform, browser flavor.”

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 assume that whenever a user opens the cloud “build” UI, a new parasite virtual device is created, and it runs no code. Its 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 the Node.js HTTP API and our own Mongoose IoT Platform-specific extensions, too. 

We can either write our own or use Browserify (e.g. https://github.com/substack/http-browserify).


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, so 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 persistence using the browser’s local storage. The device ID/PSK should be overwritten at every device start so that the user doesn’t brick its own virtual device.

Detailed Design

Blocking Behavior

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

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

On Chrome, the 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 Web Workers. It's supported by almost all modern browsers (including iOS safari), except Opera Mini.

Web Workers communicate to the 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 the console, as demonstrated by the  while(true) console.log snippet above.

api, cloud, iot, mongoose

Published at DZone with permission of Marko Mikulicic , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}