Skip to content

Instantly share code, notes, and snippets.

@dirkjanfaber
Last active September 26, 2016 18:50
Show Gist options
  • Select an option

  • Save dirkjanfaber/8eff7c6585c3d4cdf732512ddf94ca68 to your computer and use it in GitHub Desktop.

Select an option

Save dirkjanfaber/8eff7c6585c3d4cdf732512ddf94ca68 to your computer and use it in GitHub Desktop.
Blink(1) on value increase of thingspeak channel
/*
Program that keeps an eye on a (private) thingspeak channel + field and
acts upon change in value of that field. When the value increases,
a system call to blink1-tool is called to colour the blink(1) led
pumpkin orange.
There are some commandline options:
-v for VERBOSE
-a for the apikey
-c for the thingspeak channel
-f for the field to check
-s for setting the time between checks
Compiling:
gcc -lcurl -O2 -Wall -o blink1speak blink1speak.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <curl/curl.h>
#ifndef VERBOSE
#define VERBOSE 0
#endif
struct MemoryStruct {
char *memory;
size_t size;
};
float lastvalue = -1.0;
int verbose = VERBOSE;
static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
if(mem->memory == NULL) {
/* out of memory! */
printf("not enough memory (realloc returned NULL)\n");
return 0;
}
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
float tempvalue = atof(contents);
if ( lastvalue < 0 ) {
(verbose) && printf("First run, lastvalue is undefined\n");
lastvalue = tempvalue;
}
(verbose) && printf("Lastvalue is %0.2f\n", lastvalue);
if ( lastvalue < tempvalue) {
(verbose) && printf("Value increased, blink(1)\n");
// set the blink(1) colour to pumpkin orange
char command[50];
strcpy(command, "blink1-tool --rgb '#FF9900'" );
system(command);
}
return realsize;
}
int main(int argc, char **argv)
{
char *channel = "104274";
char url[256];
char *apikey;
int field = 1;
int sleeptime = 300;
int index;
int c;
opterr = 0;
while ((c = getopt (argc, argv, "a:c:f:vs:")) != -1)
switch (c)
{
case 'a':
apikey = optarg;
break;
case 'c':
channel = optarg;
break;
case 'f':
field = atoi(optarg);
break;
case 's':
sleeptime = atoi(optarg);
break;
case 'v':
verbose = 1;
break;
case '?':
if (optopt == 'c')
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
else if (isprint (optopt))
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf (stderr,
"Unknown option character `\\x%x'.\n",
optopt);
return 1;
default:
abort ();
}
(verbose) && printf ("channel = %s, field = %d\n",
channel, field);
for (index = optind; index < argc; index++)
printf ("Non-option argument %s\n", argv[index]);
if ( apikey ) {
sprintf(url, "https://api.thingspeak.com/channels/%s/fields/field%d/last?api_key=%s", channel, field, apikey);
} else {
sprintf(url, "https://api.thingspeak.com/channels/%s/fields/field%d/last", channel, field);
}
(verbose) && printf("Checking url: %s\n", url);
while(1) {
CURL *curl_handle;
CURLcode res;
struct MemoryStruct chunk;
chunk.memory = malloc(1); /* will be grown as needed by the realloc above */
chunk.size = 0; /* no data at this point */
curl_global_init(CURL_GLOBAL_ALL);
/* init the curl session */
curl_handle = curl_easy_init();
/* specify URL to get */
curl_easy_setopt(curl_handle, CURLOPT_URL, url);
/* send all data to this function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
/* we pass our 'chunk' struct to the callback function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
/* some servers don't like requests that are made without a user-agent
field, so we provide one */
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
/* get it! */
res = curl_easy_perform(curl_handle);
/* check for errors */
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
else {
(verbose) && printf("Current value is %s\n", chunk.memory);
}
/* cleanup curl stuff */
curl_easy_cleanup(curl_handle);
free(chunk.memory);
/* we're done with libcurl, so clean it up */
curl_global_cleanup();
(verbose) && printf("Sleeping %d seconds\n", sleeptime);
sleep(sleeptime);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment