Skip to content

Instantly share code, notes, and snippets.

@marcboon
Last active December 17, 2015 15:58

Revisions

  1. marcboon revised this gist May 24, 2013. 1 changed file with 10 additions and 11 deletions.
    21 changes: 10 additions & 11 deletions xively-shared-data-tags-agent.nut
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,7 @@
    // Xively account credentials
    const MyApiKey = YOUR_API_KEY
    const MyFeedID = YOUR_FEED_ID

    // Class for reading/writing a feed at xively.com (formerly cosm)
    class XivelyFeed {
    static url = "https://api.xively.com/v2/feeds/"
    @@ -23,7 +27,7 @@ class XivelyFeed {

    // Get current feed state
    function get() {
    local headers = { "X-ApiKey": apiKey, "Content-type": "application/json" }
    local headers = { "X-ApiKey": apiKey }
    local req = http.get(url + feedID + ".json", headers)
    local res = req.sendsync()
    server.log("GET: " + res.statuscode)
    @@ -90,17 +94,13 @@ class XivelyFeed {
    }
    }

    // Xively account credentials
    const MyApiKey = YOUR_API_KEY
    const MyFeedID = YOUR_FEED_ID

    // Send notication message to other agent
    // Send notification message to other agent
    function notifyAgent(agent, state) {
    local agentURL = "https://agent.electricimp.com/" + agent
    local body = { "agent_id": MyAgentID, "feed_id": MyFeedID, "datastream": state }
    local headers = { "Content-type": "application/json" }
    local req = http.post(agentURL, headers, http.jsonencode(body))
    req.sendasync(null) // send notication without waiting for result (target might be offline)
    local req = http.put(agentURL, headers, http.jsonencode(body))
    req.sendasync(null) // send notification without waiting for result (target might be offline)
    }

    // Post-update handler, notifies other devices
    @@ -141,14 +141,13 @@ device.on("put", function(data) {

    // Handler for updates from other agents
    http.onrequest(function(req, res) {
    // send OK response to the sender
    res.send(200, "OK")
    local feed = http.jsondecode(req.body)
    // verify if this is our feed
    if("feed_id" in feed && feed.feed_id == MyFeedID) {
    // send OK response to the sender
    res.send(200, "OK")
    device.send("update", feed.datastream)
    }
    else res.send(404, "Not Found")
    })

    // Start agent
  2. marcboon revised this gist May 24, 2013. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions xively-shared-data-tags-agent.nut
    Original file line number Diff line number Diff line change
    @@ -91,8 +91,8 @@ class XivelyFeed {
    }

    // Xively account credentials
    const MyApiKey = "yfrBGQLEKKwUcK3GAVZcUSrI70CSAKwzSXNCQlVXRDFKdz0g"
    const MyFeedID = "2051981947"
    const MyApiKey = YOUR_API_KEY
    const MyFeedID = YOUR_FEED_ID

    // Send notication message to other agent
    function notifyAgent(agent, state) {
  3. marcboon created this gist May 23, 2013.
    170 changes: 170 additions & 0 deletions xively-shared-data-tags-agent.nut
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,170 @@
    // 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)
    }

    // Get current feed state
    function get() {
    local headers = { "X-ApiKey": apiKey, "Content-type": "application/json" }
    local req = http.get(url + feedID + ".json", headers)
    local res = req.sendsync()
    server.log("GET: " + res.statuscode)
    return res.statuscode == 200 ? http.jsondecode(res.body) : null
    }

    // Get a datastream (channel)
    function getStream(id) {
    local feed = get()
    if(feed != null) {
    foreach(stream in feed.datastreams) {
    if(stream.id == id) return stream // stream found
    }
    }
    return null // stream not found
    }

    // Get tags for this feed as array
    function getTags() {
    local feed = get()
    if(feed != null) {
    if("tags" in feed) return feed.tags // return array with tags
    else return [] // no tags, return empty array
    }
    return null // failed to get tags
    }

    // Set tags for this feed
    function setTags(tags) {
    local body = { "version": "1.0.0", "tags": tags }
    local headers = { "X-ApiKey": apiKey, "Content-type": "application/json" }
    local req = http.put(url + feedID + ".json", headers, http.jsonencode(body))
    if(req.sendsync().statuscode == 200) {
    server.log("tags updated: " + http.jsonencode(tags))
    return tags
    }
    server.log("setTags failed")
    return null
    }

    // Add a tag to this feed
    function addTag(tag) {
    local tags = getTags()
    if(tags != null) {
    if(tags.find(tag) == null) {
    tags.push(tag)
    tags = setTags(tags)
    }
    }
    return tags
    }

    // Remove a tag from this feed
    function removeTag(tag) {
    local tags = getTags()
    if(tags != null) {
    local i = tags.find(tag)
    if(i != null) {
    tags.remove(i)
    tags = setTags(tags)
    }
    }
    return tags
    }
    }

    // Xively account credentials
    const MyApiKey = "yfrBGQLEKKwUcK3GAVZcUSrI70CSAKwzSXNCQlVXRDFKdz0g"
    const MyFeedID = "2051981947"

    // Send notication message to other agent
    function notifyAgent(agent, state) {
    local agentURL = "https://agent.electricimp.com/" + agent
    local body = { "agent_id": MyAgentID, "feed_id": MyFeedID, "datastream": state }
    local headers = { "Content-type": "application/json" }
    local req = http.post(agentURL, headers, http.jsonencode(body))
    req.sendasync(null) // send notication without waiting for result (target might be offline)
    }

    // Post-update handler, notifies other devices
    function onUpdate(res) {
    server.log("PUT: " + res.statuscode)
    local tags = feed.getTags()
    if(tags != null) {
    // notify agents
    local state = feed.getStream("LED")
    foreach(tag in tags) {
    // agentIDs are prefixed with @
    if(tag[0] == '@') {
    // Skip self
    if(tag != MyAgentID)
    notifyAgent(tag.slice(1), state)
    }
    }
    }
    }

    // Add agentID to this feed's tags when device connects
    device.onconnect(function() {
    server.log("device connected")
    feed.addTag(MyAgentID)
    })

    // Remove agentID from this feed's tags when device disconnects
    device.ondisconnect(function() {
    server.log("device disconnected")
    feed.removeTag(MyAgentID)
    })

    // Handler for updates from device
    device.on("put", function(data) {
    server.log(http.jsonencode(data))
    feed.put(data, onUpdate)
    })

    // Handler for updates from other agents
    http.onrequest(function(req, res) {
    local feed = http.jsondecode(req.body)
    // verify if this is our feed
    if("feed_id" in feed && feed.feed_id == MyFeedID) {
    // send OK response to the sender
    res.send(200, "OK")
    device.send("update", feed.datastream)
    }
    else res.send(404, "Not Found")
    })

    // Start agent
    server.log("agent started")

    // Create xively feed object
    feed <- XivelyFeed(MyApiKey, MyFeedID)

    // This imp's agentID (agentURL with domain replaced by @)
    MyAgentID <- "@" + http.agenturl().slice(29)
    server.log("agentID: " + MyAgentID)

    // Add agentID to this feed's tags
    feed.addTag(MyAgentID)

    // Get initial state
    state <- feed.getStream("LED")
    server.log(http.jsonencode(state))
    device.send("update", state)
    30 changes: 30 additions & 0 deletions xively-shared-data-tags-device.nut
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,30 @@
    imp.configure("xively-shared-data-tags", [], [])

    sw <- hardware.pin1
    led <- hardware.pin2

    sw.configure(DIGITAL_IN_PULLUP)
    led.configure(DIGITAL_OUT)

    agent.on("update", function(data) {
    if("id" in data && data.id == "LED") {
    local val = data.current_value.tointeger()
    server.log("update: " + val)
    led.write(val)
    }
    })

    // toggle LED when switch is pressed
    function readswitch() {
    imp.wakeup(0.05, readswitch)
    local now = sw.read()
    if(now != prev && now == 0) {
    local val = 1 - led.read()
    led.write(val)
    agent.send("put", { "LED": val })
    }
    prev = now
    }

    prev <- sw.read()
    readswitch()