Skip to content

Instantly share code, notes, and snippets.

@hfiennes
Created July 24, 2019 21:10
Show Gist options
  • Save hfiennes/26c04f87c86adc9de63187d744490cb6 to your computer and use it in GitHub Desktop.
Save hfiennes/26c04f87c86adc9de63187d744490cb6 to your computer and use it in GitHub Desktop.
Tinamous demo with explorer kit
// Class for talking to tinamous; not library quality at this point!
class Tinamous {
_account = null;
_device = null;
_password = null;
_clientid = null;
_mqttclient = null;
_connectcb = null;
function constructor(account, device, password, clientid = null) {
_account = account;
_device = device;
_password = password;
_clientid = clientid;
// Create the client here, so eg message handlers can be registered before connect
_mqttclient = mqtt.createclient();
}
// Queue a reconnect in 60s
function _retryConnect() {
if (_mqttclient) {
imp.wakeup(60, function() { connect(_connectcb); }.bindenv(this));
}
}
function _connectHandler(result) {
// Connect failed?
if (result != 0) {
// Tell handler and retry later
if (_connectcb) _connectcb(result);
_retryConnect();
return;
}
// Connect successful; subscribe to command channel (all commands)
_mqttclient.subscribe("/Tinamous/V1/Commands/"+_device+"/#", mqtt.AT_MOST_ONCE, function(result, mode) {
// This is the subscription acknowledgement callback
if (result == 0 && mode < 0x80) {
// We are subscribed, fire the callback saying all is ok
_connectcb(0);
} else {
// We couldn't subscribe for some reason so inform the user
_connectcb(result);
}
}.bindenv(this));
}
function connect(connectCallback) {
// Save connect callback as we will call it on retries too
_connectcb = connectCallback;
// If we were already connected, disconnect
if (_mqttclient.isconnected()) {
_mqttclient.disconnect();
}
// Ensure connection handler is registered
_mqttclient.onconnect(_connectHandler.bindenv(this));
// Reconnect if we lose connection
_mqttclient.onconnectionlost(_retryConnect.bindenv(this));
// Attempt connection
local options = { "username": _device+"."+_account, "password": _password };
_mqttclient.connect("ssl://"+_account+".tinamous.com:8883",
_clientid?_clientid:imp.configparams.deviceid,
options);
}
function postMeasurement(measurement, cb = null) {
// Format as JSON, post to measurement endpoint
local message = _mqttclient.createmessage("/Tinamous/V1/Measurements/Json", http.jsonencode(measurement), {});
// Send it and pass callback
message.sendasync(cb?cb.bindenv(this):null);
}
// Post a status message to the device timeline
function postStatus(status, cb = null) {
_mqttclient.createmessage("/Tinamous/V1/Status", status, {}).sendasync(cb?cb.bindenv(this):null);
}
// Just registers the handler directly
function registerCommandhandler(handler) {
_mqttclient.onmessage(handler);
}
}
// Tinamous details
account <- "accountname";
devname <- "deviceusername";
password <- "devicepassword";
// Connect to tinamous
tinamous <- Tinamous(account, devname, password);
tinamous.connect(function(v) {
if (v == 0) {
server.log("Successfully connected to Tinamous & subscribed to commands");
tinamous.postStatus("Device "+devname+" connected to MQTT");
} else server.log("Did not connect, code "+v+" (retrying in 60s)");
}.bindenv(this));
// (optional) Register a command handler
tinamous.registerCommandhandler(function(m) {
// Just log that we got a command for now
// Body is binary (a blob) hence convert to a string to make it printable
server.log("got command "+m.topic+":"+m.message.tostring());
});
// When we get a message from the device, log and push it to Tinamous
device.on("reading", function(v) {
server.log(format("Current Humidity: %0.2f %s, Current Temperature: %0.2f °C", v.humidity, "%", v.temperature));
// Send to Tinamous
tinamous.postMeasurement(v, function(result) {
server.log("mqtt publish returned "+result);
});
});
#require "HTS221.device.lib.nut:2.0.1"
imp.enableblinkup(false);
hardware.i2c89.configure(CLOCK_SPEED_400_KHZ);
tempHumid <- HTS221(hardware.i2c89);
tempHumid.setMode(HTS221_MODE.ONE_SHOT);
function poll() {
local result = tempHumid.read();
if ("error" in result) {
server.error("An Error Occurred: " + result.error);
} else {
agent.send("reading", result);
}
}
poll();
// Go to sleep for 5 mins
imp.onidle(function() {
server.flush(1);
server.disconnect();
imp.deepsleepfor(5*60);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment