Skip navigation

Introduction

At JiveWorld and in a few places here in the community there have been references to the Internet of Things.  It was at JiveWorld that I decided it would be neat to combine something that qualifies as an Internet of Things project while also involving the JIve SDK.  Like everyone else finding the time is always the catch but I finally found the time this past weekend to put together a small project that helps with learning a little bit about the Jive SDK and some simple hardware setup.

 

I choose the Raspberry Pi for this project since it will provide the necessary connection to the Internet as well as the ability to read general purpose input/output (GPIO).  The Raspberry Pi has been mentioned before here in the developer community but the link for setup is apparently gone now (Jive Purposeful Place Integration Service works on Raspberry Pi!)

 

In this project the Raspberry Pi will gather three readings using a humidity/temperature sensor and some internal data.  Those three readings will be the cpu temperature, room temperature, and humidity.  Using the Jive SDK the data can be pushed to a Jive instance and a new discussion can even be generated around the current reading.

 

Equipment

Since this project has a real connection to the physical world there is some equipment needed.

I get all my stuff from Adafruit: Adafruit Industries, Unique & fun DIY electronics and kits  The links above will lead to the Adafruit store.   Of course there are other places they just are not as cool as Limor Fried and if she is listening I definitely want to work there one day :-)

 

Some of the items above are not required but will make the project easier.  Those are marked with an asterisk (*).  The wireless adapter is not required but if you don't want to have to keep this located on a physical wire it is a good addition.  The Pi Cobbler and breadboard are not needed but without them the temperature sensor will much more difficult to connect to the Raspberry Pi.  You can also do this entire project with only the Raspberry Pi but there will be only one measurement (cpu temperature) and it won't be as much fun.

 

Here is a picture of my Raspberry Pi all connected up.  Bender is also optional but helpful!

raspberrypi1-pi and temp sensor.jpg

I'm not going through all the setup of a Raspberry Pi.  There are plenty of tutorials at the main Raspberry Pi web site and Adafruit to get the Pi up and running and connected wirelessly.

 

Temperature Gathering

 

pigpio

In order to use a Python script to read GPIO pins there is a library needed.  The pigpio library creates an interface so that interacting with the GPIO pins is easy.  Download it from here: pigpio library.  Unzip it in the /home/pi folder.

I like to setup the pigpio process to run on startup so that I can use GPIO from scripts and programs without having to remember to start the process.  I use the rc.local file in order to make this happen.  Simply edit the /etc/rc.local file (sudo nano /etc/rc.local) and add the pigpio command (/home/pi/pigpio/pigpiod) to the end of the file:

My file ended up looking like this:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

/home/pi/pigpio/pigpiod

exit 0







 

Wiring the sensor

The AM2302 is the perfect temperature sensor for a project like this since it comes pre-wired and has a resistor already wired up.  It is truly a plug and play sensor but of course it is a little more expensive.  Wiring up the sensor is a breeze once the Pi Cobbler is connected to the breadboard.  Assuming the Pi Cobble is facing the end of the breadboard the row 1 on the breadboard is on the left (right side of the photo above) then the wires go into rows 4 (red), 5 (black), and 6 (yellow).  These rows on the breadboard match up to the GPIO pin 4, a ground, and GPIO pin 17 on the Raspberry Pi.

 

Getting measurements

With everything wired up the next step is to read the sensor and record the measurements.  Because hardware can be slow and having every connection from our Jive tile physically read the hardware would never scale this setup is recording the current reading to a file.  We will use the file to read the measurements from the Node.js process and send the data to a tile.  I am showing the cpu temperature script here just to keep things short but in the download there is a script for reading the temperature sensor as well.

 

There are two Python scripts included in the download.  One collects the CPU temperature and the other turns on the temperature sensor and then reads the data from the sensor before turning it back off.  They put their data into a file in the same directory.  That file is named "output.txt" and the cpu temperature goes in first without a line break followed by the sensor reading.  If you want to do this project without the temperature sensor then simply having the CPU temperature should work just fine.

cputemp.py

#!/usr/bin/python
import cgi;
import cgitb;
import time
cgitb.enable()
import commands
import sys
import string
mytemp1 = commands.getoutput('/opt/vc/bin/vcgencmd measure_temp | cut -d "=" -f2 | cut -d "\'" -f1')
output = str(float(mytemp1) * 9 / 5 + 32)
sys.stdout.write(output)






 

Here is an example of the cron file I have setup so that the temperature is read every hour.

# m h  dom mon dow   command

58 * * * * /home/pi/dev/projects/pitemp/cputemp.py > /home/pi/dev/projects/pitemp/output.txt

59 * * * * /home/pi/dev/projects/pitemp/DHT22.py >> /home/pi/dev/projects/pitemp/output.txt

You could read the temperature every few minutes but anything less than 5 minutes is probably too much and attempting to read the temperature sensor too frequently will probably lead to failures.

 

This is also a good time to point out that all the files are in /home/pi/dev/projects.  If you download the files then extract the compressed tar file into the pi users home folder then everything here will match up.

 

Node Setup on the Pi

Setting up Node on the Raspberry Pi has gotten pretty easy.

First make sure the Raspberry Pi is up to date, then download the ARM build of Node, create a symbolic link and it should be up and running.  The version might change this is just the one I happen to be running.

cd ~
sudo apt-get upgrade
sudo apt-get update
cd /opt
sudo wget http://nodejs.org/dist/v0.10.2/node-v0.10.28-linux-arm-pi.tar.gz
sudo tar -xvzf node-v0.10.28-linux-arm-pi.tar.gz
sudo ln -s node-v0.10.28-linux-arm-pi node






 

Next you will want to modify your login path to include /opt/node/bin. Test it out by logging out and then back in to the pi and try "node --version".

 

Install the jive-sdk with "npm install jive-sdk -g".   This can take a while on the Raspberry Pi.  Take a break and grab a drink.  Think about getting a Raspberry Pi 2 model with the faster processor.

 

Temperature Tile

If you downloaded the files then this project will already exist in "/home/pi/dev/projects/jive-pitemp-app".  You can use that app and run the examples if you modify the apps url and uuid in the jiveclientconfiguration.json file.  You can create your own tile since what follows here basic set of instructions on how I modified the example tile project.  It is not a complete step by step guide to creating a tile.  There are a ton of great resources for the JIve SDK and tiles so I am skipping a lot of detail here since this project is about wiring these things together.  Yuval, Aaron and Ryan have done a great job tweaking and documenting the API and since this project used the list tile example that would be the place to start Getting Started > Creating a List Tile with the Jive Node SDK for more background.

 

Create a directory for the tile and setup the jive-sdk:

mkdir -p /home/pi/dev/projects/jive-pitemp-app
cd /home/pi/dev/projects/jive-pitempt-app
jive-sdk create tile-list
npm update




That last command will give you time for another drink.

 

Now it is time to modify everything to make the Raspberry Pi temperature tile.  I will probably forget something but all the files are in the download.  I renamed this project to "raspberrypi-temperature".  I did this for a couple of reasons but the primary one is that if you are going to start learning the SDK it helps to rename the example.  Executing the example does not teach very much but when you have to rename everything you will be touching more points in the code and seeing what they do.

First change the name in the package.json file.  Then edit the jiveclientconfiguration.json file to point to your service url as well as exclude the port from the client.  Put in a name and description and a uuid.  Mine ended up like this:

{

    "clientUrl": "https://whoiskevin-rpi.ngrok.com",

    "port": "8090",

    "clientUrlExcludesPort": true,

    "development" : true,

    "extensionInfo" : {

        "uuid": "372d4980-1eca-438d-9ce9-3d50f1531975",

        "name" : "raspberrypi-temperature",

        "description" : "Simple list tile with the current temperature of Raspberry Pi hosting the node service along with the room temp and humidity."

    }

}

Notice that url.  If you haven't already take a look at Ryan's post on using ngrok.  That is how we are going to get this Raspberry Pi working with the outside world.

 

The next change goes in the template.json file located in the tiles folder:

{

    "default": {

        "name": "defaultTemplate",

        "displayName": "Contains: [raspberrypi-temperature] ",

        "description": "Extension UUID 372d4980-1eca-429d-9ce9-3d50f1531975 Contains: [raspberrypi-temperature] ",

        "tiles": [

            "raspberrypi-temperature"

        ]

    }

}

This is where the system knows what tiles are available.  In this case I made a few changed to the display name and description but the essential change is to the "tiles" so that instead of example-tile it now expects a folder named raspberrypi-temperature.  Renaming the example-tile folder to raspberrypi-temperature will allow you to modify the remainder of the files and create a working example.

Inside the raspberrypi-temperature folder modify the definition.json file:

{

    "sampleData" : {

        "title" : "WhoIsKevin Raspberry Pi Temperature",

        "contents" : [ {

            "text" : "Waiting for initial reading..."

        } ],

        "config" : {

               "listStyle" : "contentList"

        }

    },

    "displayName" : "RaspberryPi Temperature",

    "name" : "raspberrypi-temperature",

    "description" : "Display my RaspberryPi cpu temperature, room temperature and humidity.",

    "style" : "LIST",

    "icons" : {

        "16" : "https://dl.dropboxusercontent.com/u/2391260/WhoIsKevin_Logo.jpg",

        "48" : "https://dl.dropboxusercontent.com/u/2391260/WhoIsKevin_Logo.jpg",

        "128" : "https://dl.dropboxusercontent.com/u/2391260/WhoIsKevin_Logo.jpg"

    },

    "action": "/raspberrypi-temperature/action"

}

You might want to use a different icon of course.  I used some icons from the public folder of my dropbox account.  I of course cannot guarantee they will always be there.

 

Now we are finally to the file with the real changes.  In the raspberrypi-temperature folder is a sub-folder named backend that contains the code responsible for performing data pushes to tile instances.  This is where we need to get our temperature measurements and send them to the tile.  The function I modified is "processTileInstance".

function processTileInstance(instance) {
    jive.logger.debug('running pusher for ', instance.name, 'instance', instance.id);

    // creates a data update structure
    function getFormattedData(tempLine) {
        var allTemps = tempLine.split(' ');
        return {
            data: {
                "title": "Raspberry Pi Temperature Log",
                "contents": [
                    {
                        "text": "CPU Temperature : " + allTemps[0] + " F",
                        "icon": "https://dl.dropboxusercontent.com/u/2391260/raspberrypi-sd.png",
                        "linkDescription": "Current CPU temperature."
                    },
                    {
                        "text": "Room Temperature : " + allTemps[1] + " F",
                        "icon": "https://dl.dropboxusercontent.com/u/2391260/thermometer.png",
                        "linkDescription": "Room temperature from DHT22."
                    },
                    {
                        "text": "Humidity : " + allTemps[2] + " %",
                        "icon": "https://dl.dropboxusercontent.com/u/2391260/Humidity-Icon.png",
                        "linkDescription": "Humidity from DHT22."
                    }
                ],
                "config": {
                    "listStyle": "contentList"
                },
                "action": {
                    "text": "Share State",
                    "url": jive.service.options['clientUrl'] + '/raspberrypi-temperature/action.html',
                    "context": {
                        "cputemp": allTemps[0] + " F",
                        "roomtemp": allTemps[1] + " F",
                        "humidity": allTemps[2] + " %"
                    }
                }
            }
        };
    }

    fs.readFile('/home/pi/dev/projects/pitemp/output.txt', 'utf8', function (err,data) {
        if (err) {
            jive.logger.debug('Error reading temperature output, push failed', err);
        }
        else {
            jive.logger.debug(data);
            return jive.tiles.pushData(instance, getFormattedData(data));
        }
    });
}


 

What you will notice is that I've added a very simple piece of code to read the line of data from the output.txt file.  In the backend.js file I also added a require statement "var fs = require('fs');" which includes the node file system utilities.  The "fs.readFile" line reads this file and if there is no error sends that line of data to the "getFormattedData" function which splits the line to obtain the three separate measurements and then puts each one out as a data line for the tile.  Again I am using some icons from my dropbox but you can easily download those and put them in the public folder of the project or the tile inside the project.

Also notice that the measurements are included in the action "Share State" so that the data is available for the action call that can generate a new discussion from the current measurement.

 

That is about all of the changes that are required.  Take a look at the static files inside the tile.  There are a few paths there that need to be changed for the action to work.  Also note I left the configuration in place because removing it still seems to lock up the tile.  I may have missed something there to get it to work without the configuration since I thought that bug was fixed.  In any case currently there is a configuration popup.

 

Run It

In order to run the tile you have to go through the usual installation process.  For this to work from a Raspberry Pi you need ngrok and the extension.zip file created by the jive-sdk.  So follow these steps.

  • Download ngrok for Linux/ARM to the /home/pi folder.  You can use wget again:  "wget https://api.equinox.io/1/Applications/ap_pJSFC5wQYkAyI0FIVwKYs9h1hW/Updates/Asset/ngrok.zip?os=linux&arch=arm&channel=stable"  Unzip it  "unzip ngrok.zip"
  • Run ngrok the first time following the instructions.  After you verify that it is running kill it with ctrl-c and use the following to run it in the background.  "./ngrok -log=stdout -subdomain=somebody-rpi 8090 > /dev/null &"  Notice that I used a subdomain call.  You cannot use the one I have reserved so that is an adjustment you have to make so that somebody-rpi is unique and then put that into the clienturl inside the jiveclientconfiguration.json file.  "clientUrl":"https://somebody-rpi.ngrok.com"
  • From the root of the tile project run the node server: "node app.js"

 

Now login to the Jive developer sandbox and choose manage apps to upload the extension.  Once it is uploaded you can add the tile to a space or group and view the results.  Here are the screen shots I took of the install and the tile in action.

raspberrypi2-addon-screen.png

raspberrypi3-tile-selection.png

raspberrypi4-tile.png

raspberrypi5-tile-to-discussion.png

 

Conclusion

I have not had a lot of time to play with the node sdk due to other projects and the usual time crunch but this project allowed me to get into a few details around how the example list tile is setup.  If you take any of the examples and work on them in this way you will discover more about the sdk.   If you try this project then let everyone know in the comments.  Don't suffer in silence the developer community is pretty active with answers.

Every quarter, Jive releases its latest and most advanced cloud release, and with these releases comes a new bevy of integration features.  In the past, we have done Developer Webinar's but given the massive number of features we had to cover in this announcement, we felt it was better to bring them together in a blog post.  If you have any questions about any of the features, feel free to comment on the related documentation, or if you have a general question about this post, please use the comments below.

 

In the Winter 2015 Cloud Release, we have a nice set of new features available to developers:

  • Custom View Tiles - You can now build your own HTML view within a tile. Not only that, but you can have Jive host this tile so you don’t need to prop up a service if you don’t want to.
    • Alternatively, you can host a service and push custom content into your tile. In either case, you can provide tile actions just like other tile styles. This is a compelling new tile style for those customers who are longing for HTML widget-like functionality in a tile, or for those who simply want more control over their tile layout.
  • App actions filtered by Security Group -  In the previous cloud release (Fall 2014, 8c4), we gave you the ability to filter apps based on security groups. We now give you finer-grained control over your app’s visibility. In this release, you can filter app actions based on security groups.
  • Launcherless Apps - Now that we offer many different types of app actions, there may be scenarios where you don’t want your app to appear in the main Apps menu. You can now turn that off, without relying on security group filters.
  • Private Tile Properties - We now expose the ability for you to store data on a per-user basis for each tile instance. This can be useful when you want each user to have some unique information associated with a shared tile.
  • Tile Availability on Different Page Types - Now that there are more potential places to put tiles, we have added a new field to the tile definition so that you can define which types of Jive pages make sense for your tile.
  • REST API Updates - The REST API has been updated with new endpoints for new features, such as News, Pages, Entitlements.
  • Analytics API V2 - Same great platform, but with more events and filters to enrich your integration with analytics data.

 

Other recent updates:

  • We’ve made some tweaks to the Jive Node SDK
    • We have added four new custom view tile examples
    • We have cleaned up the ESF example
    • We have added cleaner SDK help output.
  • ESF Overview & Tutorial - We have created an overview and tutorial for those who want to get started with the external storage framework.

 

Developer highlights from the previous Fall 2015 Cloud Release:

  • Jive-Hosted Apps - We’re excited to promote this new feature that allows you to have Jive host your app’s static assets. You no longer need to prop up an integration service just to host an app.
  • Entitlements API - This document provides a tour of the new entitlements REST API.
  • Pages API - This document provides a tour of the new Pages REST API. It includes information about how to put tiles on your new pages.
  • Filtering App Visibility using Security Groups - With this feature, you can control an app’s visibility based on security groups.

 

Feel free to check out the past developer webinars, to learn more about recent feature additions to the Jive platform.

Filter Blog

By date: By tag: