Using the Flexs Q3 with InfluxDB and Grafana

banner_screenshot3

Using the Flexs Q3 with InfluxDB and Grafana offers you the perfect way to store and present all of your recorded data points.

(Video)

 

The Flexs Q3 supports UDP Streaming of it’s registers to a remote server.

Were going to create a simple listener application in ‘C’ that will listen for a received data, process it and load it into our influxdb database. **This guide assumes that your operating on the Linux Operating System and have a build environment set-up with the libcurl-dev and libcurl packages installed.

Start by creating a Database called ‘Sites’ from the influxdb administration portal

Create a local file on your computer titled ‘main.c’

Clip and paste the below code into you ‘main.c’ file

Update the ‘SERVER’ #define in the code to match your influxdb server url and login string

Compile the code with the command ‘gcc ./main.c -lcurl’

Run the compiled application with the command ‘./a.out’

This code creates a UDP Socket and listens on it, when a packet arrives it creates a json string with the results and using curl it querys the influxdb server to add the data.

you can checkout a live InfluxDB / Grafana demo at https://flexscada.com/hmi

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <curl/curl.h>

#define BUFSIZE sizeof(registers)

#define PORT 8000

#define SERVER “http://mydomain.ca:8086/db/sites/series?u=root&p=root”

#pragma pack(1)

typedef struct
{
unsigned char uid[16];
unsigned char node;
float data[128];
} REGISTERS;

#pragma push

char *json;

char hex[256][2] = {{‘0′,’0’},{‘0′,’1’},{‘0′,’2’},{‘0′,’3’},{‘0′,’4’},{‘0′,’5’},{‘0′,’6’},{‘0′,’7’},{‘0′,’8’},{‘0′,’9’},{‘0′,’a’},{‘0′,’b’},{‘0′,’c’},{‘0′,’d’},{‘0′,’e’},{‘0′,’f’},{‘1′,’0’},{‘1′,’1’},{‘1′,’2’},{‘1′,’3’},{‘1′,’4’},{‘1′,’5’},{‘1′,’6’},{‘1′,’7’},{‘1′,’8’},{‘1′,’9’},{‘1′,’a’},{‘1′,’b’},{‘1′,’c’},{‘1′,’d’},{‘1′,’e’},{‘1′,’f’},{‘2′,’0’},{‘2′,’1’},{‘2′,’2’},{‘2′,’3’},{‘2′,’4’},{‘2′,’5’},{‘2′,’6’},{‘2′,’7’},{‘2′,’8’},{‘2′,’9’},{‘2′,’a’},{‘2′,’b’},{‘2′,’c’},{‘2′,’d’},{‘2′,’e’},{‘2′,’f’},{‘3′,’0’},{‘3′,’1’},{‘3′,’2’},{‘3′,’3’},{‘3′,’4’},{‘3′,’5’},{‘3′,’6’},{‘3′,’7’},{‘3′,’8’},{‘3′,’9’},{‘3′,’a’},{‘3′,’b’},{‘3′,’c’},{‘3′,’d’},{‘3′,’e’},{‘3′,’f’},{‘4′,’0’},{‘4′,’1’},{‘4′,’2’},{‘4′,’3’},{‘4′,’4’},{‘4′,’5’},{‘4′,’6’},{‘4′,’7’},{‘4′,’8’},{‘4′,’9’},{‘4′,’a’},{‘4′,’b’},{‘4′,’c’},{‘4′,’d’},{‘4′,’e’},{‘4′,’f’},{‘5′,’0’},{‘5′,’1’},{‘5′,’2’},{‘5′,’3’},{‘5′,’4’},{‘5′,’5’},{‘5′,’6’},{‘5′,’7’},{‘5′,’8’},{‘5′,’9’},{‘5′,’a’},{‘5′,’b’},{‘5′,’c’},{‘5′,’d’},{‘5′,’e’},{‘5′,’f’},{‘6′,’0’},{‘6′,’1’},{‘6′,’2’},{‘6′,’3’},{‘6′,’4’},{‘6′,’5’},{‘6′,’6’},{‘6′,’7’},{‘6′,’8’},{‘6′,’9’},{‘6′,’a’},{‘6′,’b’},{‘6′,’c’},{‘6′,’d’},{‘6′,’e’},{‘6′,’f’},{‘7′,’0’},{‘7′,’1’},{‘7′,’2’},{‘7′,’3’},{‘7′,’4’},{‘7′,’5’},{‘7′,’6’},{‘7′,’7’},{‘7′,’8’},{‘7′,’9’},{‘7′,’a’},{‘7′,’b’},{‘7′,’c’},{‘7′,’d’},{‘7′,’e’},{‘7′,’f’},{‘8′,’0’},{‘8′,’1’},{‘8′,’2’},{‘8′,’3’},{‘8′,’4’},{‘8′,’5’},{‘8′,’6’},{‘8′,’7’},{‘8′,’8’},{‘8′,’9’},{‘8′,’a’},{‘8′,’b’},{‘8′,’c’},{‘8′,’d’},{‘8′,’e’},{‘8′,’f’},{‘9′,’0’},{‘9′,’1’},{‘9′,’2’},{‘9′,’3’},{‘9′,’4’},{‘9′,’5’},{‘9′,’6’},{‘9′,’7’},{‘9′,’8’},{‘9′,’9’},{‘9′,’a’},{‘9′,’b’},{‘9′,’c’},{‘9′,’d’},{‘9′,’e’},{‘9′,’f’},{‘a’,’0′},{‘a’,’1′},{‘a’,’2′},{‘a’,’3′},{‘a’,’4′},{‘a’,’5′},{‘a’,’6′},{‘a’,’7′},{‘a’,’8′},{‘a’,’9′},{‘a’,’a’},{‘a’,’b’},{‘a’,’c’},{‘a’,’d’},{‘a’,’e’},{‘a’,’f’},{‘b’,’0′},{‘b’,’1′},{‘b’,’2′},{‘b’,’3′},{‘b’,’4′},{‘b’,’5′},{‘b’,’6′},{‘b’,’7′},{‘b’,’8′},{‘b’,’9′},{‘b’,’a’},{‘b’,’b’},{‘b’,’c’},{‘b’,’d’},{‘b’,’e’},{‘b’,’f’},{‘c’,’0′},{‘c’,’1′},{‘c’,’2′},{‘c’,’3′},{‘c’,’4′},{‘c’,’5′},{‘c’,’6′},{‘c’,’7′},{‘c’,’8′},{‘c’,’9′},{‘c’,’a’},{‘c’,’b’},{‘c’,’c’},{‘c’,’d’},{‘c’,’e’},{‘c’,’f’},{‘d’,’0′},{‘d’,’1′},{‘d’,’2′},{‘d’,’3′},{‘d’,’4′},{‘d’,’5′},{‘d’,’6′},{‘d’,’7′},{‘d’,’8′},{‘d’,’9′},{‘d’,’a’},{‘d’,’b’},{‘d’,’c’},{‘d’,’d’},{‘d’,’e’},{‘d’,’f’},{‘e’,’0′},{‘e’,’1′},{‘e’,’2′},{‘e’,’3′},{‘e’,’4′},{‘e’,’5′},{‘e’,’6′},{‘e’,’7′},{‘e’,’8′},{‘e’,’9′},{‘e’,’a’},{‘e’,’b’},{‘e’,’c’},{‘e’,’d’},{‘e’,’e’},{‘e’,’f’},{‘f’,’0′},{‘f’,’1′},{‘f’,’2′},{‘f’,’3′},{‘f’,’4′},{‘f’,’5′},{‘f’,’6′},{‘f’,’7′},{‘f’,’8′},{‘f’,’9′},{‘f’,’a’},{‘f’,’b’},{‘f’,’c’},{‘f’,’d’},{‘f’,’e’},{‘f’,’f’}};

REGISTERS registers;

int main(void)
{

CURL *curl;
CURLcode res;

struct sockaddr_in myaddr; /* our address */
struct sockaddr_in remaddr; /* remote address */
socklen_t addrlen = sizeof(remaddr); /* length of addresses */
int recvlen; /* # bytes received */
int fd; /* our socket */
unsigned char buf[BUFSIZE]; /* receive buffer */

/* create a UDP socket */

if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror(“cannot create socket\n”);
return 0;
}

/* bind the socket to any valid IP address and a specific port */

memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
myaddr.sin_port = htons(PORT);

if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
perror(“bind failed”);
return 0;
}

json = malloc(10000); // Should be plenty

/* In windows, this will init the winsock stuff */
curl_global_init(CURL_GLOBAL_ALL);

/* get a curl handle */
curl = curl_easy_init();
if(curl) {

/* now loop, receiving data and loading what we recieved into emoncms */
for (;;) {
int d = recvfrom(fd, &registers, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);
printf(“Rcv: %d : %d\n”,d, sizeof(REGISTERS));
if(d == BUFSIZE){
int k = 1;
char buffer[128];
// strcat(json,””);
*json = ‘\0’;

// Convert the UID to a Hex String… 16 bytes -> 32 bytes
char uid[33];
int i;

for(i=0; i<16; i++) {
uid[i*2] = hex[registers.uid[i]][0];
uid[i*2+1] = hex[registers.uid[i]][1];
}
uid[32] = ‘\0’;

sprintf(buffer,”[{\”name\”:\”%s\”,\”points\”:[[“,uid);
strcat(json,buffer);

for( ;k < 128; k++){
char end = ‘,’;
if(k == 127){end = ‘ ‘;}
if(registers.data[k] == registers.data[k]){
sprintf(buffer,”%f%c”,registers.data[k],end);
strcat(json,buffer);
}
}

strcat(json,”]],\”columns\”:[“);

for(k=1 ;k < 128; k++){
char end = ‘,’;
if(k == 127){end = ‘ ‘;}
if(registers.data[k] == registers.data[k]){
sprintf(buffer,”\”%d\”%c”,k,end);
strcat(json,buffer);
}
}

// “R1”, “R2”, “R3″
strcat(json,”]}] “);

/* First set the URL that is about to receive our POST. This URL can
just as well be a https:// URL if that is what should receive the
data. */
curl_easy_setopt(curl, CURLOPT_URL, SERVER);
/* Now specify the POST data */
curl_easy_setopt(curl, CURLOTP_POSTFIELDSIZE,strlen(json));
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json);
// printf(json);

/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, “curl_easy_perform() failed: %s\n”,
curl_easy_strerror(res));

}
}

curl_easy_cleanup(curl);
}
curl_global_cleanup();

close(fd);
return 0;
}

You must be logged in to post a comment.
Select your currency