Skip to content

Instantly share code, notes, and snippets.

@marcboon
Last active December 18, 2015 06:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcboon/5740771 to your computer and use it in GitHub Desktop.
Save marcboon/5740771 to your computer and use it in GitHub Desktop.
Electric imp round-trip latency logger, using xively.com. It measures round-trip latency by feeding an output port back to an input port. Public feed of latency stats available at https://xively.com/feeds/220375411
// round-trip-latency-xively
// measures round-trip latency by sending inverted input back to output, log to xively.com
// [agent code]
// Xively account credentials
const MyApiKey = PRIVATE_API_KEY
const MyFeedID = "220375411"
// Class for reading/writing a feed at xively.com (formerly cosm)
class XivelyFeed {
static url = "https://api.xively.com/v2/feeds/"
apiKey = null
feedID = null
constructor(apiKey, feedID) {
this.apiKey = apiKey
this.feedID = feedID
}
// Send data to feed, expects a table with channel:value pairs
function put(data, callback) {
local datastreams = []
foreach(channel, value in data) {
datastreams.push({ "id": channel, "current_value": value })
}
local body = { "version": "1.0.0", "datastreams": datastreams }
local headers = { "X-ApiKey": apiKey, "Content-type": "application/json" }
local req = http.put(url + feedID + ".json", headers, http.jsonencode(body))
req.sendasync(callback)
}
}
// Handler for updates from device
device.on("put", function(data) {
feed.put(data, function(res) {
server.log("update: " + res.statuscode)
})
})
// Start agent
server.log("agent started")
// Create xively feed object
feed <- XivelyFeed(MyApiKey, MyFeedID)
// round-trip-latency-xively
// measures round-trip latency by sending inverted input back to output, log to xively.com
// [device code]
const ONESECOND = 1000 // 1 second in ms
const INTERVAL = 60 // 1 minute reporting interval
led <- hardware.pin9
led.configure(DIGITAL_OUT)
out <- OutputPort("out")
class In extends InputPort {
type = "bool"
name = "in"
function set(value) {
// toggle output
local now = hardware.millis()
led.write(value)
out.set(1 - value)
// do statistics
local val = now - t
t = now
if(val > latency.max) latency.max = val
if(val < latency.min) latency.min = val
latency.avg += val
latency.cnt++
if(now >= timer && latency.cnt > 0) {
latency.avg /= latency.cnt
server.log(format("cnt: %d, avg: %d, min: %d, max: %d", latency.cnt, latency.avg, latency.min, latency.max))
// send latency stats to agent for publishing on xively.com
agent.send("put", latency)
// reset stats
timer = t + INTERVAL * ONESECOND
latency.min = INTERVAL * ONESECOND
latency.max = 0
latency.avg = 0
latency.cnt = 0
imp.wakeup(INTERVAL, watchdog)
}
}
}
function watchdog() {
if(latency.cnt == 0) {
imp.wakeup(INTERVAL, watchdog)
// report interval without data
agent.send("put", { cnt = 0 })
// restart
t = hardware.millis()
timer = t + INTERVAL * ONESECOND
out.set(1)
}
}
imp.configure("round-trip-latency-xively", [In()], [out])
// init values
latency <- {
min = INTERVAL * ONESECOND
max = 0
avg = 0
cnt = 0
}
// init timers
t <- hardware.millis()
timer <- t + INTERVAL * ONESECOND
// start
imp.wakeup(INTERVAL, watchdog)
out.set(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment