Overview

Every device that runs the library holds an instance of MiletusDevice.

Traits are loaded from a JSON description. The user has to load a provider instance to the libMiletus instance. The user also loads one or more instances of communication interfaces. A list containing the name of traits is used to “load” a new component.

Drawing

Concepts

Components are abstractions to hold a set of one or more Traits.

A Trait describes specific characteristics from modules of the device.

Traits have Commands, exposing procedures that can be invoked. This commands can have arguments, that is passed as a parameter.

Each parameter has a name and a set of properties like type, range.

Traits also have States, which is described on the trait JSON. This description contains the type of the value and can include the range of possible values. Components expose the current value of a State.

Example

Exemplifying an air conditioning system that contains a display. For this device we have the components:

The control Component holds the Trait onOff and temperature. The environment Component has temperature and humidity as Traits. The display Component has Traits for brightness, contrast, and also has the Trait onOff

For example, the Trait temperature of the Component control has Commands to increase, decrease, and set a specific temperature. The State of this Trait exposes the current set temperature.

An abstract example of the device is represented in JSON format bellow.

    
{
  "Device": {
    "AirConditioning": {
      "components": {
        "Control": {
          "traits": {
            "onOff": {
              "commands": {
                "onOff": {}
              },
              "states": {
                "isTurnedOn": {
                  "type": "boolean",
                  "currentValue": true
                }
              }
            },
            "temperature": {
              "commands": {
                "setTemperature": {
                  "parameters": {
                    "temperature": {
                      "type": "number",
                      "maximum": 30,
                      "minimum": 17
                    }
                  }
                },
                "increaseTemperature": {},
                "decreaseTemperature": {}
              },
              "states": {
                "temperature": {
                  "unity": "celsius",
                  "type": "number",
                  "maximum": 30,
                  "minimum": 17,
                  "currentValue": 23
                }
              }
            }
          }
        },
        "Environment": {
          "traits": {
            "temperature": {
              "states": {
                "temperature": {
                  "unity": "celsius",
                  "type": "number",
                  "maximum": 30,
                  "minimum": 17,
                  "currentValue": 23
                }
              }
            },
            "humidity": {
              "states": {
                "humidity": {
                  "unity": "percentage",
                  "type": "number",
                  "maximum": 100,
                  "minimum": 0,
                  "currentValue": 58
                }
              }
            },
            "lightness": {
              "state": {
                "lightness": {
                  "unity": "lux",
                  "type": "number",
                  "maximum": 20000,
                  "minimum": 0.0001,
                  "currentValue": 348.57
                }
              }
            }
          }
        },
        "Display": {
          "traits": {
            "onOff": {
              "commands": {
                "onOff": {}
              },
              "states": {
                "isTurnedOn": {
                  "type": "boolean",
                  "currentValue": true
                }
              }
            },
            "brightness": {
              "commands": {
                "setBrilightness": {
                  "parameters": {
                    "brightness": {
                      "type": "number",
                      "maximum": 100,
                      "minimum": 0
                    }
                  }
                }
              },
              "states": {
                "brightness": {
                  "unity": "percentage",
                  "type": "number",
                  "maximum": 100,
                  "minimum": 0,
                  "currentValue": 50
                }
              }
            },
            "contrast": {
              "commands": {
                "setContrast": {
                  "parameters": {
                    "brightness": {
                      "type": "number",
                      "maximum": 100,
                      "minimum": 0
                    }
                  }
                }
              },
              "states": {
                "contrast": {
                  "unity": "percentage",
                  "type": "number",
                  "maximum": 100,
                  "minimum": 0,
                  "currentValue": 50
                }
              }
            }
          }
        }
      }
    }
  }
}
    
  

Requests

All information from the device is retrieved as from requests.

mDNS

Info

An overview information about the device connection capabilities is retrieved by the request info.

In Linux/Unix, you can use the command curl in the IP of the device to retrieve this information.

curl 192.168.0.11/info

The response comes in the JSON format. An example is shown below.

    
      {
        "Id": "1c9c1b5d",
        "Name": "Example_Device",
        "Description": "",
        "ModelManifestId": "LIBMI"
      }
    
  

Traits

All of the descriptions of device capabilities is exposed by traits. The traits can be retrieved in the same form as was described in the device. Using this information you can know information about the device states, retrieved in a component request or execute a command.

curl 192.168.0.11/traits
    
  {
  "fingerprint": 135246,
  "traits": {
    "room": {
      "commands": {
        "onOff": {
          "parameters": {
            "lightparam": {
              "type": "boolean"
            }
          }
        }
      },
      "state": {
        "light": {
          "isRequired": true,
          "type": "boolean"
        },
        "temperature": {
          "isRequired": true,
          "type": "number"
        },
        "humidity": {
          "isRequired": true,
          "type": "number"
        }
      }
    }
  }
}
    
  

Components

curl 192.168.0.11/components
    
  {
  "fingerprint": 135246,
  "components": {
    "RoomA": {
      "traits": [
        "room"
      ],
      "state": {
        "room": {
          "light": true,
          "temperature": 25,
          "humidity": 33
        }
      }
    }
  }
}
    
  

Command Execution

    
    curl -H "Content-Type: application/json" -X POST -d 
    '{"name":"room.onOff","component":"RoomA","parameters":{"lightparam":true}}'
    192.168.0.11/commands/execute
  
Response success
    
    {
      "state": "done",
      "results": {
        "actualBrilightness": 48
      }
    }
  
Response fail
    
    {
      "state": "error",
      "error": {
        "code": "invalidBrilightness"
      }
    }
  

MQTT package encapsulation

Traits, Info, and Components are retained in the broker. Its values are published at the startup of the device and on each update.

A message from the IoT device to the client is published in the "out" subtopic. At the opposite way, it is published in "in" subtopic.

In each subtopic is published a command or a status always complaining the libMiletus JSON format.


Interaction between Client and Broker







Client



(subscribe) RoomB/out/info
JSON info

(subscribe) RoomB/out/traits
JSON traits

(subscribe) RoomB/out/components
JSON components

(subscribe) RoomB/out/commands/execute
(publish) RoomB/in/commands/execute
JSON “done” (“/out” publish)









Broker

Subtopics:

(The scratches mean that they have not yet been implemented)

DeviceID/{in/out}/commands/execute
DeviceID/{in/out}/commands/status
DeviceID/{in/out}/commands/list
DeviceID/{in/out}/commands/cancel
DeviceID/{out}/traits
DeviceID/{out}/info
DeviceID/{out}/components


Examples:

Room_B/out/info:
    
{
  "Id": "Room_B",
  "Name": "Room_B",
  "Description": "Meeting room device",
  "ModelManifestId": "LIBMI"
}
    
  
Room_B/out/traits:
    
{
  "fingerprint": "00000000",
  "traits": {
    "room": {
      "commands": {
        "onOff": {
          "minimalRole": "user",
          "parameters": {}
        },
        "sendTVCommand": {
          "minimalRole": "user",
          "parameters": {
            "TVCommand": {
              "type": "string",
              "enum": [
                "mute",
                "onOff",
                "up",
                "down",
                "right",
                "left",
                "ok",
                "menu",
                "source",
                "exit",
                "vol_up",
                "vol_down"
              ]
            }
          }
        }
      },
      "state": {
        "lightness": {
          "isRequired": true,
          "type": "number"
        },
        "temperature": {
          "isRequired": true,
          "type": "number"
        },
        "humidity": {
          "isRequired": true,
          "type": "number"
        }
      }
    }
  }
}
    
  
Room_B/out/components:
    
{
  "fingerprint": "00015FB3",
  "components": {
    "RoomB": {
      "traits": [
        "room"
      ],
      "state": {
        "room": {
          "humidity": 44,
          "lightness": 1.973048,
          "temperature": 24
        }
      }
    }
  }
}
    
  
Room_B/in/commands/execute:
    
{
  "component": "Room",
  "name": "room.onOff",
  "parameters": {}
}
    
  
Room_B/out/commands/execute:
    
{
  "state": "done"
}
    
  

MiletusApp:

In the main screen menu, there is the option "MQTT Settings", that gives access to the two firsts screenshots below.
The first one shows the status "Not connected", and in the second one shows the status "Connection OK".
The third one show the dialog where you can add a device (to show it, just press the "+" in the red circle).
To add, just write the device name, that you can find it in the source code (macro DEVICE_NAME).

Miletus application image 4 Miletus application image 5 Miletus application image 6


BLE package encapsulation

Info Command Communication (BLE only)

Source

Packet

Destination

client

length=0018B

libMiletus

client

/info?offset=0018B

libMiletus

libMiletus

length=1234B

client

libMiletus

json={...}&offset=1234B

client

 

Execute Command Communication (BLE only)

Source

Packet

Destination

client

length=0107B

libMiletus

client

/execute/command?application=json&value={...}&offset=0107B

libMiletus

libMiletus

length=4321B

client

libMiletus

json={...}&offset=4321B

client