Queries with QL

The Jilia API supports searching across servers and devices using the Calypso Query Language syntax. To perform queries, simply add a ql query parameter to your API calls. Its value is a SQL-like syntax for filtering the API results.

In all examples below, the text {token} should be replaced with your authorization token. See the Authentication page for more information. If you already have a registered Jilia application, you can use the Quick Start page to generate a new token.

For more information on sending HTTP requests to Jilia, see the Device Interaction documentation page.

Note: When executing cURL, remember that blank spaces and other special characters must be formatted for use as a valid URL. The need to perform this conversion manually will depend on the language and framework making the request. As an example, the JavaScript environment in most browsers provides a encodeURI method. You can test its result using the input below.


  

Scenario

There are two activated servers. Each server has two thermostats, contacts, and on-off switches.

HUB-c2e28680-1669-4cf2-b0f9-41a3b7be5c26
Type Name URL
thermostat Thermostat1 https://api.jilia.io/v1/servers/HUB-c2e28680-1669-4cf2-b0f9-41a3b7be5c26/devices/0cb6613a-81d6-4310-9af1-da302a3130fd
thermostat Thermostat2 https://api.jilia.io/v1/servers/HUB-c2e28680-1669-4cf2-b0f9-41a3b7be5c26/devices/6c7550a0-8f06-4d12-a462-50b137d38964
contact Door1 https://api.jilia.io/v1/servers/HUB-c2e28680-1669-4cf2-b0f9-41a3b7be5c26/devices/87fb4d98-6da8-421e-98f2-198c5a5f150d
contact Door2 https://api.jilia.io/v1/servers/HUB-c2e28680-1669-4cf2-b0f9-41a3b7be5c26/devices/c5198af7-9788-4e53-b804-331445a2bae3
on-off Relay1 https://api.jilia.io/v1/servers/HUB-c2e28680-1669-4cf2-b0f9-41a3b7be5c26/devices/ab31b98b-c1c5-4a7f-adc8-affa02dafda8
on-off Relay2 https://api.jilia.io/v1/servers/HUB-c2e28680-1669-4cf2-b0f9-41a3b7be5c26/devices/bdfbc278-7f0b-40be-99b5-4bbcbd5d915a
HUB-d4583665-202d-468b-bcb4-eead10c61010
Type Name URL
thermostat Thermostat1 https://api.jilia.io/v1/servers/HUB-d4583665-202d-468b-bcb4-eead10c61010/devices/3ba28fb6-ed29-49d9-b9dd-ef8a87183f2a
thermostat Thermostat2 https://api.jilia.io/v1/servers/HUB-d4583665-202d-468b-bcb4-eead10c61010/devices/8bfc1223-efe4-436e-bce4-ba8c00f86007
contact Door1 https://api.jilia.io/v1/servers/HUB-d4583665-202d-468b-bcb4-eead10c61010/devices/80298cc4-4c57-4254-95a5-ffd35beb2a24
contact Door2 https://api.jilia.io/v1/servers/HUB-d4583665-202d-468b-bcb4-eead10c61010/devices/0e0e5b2b-00b0-48d4-ad37-1e9b7da37c53
on-off Relay1 https://api.jilia.io/v1/servers/HUB-d4583665-202d-468b-bcb4-eead10c61010/devices/f2860363-3bc0-4d66-9254-586012220606
on-off Relay2 https://api.jilia.io/v1/servers/HUB-d4583665-202d-468b-bcb4-eead10c61010/devices/f348230d-e3ae-41b0-8194-fae550c10fab

Query A Server

No Filter

Using cURL, we can query the first server directly to see all devices.

curl -H "Authorization: Bearer {token}" 'https://api.jilia.io/v1/servers/HUB-c2e28680-1669-4cf2-b0f9-41a3b7be5c26'
{
"entities": [
  {
    "class": [
      "device",
      "thermostat"
    ],
    "properties": {
      "id": "0cb6613a-81d6-4310-9af1-da302a3130fd",
      "name": "Thermostat1",
      "current-temperature": 76.36,
      "heating-setpoint": 76,
      "cooling-setpoint": 76,
      "system-mode": "cool",
      "running-mode": "off",
      "drift": 1.5,
      "type": "thermostat",
      "state": "ready"
    }
  },
  {
    "class": [
      "device",
      "thermostat"
    ],
    "properties": {
      "id": "6c7550a0-8f06-4d12-a462-50b137d38964",
      "name": "Thermostat2",
      "current-temperature": 73.62,
      "heating-setpoint": 76,
      "cooling-setpoint": 76,
      "system-mode": "cool",
      "running-mode": "off",
      "drift": 1.5,
      "type": "thermostat",
      "state": "ready"
    }
  },
  {
    "class": [
      "device",
      "contact"
    ],
    "properties": {
      "id": "87fb4d98-6da8-421e-98f2-198c5a5f150d",
      "name": "Door1",
      "contact": "open",
      "type": "contact"
    }
  },
  {
    "class": [
      "device",
      "contact"
    ],
    "properties": {
      "id": "c5198af7-9788-4e53-b804-331445a2bae3",
      "name": "Door2",
      "contact": "closed",
      "type": "contact"
    }
  },
  {
    "class": [
      "device",
      "on-off"
    ],
    "properties": {
      "id": "ab31b98b-c1c5-4a7f-adc8-affa02dafda8",
      "name": "Relay1",
      "on-off": "off",
      "type": "on-off",
      "state": "ready"
    }
  },
  {
    "class": [
      "device",
      "on-off"
    ],
    "properties": {
      "id": "bdfbc278-7f0b-40be-99b5-4bbcbd5d915a",
      "name": "Relay2",
      "on-off": "off",
      "type": "on-off",
      "state": "ready"
    }
  }
}

Filter on Device Type

To view only the on-off devices, append a ql query parameter to the server URL. Its value will specify a filter against the device type property: where type="on-off"

curl -H "Authorization: Bearer {token}" 'https://api.jilia.io/v1/servers/HUB-c2e28680-1669-4cf2-b0f9-41a3b7be5c26?ql=where%20type="on-off"'

With the added ql query parameter, the collection of devices returned is now filtered down to the two that match the device type specified.

{
"entities": [
  {
    "class": [
      "device",
      "on-off"
    ],
    "properties": {
      "id": "ab31b98b-c1c5-4a7f-adc8-affa02dafda8",
      "name": "Relay1",
      "on-off": "off",
      "type": "on-off",
      "state": "ready"
    },
  },
  {
    "class": [
      "device",
      "on-off"
    ],
    "properties": {
      "id": "bdfbc278-7f0b-40be-99b5-4bbcbd5d915a",
      "name": "Relay2",
      "on-off": "off",
      "type": "on-off",
      "state": "ready"
    }
  }
]}

Filter on Device State

We can query against any of the device properties. Instead of looking for certain types of devices, we can search for devices based on their current state. For example, let's find thermostats that have fallen below a certain temperature.

The unencoded ql value for the query is where current-temperature < 75

curl -H "Authorization: Bearer {token}" 'https://api.jilia.io/v1/servers/HUB-c2e28680-1669-4cf2-b0f9-41a3b7be5c26?ql=where%20current-temperature%20%3C%2075'

The above query filters down the collection of returned devices to a single thermostat.

{
  "entities": [{
    "class": [
      "device",
      "thermostat"
    ],
    "properties": {
      "id": "0cb6613a-81d6-4310-9af1-da302a3130fd",
      "name": "Thermostat1",
      "current-temperature": 69.37,
      "heating-setpoint": 65,
      "cooling-setpoint": 72,
      "system-mode": "cool",
      "running-mode": "off",
      "drift": 1.5,
      "type": "thermostat",
      "state": "ready"
    }
  }]
}

Query All Servers

The previous examples used ql to query against devices of a specific server. But it is also possible to query against all active servers. To do so, return to the root Jilia API URL and include the following query parameter and value: server=*.

For example, let's find all contact devices.

curl -H "Authorization: Bearer {token}" 'https://api.jilia.io/v1/?ql=where%20type="contact"&server=*'

The result is an entities collection with four devices. Included in the abbreviated response below is the self link href values. Notice that there are two distinct URLs, one per active server.

{
  "entities": [
    {
      "class": [
        "device",
        "contact"
      ],
      "properties": {
        "id": "87fb4d98-6da8-421e-98f2-198c5a5f150d",
        "name": "Door1",
        "contact": "open",
        "type": "contact"
      },
      "links": [
        {
          "rel": ["self", "edit"],
          "href": "https://api.jilia.io/v1/servers/HUB-c2e28680-1669-4cf2-b0f9-41a3b7be5c26/devices/87fb4d98-6da8-421e-98f2-198c5a5f150d"
        }
      ]
    },
    {
      "class": [
        "device",
        "contact"
      ],
      "properties": {
        "id": "c5198af7-9788-4e53-b804-331445a2bae3",
        "name": "Door2",
        "contact": "closed",
        "type": "contact"
      },
      "links": [
        {
          "rel": ["self", "edit"],
          "href": "https://api.jilia.io/v1/servers/HUB-c2e28680-1669-4cf2-b0f9-41a3b7be5c26/devices/c5198af7-9788-4e53-b804-331445a2bae3"
        }
      ]
    },
    {
      "class": [
        "device",
        "contact"
      ],
      "properties": {
        "id": "80298cc4-4c57-4254-95a5-ffd35beb2a24",
        "name": "Door1",
        "contact": "open",
        "type": "contact"
      },
      "links": [
        {
          "rel": ["self", "edit"],
          "href": "https://api.jilia.io/v1/servers/HUB-d4583665-202d-468b-bcb4-eead10c61010/devices/80298cc4-4c57-4254-95a5-ffd35beb2a24"
        }
      ]
    },
    {
      "class": [
        "device",
        "contact"
      ],
      "properties": {
        "id": "0e0e5b2b-00b0-48d4-ad37-1e9b7da37c53",
        "name": "Door2",
        "contact": "closed",
        "type": "contact"
      },
      "links": [
        {
          "rel": ["self", "edit"],
          "href": "https://api.jilia.io/v1/servers/HUB-d4583665-202d-468b-bcb4-eead10c61010/devices/0e0e5b2b-00b0-48d4-ad37-1e9b7da37c53"
        }
      ]
    }
  ]
}

As a final example, let's refine the above search to only include contact devices whose state is currently "open". The unencoded ql value is: where type="contact" and contact="open"

curl -H "Authorization: Bearer {token}" 'https://api.jilia.io/v1/?ql=where%20type=%22contact%22%20and%20contact=%22open%22&server=*'

The results below have been trimmed to display the properties of each entity result. We can see that at the time the query was executed, there were three contact devices (across all servers) in the "open" state.

{
  "entities": [
    {
      "properties": {
        "id": "87fb4d98-6da8-421e-98f2-198c5a5f150d",
        "name": "Door2",
        "contact": "open",
        "type": "contact"
      }
    },
    {
      "properties": {
        "id": "80298cc4-4c57-4254-95a5-ffd35beb2a24",
        "name": "Door1",
        "contact": "open",
        "type": "contact"
      }
    },
    {
      "properties": {
        "id": "0e0e5b2b-00b0-48d4-ad37-1e9b7da37c53",
        "name": "Door2",
        "contact": "open",
        "type": "contact"
      }
    }
  ]
}