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 }
)
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")
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`
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 }
)
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 }
)
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 }))
Top comments (0)