Fork me on GitHub

Machine-to-machine
instant messaging

Open communications network & API for the Internet of Things.

MQTT IoT NETWORK

SkyNet is a cloud-based MQTT-powered network that scales to meet any needs whether the nodes are smart home devices, sensors, cloud resources, drones, Arduinos, Raspberry Pis, etc.

REST & WEBSOCKET API

SkyNet is powered by Node.JS and based entirely on its integrated REST API and realtime Websocket API with extensible JSON device & messaging.

DEVICE DIRECTORY

SkyNet provides a queriable device directory API for registering and discovering nodes on the SkyNet network. SkyNet also maintains presence for each device making it easy to know what is on/offline.

DEVICE SECURITY

SkyNet issues a unique 36 character UUID and secret token for each device connecting to our network. These device "credentials" are required for authentication, API calls, and subscriptions.


NODE.JS NPM MODULE

Node.JS is known for fast, event-driven operations perfect for nodes and devices such as RaspberryPi, Arduino, and Tessel. Our NPM module gets your app up & running quickly!

JAVASCRIPT

Connect to SkyNet from a web browser or mobile device using our SkyNet.JS javascript include file!

Thanks to Tom De Moor, Python websockets are now supported on SkyNet!


SkyNet allows you to query devices such as drones, hue light bulbs, weemos, arduinos, and server nodes that meet your criteria and send IM messages to 1 or all devices.

You can also subscribe to messages being sent to/from devices and their sensor activities.

DEMO!

SkyNet in Action

REST API

Base URI: http(s)://skynet.im

Status

/status
Returns the SkyNet platform status
curl -X GET http://skynet.im/status

Devices

/devices?key=value&key=value
Returns an array of device UUIDs based on key/value query criteria
curl -X GET http://skynet.im/devices?type=drone

/devices/{uuid}
Returns all information (except the token) of a specific device or node
curl -X GET http://skynet.im/devices/ad698900-2546-11e3-87fb-c560cb0ca47b

/devices
Payload: key=value (i.e. type=drone&color=black)
Registers a node or device with SkyNet. SkyNet returns a UUID device id and security token. You can pass any key/value pairs and even override SkyNet's auto-generated UUID and/or token by passing your own uuid and/or token in the payload i.e. uuid=123&token=456
curl -X POST -d "type=drone&color=black" http://skynet.im/devices

/devices/{uuid}
Payload: token=123&key=value (i.e. token=123&type=drone&color=blue&online=true)
Updates a node or device currently registered with SkyNet. You must pass the token for security but you can pass any key/value pairs to update object as well as null to remove a propery (i.e. color=null).
curl -X PUT -d "token=123&color=blue&online=true" http://skynet.im/devices/ad698900-2546-11e3-87fb-c560cb0ca47b

/devices/{uuid}
Payload: token=123
Deletes or unregisters a node or device currently registered with SkyNet. You must pass the token for security.
curl -X DELETE -d "token=123" http://skynet.im/devices/ad698900-2546-11e3-87fb-c560cb0ca47b

myDevices

/mydevices/{uuid}
Returns all information (including tokens) of all devices or nodes belonging to a user's UUID (identified with an "owner" property and user's UUID i.e. "owner":"0d1234a0-1234-11e3-b09c-1234e847b2cc")
curl -X GET http://skynet.im/mydevices/0d1234a0-1234-11e3-b09c-1234e847b2cc?token=1234glm6y1234ldix1234nux41234sor

Messages

/messages
Send a message to a specific device, array of devices, or all devices subscribing to a UUID on the SkyNet platform
curl -X POST -d '{"devices": "*", "payload": {"yellow":"off"}}' http://skynet.im/messages
curl -X POST -d '{"devices": ["ad6...47b","2f3...170"], "payload": {"yellow":"off"}}' http://skynet.im/messages
curl -X POST -d '{"devices": "ad698900-2546-11e3-87fb-c560cb0ca47b", "payload": {"yellow":"off"}}' http://skynet.im/messages
{"skynet":"online","timestamp":1381536589633,"eventCode":200,"_id":"5258934d56330f7dd0000009"}

Events

/events/{uuid}?token={token}
Returns last 10 events related to a specific device or node
curl -X GET http://skynet.im/events/ad698900-2546-11e3-87fb-c560cb0ca47b?token=123

Subscribe

/subscribe/{uuid}?token={token}
This is a streaming API that returns device/node mesages as they are sent and received. Notice the comma at the end of the response. SkyNet doesn't close the stream.
Note: You can subscribe to UUIDs without knowing the token but this will only allow you to receive broadcast messages from the UUID (devices=* or devices=all)
curl -X GET http://skynet.im/subscribe/ad698900-2546-11e3-87fb-c560cb0ca47b?token=123

Authenticate

/authenticate/{uuid}?token={token}
Returns UUID and authticate: true or false based on the validity of uuid/token credentials
curl -X GET http://skynet.im/authenticate/81246e80-29fd-11e3-9468-e5f892df566b?token=5ypy4rurayktke29ypbi30kcw5ovfgvi

IP Address

/ipaddress
Returns the public IP address of the request. This is useful when working with the SkyNet Gateway behind a firewall.
curl -X GET http://skynet.im/ipaddress

Data

/data/{uuid}
Payload: token=value&key=value (i.e. temperature=78&humity=30)
Stores sensor data for a particular UUID. You can pass any key/value pairs.
curl -X POST -d "token=123&temperature=78" http://skynet.im/data/0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc


/data/{uuid}?token={token}
Returns last 10 data updates related to a specific device or node
curl -X GET http://skynet.im/data/0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc?token=123

SkyNet offers a realtime websocket API as well as a Node.JS NPM module to make event-driven IoT development fast and easy. When nodes and devices register with SkyNet, they are assigned a unique id known as a UUID along with a security token. (Note: tokens can be provided by the request rather than having SkyNet assign one for you.)

Upon connecting your node or device to SkyNet, you can query and update devices on the network and send machine-to-machine (M2M) messages in an RPC-style fashion. Here are the basics for a socket.io implementation of using native websockets:

var io = require('socket.io-client')
socket = io.connect('http://skynet.im', {
    port: 80
});

socket.on('connect', function(){
  console.log('Requesting websocket connection to SkyNet');

  socket.on('identify', function(data){
    console.log('Websocket connecting to SkyNet with socket id: ' + data.socketid);
    console.log('Sending device uuid: ad698900-2546-11e3-87fb-c560cb0ca47b');
    socket.emit('identity', {uuid: 'ad698900-2546-11e3-87fb-c560cb0ca47b', socketid: data.socketid, token: 'zh4p7as90pt1q0k98fzvwmc9rmjkyb9'});
  });

  socket.on('notReady', function(data){
    if (data.status == 401){
      console.log('Device not authenticated with SkyNet');
    }
  });
  socket.on('ready', function(data){
    if (data.status == 201){
      console.log('Device authenticated with SkyNet');

      // Send/Receive messages
      socket.emit("message",{
        "devices": ["0d3a53...847b2cc", "11123...44567"],
        "payload": {
          "red":"on"
        }, function (data) {
          console.log(data);
        }
      });
      socket.on('message', function(message){
        console.log('message received', message);
        // { devices: '0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc',
  payload: { red: 'on' },
  fromUuid: '0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc' }
      });

      // Sample SkyNet API calls:
      socket.emit('status', function(data){
        console.log('status received');
        console.log(data);
        // { skynet: 'online' }
      });

      // Subscribe and unsubscribe to a device's messages and events
      socket.emit('subscribe', {
        "uuid": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc",
        "token": "qirqglm6yb1vpldixflopnux4phtcsor"
      }, function (data) {
        console.log(data);
        // {"api":"subscribe","socketid":"j3WWX81JwWYzaidRaNA7","fromUuid":"0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc","toUuid":"0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc"}
      });

      socket.emit('unsubscribe', {"uuid": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc"}, function (data) {
        console.log(data);
        // {"api":"unsubscribe","socketid":"j3WWX81JwWYzaidRaNA7","uuid":"0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc"}
      });

      // Register device
      socket.emit('register', {
        "type":"drone"
      }, function (data) {
        console.log(data);
        // {"type":"drone","uuid":"b34cc731-b2f2-11e3-a36b-61e66c96102e","timestamp":"2014-03-24T01:22:01.123Z","token":"3k0t96e6n9mjkyb9ncpx8um4bstc5wmi","channel":"main","online":false,"ipAddress":""}
      });


      // Update device
      socket.emit('update', {
        "uuid": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc",
        "token": "qirqglm6yb1vpldixflopnux4phtcsor",
        "armed":true
      }, function (data) {
        console.log(data);
        // {"uuid":"0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc","armed":true,"timestamp":"2014-03-24T01:22:01.203Z"}
      });

      // WhoAmI?
      socket.emit('whoami', {"uuid":"0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc"}, function (data) {
        console.log(data);
        // {"armed":true,"channel":"main","color":"blue","ipAddress":"70.171.192.231","online":true,"protocol":"websocket","socketId":"j3WWX81JwWYzaidRaNA7","uuid":"0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc"}
      });

      // Receive last 10 device events
      socket.emit('events', {
        "uuid": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc",
        "token": "qirqglm6yb1vpldixflopnux4phtcsor"
      }, function (data) {
        console.log(data);
        // {"events":[{"uuid":"0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc","armed":true,"timestamp":"2014-03-24T01:22:01.203Z","fromUuid":{"armed":true,"channel":"main","color":"blue","ipAddress":"70.171.192.231","online":true,"protocol":"websocket","socketId":"j3WWX81JwWYzaidRaNA7","uuid":"0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc"},"eventCode":401,"id":"532f88b90db905bf09055983"}]}
      });

      // Store sensor data for device
      socket.emit('data', {
        "uuid": "f828ef20-29f7-11e3-9604-b360d462c699",
        "token": "syep2lu2d0io1or305llz5u9ijrwwmi",
        "temperature": 55
      }, function (data) {
        console.log(data);
      });


    }
  });
});

            

Websocket API commands include: status, register, unregister, update, whoami, devices, subscribe, unsubscribe, authenticate, data, and message. You can send a message to a specific UUID or an array of UUIDs or all nodes on SkyNet.

Node.JS NPM Module

SkyNet also offers a Node.JS NPM module for making event-driven IoT development fast and easy. This Node.JS module allows you to specify messaging protocol ("mqtt", "websocket"). If you select MQTT communications, you must specify your desired Quality of Service level ("qos") on the config as well as each message and subscription. You can install the skynet module by running:

npm install skynet

Here's a kitchen-sink sample Node.JS app using the SkyNet NPM module:

var skynet = require('skynet');

var conn = skynet.createConnection({
  "uuid": "ad698900-2546-11e3-87fb-c560cb0ca47b",
  "token": "zh4p7as90pt1q0k98fzvwmc9rmjkyb9",
  "protocol": "mqtt", // or "websocket"
  "qos": 0, // MQTT Quality of Service (0=no confirmation, 1=confirmation, 2=N/A)
  "server": "localhost", // optional - defaults to http://skynet.im
  "port": 3000  // optional - defaults to 80
});

conn.on('notReady', function(data){
  console.log('UUID FAILED AUTHENTICATION!');
  console.log(data);

  // Register a device
  conn.register({
    "type": "drone"
  }, function (data) {
    console.log(data);

    // Login to SkyNet to fire onready event
    conn.authenticate({
      "uuid": data.uuid,
      "token": data.token
    }, function (data) {
      console.log(data);
    });

  });

});

conn.on('ready', function(data){
  console.log('UUID AUTHENTICATED!');
  console.log(data);

  // Send and receive messages
  conn.message({
    "devices": "*",
    "payload": {
      "red":"on"
    },
    "qos": 0
  });

  // Subscribe to device/node i/o
  conn.subscribe({
    "uuid": "f828ef20-29f7-11e3-9604-b360d462c699",
    "token": "syep2lu2d0io1or305llz5u9ijrwwmi"
  }, function (data) {
    console.log(data);
  });

  // Unsubscribe to device/node i/o
  conn.unsubscribe({
    "uuid": "f828ef20-29f7-11e3-9604-b360d462c699"
  }, function (data) {
    console.log(data);
  });

  conn.on('message', function(message){
    console.log('message received', message);
  });


  // Event triggered when device loses connection to skynet
  conn.on('disconnect', function(data){
    console.log('disconnected from skynet');
  });

  // Register a device
  conn.register({
    // token is optional. skynet will assign one for your device uuid if not present
    "token": "zh4p7as90pt1q0k98fzvwmc9rmjkyb9",
    "type": "drone"
  }, function (data) {
    console.log(data);
  });

  // UnRegister a device
  conn.unregister({
    "uuid": "ad698900-2546-11e3-87fb-c560cb0ca47b",
    "token": "zh4p7as90pt1q0k98fzvwmc9rmjkyb9"
  }, function (data) {
    console.log(data);
  });

  // Update device
  conn.update({
    "uuid":"ad698900-2546-11e3-87fb-c560cb0ca47b",
    "token": "zh4p7as90pt1q0k98fzvwmc9rmjkyb9",
    "armed":true
  }, function (data) {
    console.log(data);
  });

  // WhoAmI?
  conn.whoami({"uuid":"ad698900-2546-11e3-87fb-c560cb0ca47b"}, function (data) {
    console.log(data);
  });

  // Receive an array of device UUIDs based on user defined search criteria
  conn.devices({
    "type":"drone"
  }, function (data) {
    console.log(data);

    // Send hello world to the array of device uuids
    conn.message({
      "devices": data.devices,
      "payload": {
        "hello":"world"
      },
      "qos": 0
    });

  });

  // SkyNet status
  conn.status(function (data) {
    console.log(data);
  });

  // Receive last 10 device events
  conn.events({
    "uuid": "f828ef20-29f7-11e3-9604-b360d462c699",
    "token": "syep2lu2d0io1or305llz5u9ijrwwmi"
  }, function (data) {
    console.log(data);
  });

  // Store sensor data for device
  conn.data({
    "uuid": "f828ef20-29f7-11e3-9604-b360d462c699",
    "token": "syep2lu2d0io1or305llz5u9ijrwwmi",
    "temperature": 55
  }, function (data) {
    console.log(data);
  });


});


            

SkyNet automatically creates a websocket room for each connect device. This allows apps and other nodes and devices to connect and monitor events and commands. Note: UUID and Token are required to subscribe to device/node events. Here's a sample Node.JS device monitoring script:

script(src="http://code.jquery.com/jquery-1.10.1.min.js")
script(src="/socket.io/socket.io.js")
script.
  // Connect to SkyNet server & port
  var socket = io.connect('http://skynet.im:80');

  // subscribe to uuid
  socket.emit('subscribe', {
    "uuid": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc",
    "token": "qirqglm6yb1vpldixflopnux4phtcsor"
  }, function (data) {
    console.log(data);
  });

  // unsubscribe to uuid
  socket.emit('unsubscribe', {"uuid": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc"}, function (data) {
    console.log(data);
  });

  socket.on('identify', function (data) {
    console.log(data);
    $(".activity").prepend(JSON.stringify(data) + '<br />');
  });

  socket.on('message', function (message) {
    console.log('message received', message);
    $(".activity").prepend(JSON.stringify(message) + '<br />');
  });

            

For your convenience, we also have a skynet.js javascript include file that you can use for client-side Web and/or mobile apps. Here are the basics:


<html>
<head>
  <script src="http://skynet.im/js/skynet.js"></script>
  <script>
    var skynetConfig = {
      "uuid": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc",
      "token": "qirqglm6yb1vpldixflopnux4phtcsor",
      "protocol": "websocket",
      "host": "localhost", // optional (defaults to "http://skynet.im")
      "port": 3000 // optional (defaults to 80)
    }
    skynet(skynetConfig, function (e, socket, device) {
    // skynet(function (e, socket, device) {
    // skynet({appName:'chris'}, function (e, socket, device) {
      if (e) throw e

      // Sample SkyNet API calls:
      socket.emit('status', function(data){
        console.log('status received');
        console.log(data);
      });
      // Subscribe and unsubscribe to a device's messages and events
      socket.emit('subscribe', {
        "uuid": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc",
        "token": "qirqglm6yb1vpldixflopnux4phtcsor"
      }, function (data) {
        console.log(data);
      });

      socket.emit('unsubscribe', {"uuid": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc"}, function (data) {
        console.log(data);
      });

      // Send and receive messages
      socket.emit('message', {
        "devices": "*",
        "payload": {
        "skynet":"online"
      }}, function(data){
        console.log(data);
      });
      socket.on('message', function(message){
        console.log('message received', message);
      });


      // Get the status of the SkyNet network
      socket.emit('status', function(data){
        console.log('status received');
        console.log(data);
      });

      // Register device
      socket.emit('register', {
        "type":"drone"
      }, function (data) {
        console.log(data);
      });


      // Update device
      socket.emit('update', {
        "uuid": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc",
        "token": "qirqglm6yb1vpldixflopnux4phtcsor",
        "armed":true
      }, function (data) {
        console.log(data);
      });

      // WhoAmI?
      socket.emit('whoami', {"uuid":"0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc"}, function (data) {
        console.log(data);
      });

      // Receive last 10 device events
      socket.emit('events', {
        "uuid": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc",
        "token": "qirqglm6yb1vpldixflopnux4phtcsor"
      }, function (data) {
        console.log(data);
      });

    });
  </script>
</head>
<body>
  SkyNet client-side app
</body>
</html>

            

Note: There are three ways listed in the HTML example:
1. The first option is used when you know the UUID and token of the device or node being connected to SkyNet
var skynetConfig = {
  "uuid": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc",
  "token": "qirqglm6yb1vpldixflopnux4phtcsor"
}
skynet(skynetConfig, function (e, socket, device) {

2. If you would like for SkyNet to automatically register a new UUID and token for you. This information will be returned in the device object.
skynet(function (e, socket, device) {

3. Similar to option two, SkyNet will automatically register your device/node but you can pass additional JSON elements to your device description. There are no reserved element names.
skynet({'appName':'chris', 'awesomeMeter':10}, function (e, socket, device) {

Examples

Here are a few examples to get you started. You will need to create your own UUID and token. You can do this by running the following command from your terminal window:

curl -X POST -d "type=example" http://skynet.im/devices

This should return a response from SkyNet with your very own UUID and Token like this one! Please use this UUID and Token in the examples below.

We will be using the SkyNet and Request NPM modules in the examples below. You can install them using the following terminal commands:

npm install skynet
npm install request

          
var request = require('request');

// Check SkyNet status
request('http://skynet.im/status', function (error, response, body) {
  if (!error && response.statusCode == 200) {
    console.log(body) // Print skynet status.
  }
})

// Subscribe to UUID
// curl -X GET http://skynet.im/subscribe/0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc?token=qirqglm6yb1vpldixflopnux4phtcsor
console.log('Subscribing to UUID: 0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc')
request.get('http://skynet.im/subscribe/0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc',
  {qs: {'token': 'qirqglm6yb1vpldixflopnux4phtcsor'}}
  , function (error, response, body) {
    if (!error && response.statusCode == 200) {
      console.log(body) // Print device activity.
  }
})

// Send message
// curl -X POST -d '{"devices": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc", "payload": {"yellow":"off"}}' http://skynet.im/messages
setTimeout(function(){
  request.post('http://skynet.im/messages',
    {form: {'devices':'0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc', 'payload': 'test'}}
    , function (error, response, body) {
      if(response.statusCode == 200){
        console.log(body);
      }
  });
},1000);

      
    
        
var skynet = require('skynet');
var request = require('request');

var conn = skynet.createConnection({
  "uuid": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc",
  "token": "qirqglm6yb1vpldixflopnux4phtcsor",
  "protocol": "websocket"
});

conn.on('ready', function(data){
  console.log('Ready');

  conn.on('message', function(data){
    console.log(data);
  });

  conn.status(function (data) {
    console.log(data);
  });

  conn.message({
    "devices": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc",
    "payload": {
      "hello":"world"
    }
  });

});
      
    
  


<html>
<head>
  <script src="skynet.js"></script>
  <script>
    var skynetConfig = {
      "uuid": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc",
      "token": "qirqglm6yb1vpldixflopnux4phtcsor",
      "protocol": "websocket"
    }
    skynet(skynetConfig, function (e, socket) {
      if (e) throw e

      window.socket = socket;

      // Wait for message
      socket.on('message', function(message){
        console.log('message received', message);
      });

      // Get the status of the Skynet network
      socket.emit('status', function(data){
        console.log('status received');
        console.log(data);
      });

      // Send and receive messages
      socket.emit('message', {
        "devices": "0d3a53a0-2a0b-11e3-b09c-ff4de847b2cc",
        "payload": {
        "red":"on"
        }
      }, function(data){
        console.log(data);
      });

    });
  </script>

</head>
<body>
  Skynet.JS Demo
</body>
</html>


Get in touch