MClimate API

Documentation

MClimate API 1

Introduction

Based on simple REST principles, the MClimate API endpoints return JSON metadata about the smart-home controllers like temperature, humidity, etc., directly from the MCloud.

The API also provides interface to control MClimate devices and access to user-related data, like user’s devices, activity, etc. Such access is enabled through selective authorization, by the user.

The base address of MClimate API is https://developers-api.seemelissa.com/v1. The API provides a set of endpoints, each with its own unique path. To access private data through the Web API, such as user profiles and playlists, an application must get the user’s permission to access the data. Authorization is via the MClimate Auth service.

Requests

The MClimate Web API is based on REST principles. Data resources are accessed via standard HTTPS requests in UTF-8 format to an API endpoint. Where possible, Web API uses appropriate HTTP verbs for each action:

METHOD

ACTION

GET

Retrieves resources

POST

Creates resources

PUT

Changes and/or replaces resources or collections

DELETE

Deletes resources

Response format

Our API uses the Hypertext Application Language or HAL as response format for our requests. HAL is a simple format that gives a consistent and easy way to hyperlink between resources in an API. APIs that adopt HAL can be easily served and consumed using open source libraries available for most major programming languages. It's also simple enough that you can just deal with it as you would any other JSON.

HAL recognises two basic types of responses: entity and collection. Both responses follow the same general format, although they are slightly different.

Whenever an API response returns an entity (e.g. /v1/controllers/{serial_number}). The HAL response format is as follows:

{
  "controller": {
    "user_id": 200,
    "serial_number": "UV******8CS6",
    "mac": "5ECF7F********",
    "firmware_version": "V1SHTHF",
    "name": "Melissa UV4*****",
    "type": "melissa",
    "online": false
  },
  "_links": {
    "self": {
      "href": "/v1/controllers/UV4R7******S6"
    }
  }
}

Notice, how the actual information is "enveloped" in a key named after the resource or in this case the "controller" resource. The "_links" key is a mandatory key in HAL and it defines useful links to the resource itself or other related.

Whenever an API response return a collection (e.g. /v1/controllers). The HAL response format is as follows:

{
  "_embedded": {
    "controller": [
      {
        "user_id": 200,
        "serial_number": "H5******J6X",
        "mac": "“ACCF***6522E\"",
        "firmware_version": "V1SHTHF",
        "name": "Melissa H59****X",
        "type": "melissa",
        "room_id": 7,
        "online": false,
        "brand_id": 9,
        "controller_log": [],
        "_links": {
          "self": {
            "href": "/v1/controllers/H59I****6X"
          }
        }
      },
      {…},
	 {…},
	 {…},
	…
    ]
  },
  "total": 22,
  "_links": {
    "self": {
      "href": "/v1/controllers"
    },
    "first": {
      "href": "/v1/controllers?page=1"
    },
    "last": {
      "href": "/v1/controllers?page=1"
    }
  }
}

The main difference between a collection response and an entity response is that the collection response is "enveloped" in an "_embedded" key. An important thing to notice is that pagination information is returned with every collection response.

Note: If a collection response returns no information the API returns and empty response following the entity HAL format, but if an entity response return no information a 404 error response is generated.

Response Status Codes

The MClimate API uses the following response status codes, as defined in the RFC 2616 and RFC 6585:

STATUS CODE

DESCRIPTION

200

OK - The request has succeeded. The client can read the result of the request in the body and the headers of the response.

201

Created - The request has been fulfilled and resulted in a new resource being created.

202

Accepted - The request has been accepted for processing, but the processing has not been completed.

204

No Content - The request has succeeded but returns no message body.

304

Not Modified. See Conditional requests.

400

Bad Request - The request could not be understood by the server due to malformed syntax. The message body will contain more information; see Response Schema.

401

Unauthorized - The request requires user authentication or, if the request included authorization credentials, authorization has been refused for those credentials.

403

Forbidden - The server understood the request, but is refusing to fulfill it.

404

Not Found - The requested resource could not be found. This error can be due to a temporary or permanent condition.

429

Too Many Requests - Rate limiting has been applied.

500

Internal Server Error. You should never receive this error because our clever coders catch them all … but if you are unlucky enough to get one, please report it to us through a comment at the bottom of this page.

502

Bad Gateway - The server was acting as a gateway or proxy and received an invalid response from the upstream server.

503

Service Unavailable - The server is currently unable to handle the request due to a temporary condition which will be alleviated after some delay. You can choose to resend the request again.

Error responses

The MClimate API follows the error response format as defined in RFC 7807. Here is an example response following this response format:

{
    "type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
    "status": 404,
    "title": "Not Found",
    "detail": "Controller not found"
}

Fields:

"type" tries to provide further information and reference to the error described in the response

"status" is the HTTP error code generated as a result of the request

"title" human readable description of the HTTP error code

"detail" provides additional information

In the following paragraph we try to give generalized information about the error responses generated by the MClimate API:

Our API consumes content of type "application/json" if your request does not use JSON as transport or your request body is malformed a 400 response is generated

Everytime you try to fetch an unexisting entity a 404 response is generated

Since this API serves the purpose of third party integratiors, authentication and authorization mechanisms apply. Whenever you fail to authorize or authenticate a 401 response is generated

As described in [href] Rate Limiting [/href] if you exceed the number of requests per minute a 429 response is generated

If our servers experience internal problems a 500 error is generated. Should this ever happen please contact us at developers@seemelissa.com

Rate Limiting

Rate Limiting enables Web API to share access bandwidth to its resources equally across all users.

Rate limiting is applied as per application based on Client ID, and regardless of the number of users who use the application simultaneously. The number of requests for certain amount of time that are authenticated by one token is also limited.

To reduce the amount of requests, use endpoints that fetch multiple entities in one request. For example: If you often request single controllers, use endpoints that return multiple such as Fetch All User Controllers.

Note: If the API returns status code 429, it means that you have sent too many requests.

Pagination

Every GET request which returns a collection (e.g. Fetch all user controllers), contains pagination information. It is contained within the "_links" key of every response. The count of entities per page is set to the constant number of 30. An additional key "total" indicates the number of entities currently returned. Referencing which page you would like to fetch is achieved through the "page" GET in the URL. (e.g. /v1/controllers?page=2)

Pagination information schema:

    "total": 22,
    "_links": {
        "self": {
            "href": "/v1/controllers"
        },
        "first": {
            "href": "/v1/controllers?page=1"
        },
        "last": {
            "href": "/v1/controllers?page=1"
        }
    }

Additional API options

Our API provides flexibility we find usefull in current situations. All of the options described below are passed to our endpoints as GET parameters in the URL.

To define explicitly which fields of a given resource you would like to get in the response you can pass the "fields" parameter in the URL

Example: /v1/controllers/{serial_number}?fields=serial_number,mac,name

The fields are comma separated.

Sometimes it's useful to be able to pass more than just one identifier to a resource rather than just some ID. This can be achieved by just passing the desired field => value pair in the URL

NOTE: This feature is only available when returning collections

Example: /v1/controllers?type=melissa

You can also sort collections by specific parameter by passing the "sort" parameter in the URL

Example: /v1/controllers?sort=-created

The sorting order is defined by the sign preceding the field name. Default order is ascending

Limiting the number of entities in a collection response is also useful as it can lower the payload size, preferable for high latency networks. You can limit the number of entities by passing the "limit" parameter in the URL

Example: /v1/controllers?limit=15

Note: The default value of "limit" is 30 as defined in [href] Pagination [/href]

All of the above parameters can be combined as desired, but what's important to notice is that every field used in these parameters must correspond to a valid field in the resource's entity. For example /v1/controllers?foo=bar will result in an error as "foo" is not a valid field of the controllers resource

Authorization

Authorization Overview

The MClimate API provides information that you can use to build home experiences. The information is ultimately owned by users, and users can explicitly choose to share this information with third-party products.

The purpose of authorization is to give your customers a secure means to grant access to their MClimate device data.

Client site or app before authorization

In your client site or app, you can provide a way for customers to give your product access to their MClimate device data. To do this, create a button or other UI element to initiate the OAuth flow.

When you build user authorization into your app, you can either:

use an external browser to authorize an app

use a new page to auth a web app

Warning: Do not use iFrames for user authorization.

Client site or app after authorization

After your customer authorizes your third-party product, we'll send an authorization code that your product can exchange for an access token. Your product can then send the access token with API calls to access MClimate data.

To learn how to set up an authorization flow for a user and obtain an access token, see Authentication and Authorization with OAuth 2.0.

Authentication and Authorization with OAuth 2.0

The MClimate API uses the OAuth 2.0 protocol for authentication and authorization (Check the official specification here).

Before your product can access private data using the MClimate API, it must obtain an access token that grants access to that API. A single access token can grant varying degrees of access to multiple sections of the API.

The authorization sequence begins when your product redirects a browser to a MClimate URL with query parameters indicating the requested access. MClimate handles the user authentication, session selection, and user consent. The result is an authorization code, which your product can exchange for an access token. Your product can then use the access token to make calls to the API.

Step 1 - Configure your third-party product

Note: You can skip this step if you already have registered your product (and you already have Client ID and Client secret).

Register for client credentials

In order to obtain credentials, you need to have an account in our platform. If you do not have one, go to registration form and fill in all required fields. Then, when you are signed in, you need to click on your email in the upper right corner, click on "Clients" and then create a new client. You will get all needed credentials.

Set redirect URI on your server

You have to set URI on your server where the authorization code will be sent and handled e.g. http://your-app-address/callback. Note that your server must be public (localhost will not work). For development you can use tunnelling solutions like ngrok or allowing public access for your IP.

Authorization URL

When you receive your client credentials you can test your authorization URL:

https://auth.seemelissa.com/?response_type=code&client_id={CLIENT_ID}&state={STATE}&redirect_uri={REDIRECT_URI}

The authorization URL includes a state parameter that you can use to test for possible cross-site

request forgery (CSRF) attacks. The redirect_uri is optional parameter used to specify the redirect URI if one was not provided or was invalid in the client registration form. The redirection endpoint URI MUST be an absolute URI.

Step 2 - Request an authorization code

After your product is configured, you can request an authorization code. The authorization code is not the final token that you use to make calls to MClimate. It is used in the next step of the OAuth 2.0 flow to exchange for an actual access token. This step provides assurance directly from MClimate to the user that permission is being granted to the correct product, with the agreed-upon access.

The user experience

We present a MClimate login page that asks the user to grant access to your product. To test this yourself, load the authorization URL from Step 1 into a browser. You should see an access request page:

Go ahead and enter your MClimate account credentials. After clicking the “Sign in” button you will be automatically redirected to the redirect URI you provided and already set.

e.g.: If you set your redirect URI to be http://your-server/callback then after successfully authorizing in the MClimate login page you will be redirected to http://your-server/callback?code={AUTHORIZATION_CODE}&state=xyz

By getting the code parameter you will receive your authorization code. Additionally you can check the state parameter too.

Step 3 - Exchange authorization code for an access token

The final step in obtaining an access token is for your product to ask for one using the authorization code it just acquired. This is done by making an "raw" HTTP POST request with Headers: Content-Type: application/json.

Note: Use this endpoint when requesting an access token: https://developer-api.seemelissa.com/v1/token

Parameter

Description

client_id

The "product ID" generated in Step 1

client_secret

The “product secret” generated in Step 1

grent_type

The value of this field should always be: authorization_code

code

The authorization code received in Step 2

redirect_uri

(Optional) If redirect uri was provided in the authorize url, use the same value as redirect_uri parameter

Key Point: Your authorization code is valid for one POST call.

Postman example (auth)

Postman provides an easy way to test an access token request. In the Headers tab, make sure Content-Type: application/json.

Access token response

A successful access token request returns a JSON object containing the following fields:

access_token — The access token for the user. This value must be kept secure.

expires_in — The number of seconds remaining, from the time it was requested, before the token expires.

Step 4 - Make authenticated requests

After a product obtains an access token, it sends the token to a MClimate API in an HTTP authorization header.

Note: Use this root URL when making Nest API calls: https://developer-api.seemelissa.com/v1

Postman example

API

You can see more detailed information or test the API at http://developers.mclimate.eu/tools.

In order to test the API you have to have your client_id and client_secret for your client app. If you haven’t registered your client yet, you can do that at developers.mclimate.eu. After receiving your client credentials, you can start making API requests from our API testing tool by clicking the “Authorize” button and providing client_id and client_secret.

User profile

Get user profile

Getting user profile is done by making a HTTP GET request with Headers: Content-Type: application/json, Authorization: Bearer {access_token}

URL

/users/me

Method

GET 

Headers

Content-Type: application/json

Authorization: Bearer {access_token}

Optional:

Accept-Response:Advanced

success response

Code: 200

Content:

{
  "users": {
    "user_id": 200,
    "username": "office@seemelissa.com",
    "firstname": "Melissa",
    "lastname": "Test Account",
    "phone": "",
    "role": "1",
    "country_id": 4308,
    "created": "2015-04-24 13:42:58"
  },
  "_links": {
    "self": {
      "href": "/v1/users"
    },
    "controller": {
      "href": "/v1/controller/{serial_number}",
      "templated": true
    }
  }
}

Error response

Code: 401 Unauthorized

Content:

{
  "type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
  "status": 401,
  "title": "Unauthorized",
  "detail": "",
  "auth_errors": {
    "missingHeader": "Please provide Authorization header"
  }
}

Sample call

curl -X GET "https://developer-api.seemelissa.com/v1/users/me" -H "accept: application/json" -H "authorization: Bearer"

Controllers

Fetch user’s controllers

Returns json data, containing array of user’s controllers. This endpoint supports pagination, so if the user has

URL

/controllers

Method

GET 

Headers

Content-Type: application/json

Authorization: Bearer {access_token}

Accept-Response: Advanced (Optional)

URL Params

Optional:

type=melissa | bobbie | smart_plug

mac=[mac address]

and other based on the model

Data params

None

success response

<What should the status code be on success and is there any returned data? This is useful when people need to to know what their callbacks should expect!>

Code: 200

Content:

{
  "_embedded": {
    "controller": [
      {
        "user_id": 200,
        "serial_number": “NFKI****A3L”,
        "mac": “ACCF2****40”,
        "firmware_version": "V1SHTHF",
        "name": “Melissa Name",
        "type": "melissa",
        "id": 513,
        "online": false,
        "brand_id": 14,
        "controller_log": [],
        "_relation": {
          "melissa": {
            "id": 29660,
            "controller_id": 513,
            "codeset_id": 197,
            "led_state": 1,
            "temperature_offset": 13,
            "humidity_offset": 15
          }
        },
        "_links": {
          "self": {
            "href": "/v1/controllers/NFKI513WA3L"
          }
        }
      }
    ]
  },
  "total": 1,
  "_links": {
    "self": {
      "href": "/v1/controllers"
    },
    "first": {
      "href": "/v1/controllers?page=1"
    },
    "last": {
      "href": "/v1/controllers?page=1"
    }
  }
}

Error response

Code: 401 Unauthorized

Content:

{
  "type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
  "status": 401,
  "title": "Unauthorized",
  "detail": "",
  "auth_errors": {
    "missingHeader": "Please provide Authorization header"
  }
}

Sample call

curl -X GET "https://developer-api.seemelissa.com/v1/controllers" -H "accept: application/json" -H "authorization: Bearer"

Control Melissa

Get sensor data

Performing a query to Melissa device and extracting sensor data is done by making a HTTP POST request with Headers: Content-Type: application/json, Authorization: Bearer {access_token}

URL

https://developer-api.seemelissa.com/v1/provider/fetch

Request

JSON object containing the following field:

serial_number— with value - the serial number of the device you want to query sensor data from.

Response

A successful fetch sensors data request returns a JSON object containing the following fields:

provider— parent key that contains all sensor data of the selected device

temp — temperature in celsius

raw_temperature — raw sensor data for the ambient temperature

humidity — humidity in %

raw_humidity - raw sensor data for the ambient humidity

Postman example

Sending IR Command to the AC

URL

/provider/send

Method

POST

Data params

{
  "serial_number": “{Melissa Serial Number}”,
  "command": "send_ir_code",
  “state": 1,//0-OFF; 1-ON; 2-Idle
  "mode": 3, //0-Auto; 1-Fan; 2-Heat; 3-Cool; 4-Dry
  "temp": 18,// number between 16 and 30 (depends on the codeset)
  "fan": 0 //0-Auto; 1-Low; 2-Med; 3-High
}

success response

Code: 200

Content:

{
  "provider": [
    254,
    2,
    0,
    0
  ],
  "_links": {
    "self": {
      "href": "/v1/provider/send"
    }
  }
}

Error response

Code: 401 Unauthorized

Content:

{
  "type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
  "status": 401,
  "title": "Unauthorized",
  "detail": "",
  "auth_errors": {
    "missingHeader": "Please provide Authorization header"
  }
}

Sample call

curl -X POST "https://developer-api.seemelissa.com/v1/providers/send" -H "accept: application/json" -H "authorization: Bearer {TOKEN}“ -H "Content-Type: application/json" -d "{ \"serial_number\": \”SERIAL_NUMBER\", \"command\": \"set_read_mode\", \"send_ir_code_options\": { \"state\": 0, \"mode\": 0, \"temp\": 0, \"fan\": 0 }}"

Turning OFF the LED light

URL

/provider/send

Method

POST

Data params

{
  "serial_number": “{Melissa Serial Number}”,
  "command": "turn_led_off"
}

success response

Code: 200

Content:

{
  "provider": [
    254,
    6,
    0,
    0
  ],
  "_links": {
    "self": {
      "href": "/v1/provider/send"
    }
  }
}

Error response

Code: 401 Unauthorized

Content:

{
  "type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
  "status": 401,
  "title": "Unauthorized",
  "detail": "",
  "auth_errors": {
    "missingHeader": "Please provide Authorization header"
  }
}

Sample call

curl -X POST "https://developer-api.seemelissa.com/v1/providers/send" -H "accept: application/json" -H "authorization: Bearer {TOKEN}“ -H "Content-Type: application/json" -d "{ \"serial_number\": \”SERIAL_NUMBER\", \"command\": \”turn_led_off\”}”

Turning ON the LED light

URL

/provider/send

Method

POST

Data params

{
  "serial_number": “{Melissa Serial Number}”,
  "command": "reset_color"
}

success response

Code: 200

Content:

{
  "provider": [
    254,
    7,
    0,
    0
  ],
  "_links": {
    "self": {
      "href": "/v1/provider/send"
    }
  }
}

Error response

Code: 401 Unauthorized

Content:

{
  "type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
  "status": 401,
  "title": "Unauthorized",
  "detail": "",
  "auth_errors": {
    "missingHeader": "Please provide Authorization header"
  }
}

Sample call

curl -X POST "https://developer-api.seemelissa.com/v1/providers/send" -H "accept: application/json" -H "authorization: Bearer {TOKEN}“ -H "Content-Type: application/json" -d "{ \"serial_number\": \”SERIAL_NUMBER\", \"command\": \”reset_color\”}”

Control Bobbie

Get sensor data

Performing a query to Bobbie device and extracting sensor data is done by making a HTTP POST request with Headers: Content-Type: application/json, Authorization: Bearer {access_token}

URL

https://developer-api.seemelissa.com/v1/provider/fetch

Request

JSON object containing the following field:

serial_number— with value - the serial number of the device you want to query sensor data from.

Response

A successful fetch sensors data request returns a JSON object containing the following fields:

provider— parent key that contains all sensor data of the selected device

cold - value of the cold pipe temperature sensor in celsius

hot - value of the hot pipe temperature sensor in celsius

home - value of the ambient temperature sensor in celsius

energy - electrical energy in kWh

voltage - value of measured voltage in V

current - value of electrical current in A

relay_state - state of the relay (1 - on, 0 - off)

load - indicator of load (boolean value)

Postman example

Control relay state (turn Bobbie on/off)

Performing a query to Bobbie device and changing the device state is done by making a HTTP POST request with Headers: Content-Type: application/json, Authorization: Bearer {access_token}

URL

https://developer-api.seemelissa.com/v1/provider/send

Request

JSON object containing the following field:

serial_number— with value - the serial number of the device you want to query sensor data from.

command - “switch_on_off”

state - receives values “on”/“off”

Response

A successful switch on/off request returns a response with status 200 and JSON object containing the following fields:

provider— parent key that contains all sensor data of the selected device

Postman example

Control Vicki

Get device data

Performing a query to Vicki device and extracting device`s data is done by making a HTTP POST request with Headers: Content-Type: application/json, Authorization: Bearer {access_token}

URL

https://developer-api.seemelissa.com/v1/provider/fetch

Request

JSON object containing:

serial_number— the serial number of the device you want to query data from.

Response

A successful fetch sensors data request returns a JSON object containing the following fields:

provider— parent key that contains all sensor data of the selected device

mac - mac address of the device

version - version of the device

uptime -

displayDigits - digits in range 5-30; to be regarded as Target Temperature

temperature - ambient temperature in celsius

humidity - relative ambient humidity in %

motorRange - total range of the step motor

motorPosition - current position of the step motor

batteryVoltage - battery voltage

ip - device IP

port - device communication port to MClimate Cloud

Postman example