DEV Community

Cover image for DeviceScript - Temperature + MQTT
Peli de Halleux
Peli de Halleux

Posted on • Originally published at microsoft.github.io

DeviceScript - Temperature + MQTT

This article uses an ESP32-C3 board Adafruit QT Py C3
and a SHTC3 sensor to publish a temperature reading to
the Adafruit.io MQTT APIs every minute using DeviceScript.

DeviceScript

DeviceScript brings JavaScript/TypeScript to tiny IoT devices such as the ESP32. DeviceScript provides a user friendly editing/debugging experience in Visual Studio Code.

Reading temperature

We start by configuring the script for the QT Py and adding a scheduled interval to read the temperature
from the SHTC3 sensor every 60 seconds.

// hardware configuration and drivers
import "@dsboard/adafruit_qt_py_c3"
import { startSHTC3 } from "@devicescript/drivers"
import { schedule } from "@devicescript/runtime"

// mounting a temperature server for the SHTC3 sensor
const { temperature } = await startSHTC3()

schedule(
    async () => {
        // read data from temperature sensor
        const value = await temperature.reading.read()
    },
    { timeout: 1000, interval: 60000 }
)
Enter fullscreen mode Exit fullscreen mode

Configuration and Secrets

To connect to Adafruit.io, you will to get an account with https://io.adafruit.com
and store your username and password in the settings
as the IO_USERNAME and IO_KEY keys (make sure your key is in env.local).
Also create a feed and update the feed key in the example below.

import { readSetting } from "@devicescript/settings"

// TODO: update feed key
const feed = "temperature"
const username = await readSetting("IO_USERNAME")
// this secret is stored in the .env.local 
// and uploaded to the device settings
const password = await readSetting("IO_KEY")
Enter fullscreen mode Exit fullscreen mode

Starting the MQTT client

Following the Adafruit documentation,
we start a MQTT connection and craft a topic that will route the data to our account.

import { startMQTTClient } from "@devicescript/net"

...

const mqtt = await startMQTTClient({
    host: `io.adafruit.com`,
    proto: "tls",
    port: 8883,
    username,
    password,
})
const topic = `${username}/feeds/${feed}/json`
Enter fullscreen mode Exit fullscreen mode

Publish data

With the MQTT client and the topic, we can add a call to mqtt.publish in the scheduled worker
to upload the data to Adafruit (note that { value } expands to JSON { "value": value } automatically)

schedule(
    async () => {        
        ...
        // publish data to Adafruit
        await mqtt.publish(topic, { value })
    },
    { timeout: 1000, interval: 60000 }
)
Enter fullscreen mode Exit fullscreen mode

All together

Putting all the pieces together we get the following program.

import "@dsboard/adafruit_qt_py_c3"
import { startSHTC3 } from "@devicescript/drivers"
import { startMQTTClient } from "@devicescript/net"
import { readSetting } from "@devicescript/settings"
import { schedule } from "@devicescript/runtime"

const { temperature } = await startSHTC3()

const feed = "temperature"
const username = await readSetting("IO_USERNAME")
device settings
const password = await readSetting("IO_KEY")

const mqtt = await startMQTTClient({
    host: `io.adafruit.com`,
    proto: "tls",
    port: 8883,
    username,
    password,
})
const topic = `${username}/feeds/${feed}/json`

schedule(
    async () => {
        const value = await temperature.reading.read()
        await mqtt.publish(topic, { value })
    },
    { timeout: 1000, interval: 60000 }
)
Enter fullscreen mode Exit fullscreen mode

Extra points: Filtering data

You could use observables to smooth the sensor
data. For example, apply an exponentially moving average
on the feed of temperature readings.

import { ewma, auditTime } from "@devicescript/observables"
...
temperature.reading
    .pipe(ewma(0.5), auditTime(60000))
    .subscribe(async value => await mqtt.publish(topic, { value }))
Enter fullscreen mode Exit fullscreen mode

Top comments (0)