There is much hype about the
"Internet of Things" and the Raspberry Pi is increasingly used as an IoT controller. To describe it simply - if you have a web site accessible from anywhere that displays data from a device and/or allows control of that device - then you are part of the Internet of Things.
I have a smart thermostat that allows me to control my heating and cooling system remotely from a smart phone app. This is one of the most commonly used IoT devices. I also have created web interfaces to some of the Raspberry Pi controlled devices in my home - alarm system, lights, sprinklers, hot tub, weather station, security cameras.
I programmed these web interfaces myself, but there are much easier ways that are actually more secure, and these use the services that support the Internet of Things. One of the easiest to use is
ThingSpeak.com. Here are the steps to use this service.
Go to the ThingSpeak web site and click on "Get Started." Click on "Sign Up" to create an account and then log in. Now you can create a new "Channel" which includes 1 to 8 fields of data. Once created, the channel is assigned an API_Key which is required to update the channel. You can see this value by clicking on the "API Keys" tab.
I have created a channel named "Example" with a single data field. Data can be uploaded to this field by using the following URL:
https://api.thingspeak.com/update?api_key=JPISWIDBF2CERG24&field1=123
(Yes, that is the actual API key. Feel free to post your own values, but try to keep them between 1-1000 so the chart is usable.)
You can view the public view here:
https://thingspeak.com/channels/67033Note that you can only update once per minute using this method.
Examples in a couple dozen languages, including C and Python are available here:
https://thingspeak.com/docs/examplesHere is an example of real data - temperature and fermentation rate from my home-brewing system.
I decided to create my own API since I had all the necessary code already. This API requires the CURL library to handle the web access. To install this:
sudo apt-get updatesudo apt-get install libcurl4-openssl-devHere is the API that I created for updating two fields.
/***********************************************************************
Filename: thingspeak.c
send data to ThingSpeak IoT server
Uses libcurl to send the data via HTTP
13-Nov-2015 Ted Hale created
************************************************************************/
/* system includes */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <string.h>
#include <curl/curl.h>
// Note: this function can be replaced with printf if you like.
void Log(char *format, ... );
#define TRUE 1
// the URL structure to update ThingSpeak
// https://api.thingspeak.com/update?api_key=YOUR_CHANNEL_API_KEY&field1=7
char *URLtemplate = "https://api.thingspeak.com/update?api_key=%s&%s=%s&%s=%s";
// structure used by the libcurl write callback function
struct url_data {
size_t size;
char* data;
};
//=====================================================================
// write callback function needed by libCurl
size_t write_data(void *ptr, size_t size, size_t nmemb, struct url_data *data) {
size_t index = data->size;
size_t n = (size * nmemb);
char* tmp;
data->size += (size * nmemb);
tmp = realloc(data->data, data->size + 1); /* +1 for '\0' */
if(tmp) {
data->data = tmp;
} else {
if(data->data) {
free(data->data);
}
Log("wuthread> write_data Failed to allocate memory.\n");
return 0;
}
memcpy((data->data + index), ptr, n);
data->data[data->size] = '\0';
return size * nmemb;
}
//=====================================================================
// upload data to ThingSpeak
int UpdateThingSpeak(char *api_key, char *f1, char *v1, char *f2, char *v2)
{
int error = 1;
time_t now;
struct tm *dt;
char url[256];
CURL *curl;
CURLcode res;
struct url_data response;
time(&now);
dt = gmtime(&now);
// build the URL string
snprintf(url, sizeof(url)-1, URLtemplate, api_key, f1, v1, f2, v2);
// guarantee null termination of string
url[sizeof(url)-1] = 0;
Log("UpdateThingSpeak> send: [%s]",url);
curl = curl_easy_init();
if (curl) {
response.size = 0;
response.data = malloc(4096); /* reasonable size initial buffer */
response.data[0] = '\0';
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
res = curl_easy_perform(curl);
if(res != CURLE_OK)
{
Log("UpdateThingSpeak> curl_easy_perform() failed: %s\n",curl_easy_strerror(res));
Log("URL is: [%s]",url);
error = 1;
} else {
// ThingSpeak returns "0" for error, else returns sample number
error = (strcmp(response.data,"0") == 0);
}
curl_easy_cleanup(curl);
free (response.data);
} else {
Log("UpdateThingSpeak> curl_easy_init failed\n");
error = 1;
}
return error;
}