Skip to main content

Quickstart

A very simple example to get you started with Dimension Four.

For an explanation about the terms you see used here, like space, points and signals, see the api reference

Dashboard

Start in the dashboard by creating and logging in to an account, creating a tenant, and finally a couple of tokens.

Create Account

Go to Dashboard, create an account and log in.

create account

Create tenant

Create a new tenant.

create tenant

Create tokens

Create two tokens. One admin token, (and if you plan on sharing this with anyone - one readonly token). create admin token create read only token

API

You can use any http client or graphql client, but the grapgql playground is quick and easy for testing.

Create Space

Query
mutation CREATE_SPACE {
space {
create(input: { name: "All devices" }) {
id
name
}
}
}

create space

Create Point

Query
mutation CREATE_POINT {
point {
create(input: {
spaceId: "<insert_spaceId>"
name: "Our device with sensors"
}){
id
}
}
}

create point

Create Signal

Query
mutation CREATE_SIGNAL {
signal {
create(input: {
pointId: "<insert_pointId>"
signals: [
{
unit: CELSIUS_DEGREES
value: "22.2"
type: "air temperature"
timestamp: "2021-11-17T14:30:21.000+00:00"
}
]
}) {
id
pointId
unit
type
data {
numericValue
rawValue
}
}
}
}

create signal

Query last 10 signals from any device

Query
query LATEST_SIGNALS {
signals(
paginate: { last:10 }
){
edges {
node {
id
timestamp
createdAt
type
unit
pointId
data {
numericValue
rawValue
}
}
}
}
}

query last 10 signals

Query signal from one point

Query
query LATEST_SIGNAL_FROM_MY_DEVICE {
points(where: { name: { _EQ: "Our device with sensors" } }) {
edges {
node {
temperature: signals(
where: { type: { _EQ: "air temperature" }}
paginate: { last:1 }
){
edges {
node {
id
timestamp
createdAt
type
unit
pointId
data {
numericValue
rawValue
}
}
}
}
}
}
}
}

query last signal from one point

Browser example (counter)

Finally, you can use this example code to see how this could be used client side in a browser. For more examples see http examples

Code
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello World</title>
</head>
<body>
<h1>Hello World</h1>
<div id="counter" class="counter">
<div id="number" class="number"></div>
</div>
<div id="error" class="error"></div>
</body>

<style>
html {
font-family: Arial, Helvetica, sans-serif;
background-color: blanchedalmond;
}

.counter {
background-color: blueviolet;
max-width: fit-content;
min-width: 40px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 5px;
font-size: large;
font-weight: bold;
color: white;
}

.number {
padding: 5px;
}

.error {
color: red;
}
</style>

<script>
const API_URL = "https://iot.dimensionfour.io/graph";
const TENANT_ID = "<tenant-id>";
const TENANT_KEY = "<tenant-key>";

const QUERY = `
query LATEST_SIGNAL_FROM_MY_DEVICE {
points(where: { name: { _EQ: "Our device with sensors" } }) {
edges {
node {
temperature: signals(
where: { type: { _EQ: "air temperature" }}
paginate: { last:1 }
){
edges {
node {
id
timestamp
createdAt
type
unit
pointId
data {
numericValue
rawValue
}
}
}
}
}
}
}
}`;

let variables = {
deviceName: "Our device with sensors",
type: "air temperature",
};

run();

function showError(error) {
let holder = document.getElementById("error");
holder.innerHTML = holder.innerHTML + JSON.stringify(error);
let _x = document.getElementById("error");
_x.style.display = "block";
}

async function run() {
const data = await getData();
if (data && data.data.points.edges.length > 0) {
let count =
data.data.points.edges[0].node.temperature.edges[0].node.data
.rawValue;
document.getElementById("number").innerHTML = count;
} else {
showError("No data found");
}
}

async function getData() {
try {
const res = await fetch(API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-tenant-id": TENANT_ID,
"x-tenant-key": TENANT_KEY,
},
body: JSON.stringify({ query: QUERY, variables: variables }),
});
const body = await res.json();
if (body.errors) {
showError(body.errors);
return;
}
return body;
} catch (error) {
showError(error.toString());
}
}
</script>
</html>

Make sure to use your readonly token in this example if you want to share this with anyone.

dashboard

Browser example (chart)

Code
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.7.1/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment@2.27.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment@0.1.1"></script>
<meta charset="utf-8" />
<title>Hello World</title>
</head>
<body>
<h1>Hello World</h1>
<div id="error" class="error"></div>
<div id="chartContainer" class="chartContainer">
<canvas id="myChart" width="100%" height="100%"></canvas>
</div>
</body>

<style>
html {
font-family: Arial, Helvetica, sans-serif;
background-color: blanchedalmond;
}

.counter {
background-color: blueviolet;
max-width: fit-content;
min-width: 40px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 5px;
font-size: large;
font-weight: bold;
color: white;
}

.number {
padding: 5px;
}

.error {
color: red;
}

.chartContainer {
height: 200px;
width: 200px;
}
</style>

<script>
const API_URL = "https://iot.dimensionfour.io/graph";
const TENANT_ID = "<your tenant id>";
const TENANT_KEY = "<your readonly token>";

const QUERY = `
query LATEST_SIGNAL_FROM_MY_DEVICE(
$deviceName: String!
$type: String!
$fromTime: Timestamp!
) {
points(where: {
name: { _EQ: $deviceName }
createdAt: { _GT: $fromTime }
}) {
edges {
node {
temperature: signals(
where: { type: { _EQ: $type }}
paginate: { last: 10 }
){
edges {
node {
id
timestamp
createdAt
type
unit
pointId
data {
numericValue
rawValue
}
}
}
}
}
}
}
}`;

let lastXHours = 2;
let fromTime = new Date();
fromTime.setHours(fromTime.getHours() - lastXHours);

let variables = {
deviceName: "Our device with sensors",
type: "air temperature",
fromTime: fromTime,
};

run();

async function run() {
const data = await getData();
if (data && data.data.points.edges.length > 0) {
const { timestamps, values } = formatData(data);
drawChart({ timestamps, values });
} else {
showError("No data found");
}
}

function showError(error) {
let holder = document.getElementById("error");
holder.innerHTML = holder.innerHTML + JSON.stringify(error);
let _x = document.getElementById("error");
_x.style.display = "block";
}

function formatData(data) {
let input = data.data.points.edges[0].node.temperature.edges;
let timestamps = [];
let values = [];
input.forEach((item) => {
timestamps.push(new Date(item.node.createdAt));
values.push(item.node.data.numericValue);
});
return { timestamps, values };
}

async function getData() {
try {
const res = await fetch(API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-tenant-id": TENANT_ID,
"x-tenant-key": TENANT_KEY,
},
body: JSON.stringify({ query: QUERY, variables: variables }),
});
const body = await res.json();
if (body.errors) {
showError(body.errors);
return;
}
return body;
} catch (error) {
showError(error.toString());
}
}

function drawChart(data) {
const ctx = document.getElementById("myChart").getContext("2d");
const myChart = new Chart(ctx, {
type: "line",
data: {
labels: data.timestamps,
datasets: [
{
label: `ºC`,
data: data.values,
backgroundColor: ["rgba(153, 102, 255, 0.2)"],
borderColor: ["rgba(153, 102, 255, 1)"],
borderWidth: 3,
},
],
},
options: {
plugins: {
legend: {
display: false,
},
},
scales: {
x: {
type: "time",
display: false,
ticks: {
source: "auto",
},
},
},
},
});
}
</script>
</html>

Make sure to use your readonly token in this example if you want to share this with anyone.

dashboard