Developing Web Things with Python, Client. js, and Java

The Mozilla IoT team lately released the Things Framework , which allows you to build IoT gadgets that speak the Web Matter API . Last week, James constructed an ESP8266 web thing . This time, I’ m going to demonstrate how to build web things with Python, Node. js, or Java. These types of languages are definitely not optimal just for small embedded devices; this guide is intended for higher-end devices that may run these languages with ease, as well as your own desktop computer.

To show, we’ ll be turning the particular Music Player Daemon (MPD) into a web thing. The your local library we’ ll be using here are webthing-python , webthing-node , and webthing-java .

Intro towards the Music Player Daemon (MPD)

The Music Player Daemon is an open-source music player that has been about since 2003. MPD operates in the client/server model, and is controllable more than TCP with a simple text-based process. I won’ t cover set up here, but MPD can be set up via your package manager upon Linux, Homebrew on Mac OPERATING SYSTEM X, or with binaries upon Windows .

Several Quick Notes

Even though this example is written just for MPD, it would be easily portable to music players with an API, or perhaps you could build your own player employing this example as a base. More importantly, this particular example is primarily meant to show the Things Framework, which can be used to develop an endless variety of web things.

The Python, Node. js, and Java web thing your local library all have essentially the same API. While they may not be entirely idiomatic for respective languages, doing this allows us to preserve all the libraries more easily, which is extremely valuable while the Web Thing API is still a living draft.

Getting Started

To start, initialize an empty project for your language of preference. For example , you might create a new task in IntelliJ IDEA for Java, or run npm init to start a new Node. js task. You’ ll then want to include the webthing library as an addiction. Instructions for doing so can be found for the respective Github project page, you can also look here .

Now we’ re ready to compose some code. Essentially we’ lmost all do the following:

  1. Create a Thing .
    1. Define its qualities.
    2. Define its activities.
    3. Define its occasions.
  2. Connect the Thing to a WebThingServer .

Produce a Thing

First off, let’ s import our library of preference.


 from webthing import Action, Event, Property, Issue, Value, WebThingServer 


 = require('webthing'); 


 import org. mozilla. iot. webthing. Action;
transfer org. mozilla. iot. webthing. Occasion;
import org. mozilla. iot. webthing. Property;
import org. mozilla. iot. webthing. Thing;
import org. mozilla. iot. webthing. Value;
import org. mozilla. iot. webthing. WebThingServer; 

Now, we’ ll create a basic subclass associated with Thing .


 class MPDThing(Thing):
def __init__(self):
Thing. __init__(self, 'MPD', 'musicPlayer', 'Music Player Daemon') 


 class MPDThing stretches Thing 
    super('MPD', 'musicPlayer', 'Music Player Daemon');


 public class MPDThing extends Point 
    public MPDThing() 
        super("MPD", "musicPlayer", "Music Player Daemon");

Add Properties

Since we have our MPDThing , we’ ll need to then add properties to it. Obviously, a very good music player will have quite a few properties. To demonstrate, I am going to show you how to add one, plus I’ ll link to the rest of the program code at the end of this post.

To include a property, you can do the following inside the MPDThing constructor.


 position = self. get_status()
self. add_property(
Value(self. get_volume(status), personal. set_volume),
                 'type': 'number',
                 'description': 'Playback volume',
                 'minimum': 0,
                 'maximum': 100,


 this. getStatus(). then((status) => 
  this.getVolume(status).then((v) => 
      new Property(this,
                   new Value(v, this.setVolume.bind(this)),
                     type: 'number',
                     description: 'Playback volume',
                     minimum: 0,
                     maximum: 100,


 ServerStatus status = this particular. client. getServerStatus();
Map< String, Object> volumeMetadata = new HashMap< > ();
volumeMetadata. put("type", "number");
volumeMetadata. put("description", "Playback volume");
volumeMetadata. put("minimum", 0);
volumeMetadata. put("maximum", 100);
this particular. volumeValue =
new Value(status. getVolume(), v -> this. setVolume((int)v));
this particular. addProperty(new Property(this,
this. volumeValue,

We’ ve now created a Property which allows us to GET and PUT the play-back volume. The Worth piece is an item that essentially stores a cached value and a “ value forwarder” callback. When the volume is set with a PUT request, the value forwarder can be used to forward the new value towards the actual device, which in this situation is the MPD server. We’ ve also set up some metadata for your property, including a description, worth type, and a minimum and optimum value.

Add Activities

A music player may also have a lot of actions. While the MPD web thing has several simple actions like play, pause, plus skip, I’ ve added one which takes some additional input, that will queue a series of random songs. Actions inputs are verified with a JSON Schema validator .

First, let’ s create a good Action subclass.


 class QueueRandomAction(Action):
def __init__(self, issue, input_):
Action. __init__(
self, uuid. uuid4(). hex, thing, 'queueRandom', input_=input_)

def perform_action(self):
songs = personal. thing. list()
if songs:
meant for _ in range(0, int(self. insight['count'])):
self. thing. add(random. choice(songs))

playlist = self. matter. get_playlist()
if playlist is not Not one:
self. thing. add_event(
PlaylistUpdatedEvent(self. factor, playlist)) 


 course QueueRandomAction extends Action 
  constructor(thing, input) 
    super(uuidv4(), thing, 'queueRandom', input);

    return this.thing.list().then((songs) => 
      const promises =  [] ;

      if (songs) 
        for (let i = 0; i < this.input.count; ++i) 
          const uri = songs [Math.floor(Math.random() * songs.length)] .file;

        promises.push(this.thing.getPlaylist().then((playlist) => 
          if (playlist) 
            this.thing.addEvent(new PlaylistUpdatedEvent(this.thing, playlist));

      return Promise.all(promises);


 public static course QueueRandomAction extends Action 
    public QueueRandomAction(Thing thing, JSONObject input) 
        super(UUID.randomUUID().toString(), thing, "queueRandom", input);

    public void performAction() 
        MPDThing thing = (MPDThing)this.getThing();
        Random random = new Random();
        List<MPDFile> songs = thing.list();

        for (int i = 0; i < this.getInput().getInt("count"); ++i) 
            MPDFile file = songs.get(random.nextInt(songs.size()));

        String playlist = thing.getPlaylist();
        thing.addEvent(new PlaylistUpdatedEvent(thing, playlist));

QueueRandomAction takes an insight, count , lines that number of random songs to the present playlist, and then emits a PlaylistUpdatedEvent (to be defined shortly). To add this particular new action to our MPDThing , do the following within the MPDThing constructor:


 self. add_available_action(
'description': 'Queue a series of random songs',
         'type': 'object',
         'required':  [
         ] ,
                 'type': 'number',
                 'minimum': 1,


 this. addAvailableAction(

    description: 'Queue a series of random songs',
      type: 'object',
      required:  [
      ] ,
          type: 'number',
          minimum: 1,


 Map< String, Object> queueRandomMetadata = new HashMap< > ();
queueRandomMetadata. put("description",
"Queue a series of unique songs");
Map< String, Object> queueRandomInputMetadata = new HashMap< < > ();
queueRandomInputMetadata. put("type", "object");
queueRandomInputMetadata. put("required", new String[]"count" );
Map< String, Object> queueRandomInputPropertiesMetadata =
new HashMap< > ();
Map< String, Object> queueRandomInputPropertiesCountMetadata sama dengan
new HashedMap();
queueRandomInputPropertiesCountMetadata. put("type", "number");
queueRandomInputPropertiesCountMetadata. put("minimum", 1);
queueRandomInputPropertiesMetadata. put("count",
queueRandomInputMetadata. put("properties",
queueRandomMetadata. put("input", queueRandomInputMetadata);
this. addAvailableAction("queueRandom",
QueueRandomAction. class); 

Add Events

The final piece of our Thing is the events. Since MPD is a client/server model, it can be updated externally simply by any number of other clients. As such, We created an event that will fire once the current playlist is updated.

As with Factor and Action , we’ ll develop an Event subclass.


 class PlaylistUpdatedEvent(Event):
def __init__(self, thing, data):
Event. __init__(self, factor, 'playlistUpdated', data=data) 


 class PlaylistUpdatedEvent extends Event 
  constructor(thing, data) 
    super(thing, 'playlistUpdated', data);


 public stationary class PlaylistUpdatedEvent extends Event 
    public PlaylistUpdatedEvent(Thing thing, String data) 
        super(thing, "playlistUpdated", data);

It is a basic Event . The data member will be filled along with a string representation of the present playlist.

To add this particular Event to our thing, we’ ll the actual following in the MPDThing constructor:


 self. add_available_event(
 'description': 'The current playlist has been updated',
     'type': 'string' ) 


 this. addAvailableEvent(

    description: 'The current playlist has been updated',
    type: 'string',


 Map< Chain, Object> playlistUpdatedMetadata = new HashMap< > ();
playlistUpdatedMetadata. put("description",
"The current playlist has been updated");
playlistUpdatedMetadata. put("type", "string");
this. addAvailableEvent("playlistUpdated", playlistUpdatedMetadata); 

Produce a WebThingServer

Now that we now have a thing with properties, actions, plus events, we’ ll create a WebThingServer plus attach the MPDThing to it.


  thing = MPDThing()

server = WebThingServer([thing], port=8888)

server. start()
except KeyboardInterrupt:
server. stop() 


 const thing = new MPDThing();

const server = new WebThingServer([thing], null, 8888);

process. on('SIGINT', () => 

machine. start(); 


 MPDThing thing = new MPDThing();

List< Thing> things = new ArrayList< > ();
things. add(thing);

    WebThingServer server = new WebThingServer(things, null, 8888);

           .addShutdownHook(new Thread(() -> server.stop()));

 catch (IOException e) 

Managing the Web Thing

The web thing is complete plus it’ s now controllable with the Web Thing API. Here’ s i9000 how to add it to the Elements Gateway :

The Things Gateway doesn’ t currently provide a way to make use of actions or display events, yet those are in the works.

Alternatively, you can control the internet thing via cURL or any additional HTTP library you choose:


  $ curl 
-H 'Content-Type: application/json' 
 -d ' "play": ' 

Wrapping Up

Your own imagination is really your only restrict as to what you can turn into a web matter. If you’ d like to view the rest of this example and how the particular MPD controls are implemented, all the code is available on Github .

If you have any queries or suggestions, you can head over to Talk or find all of us in #iot on irc. mozilla. org . Additionally , feel free to create problems, or even better, submit pull requests, towards the webthing library repositories!

Erina is a software engineer at Mozilla working on Project Things.

More posts by Michael Stegeman…

If you liked Developing Web Things with Python, Client. js, and Java by Michael Stegeman Then you'll love Web Design Agency Miami

Add a Comment

Your email address will not be published. Required fields are marked *