Posts: 475
Threads: 68
Joined: May 2015
04-12-2017, 02:05 PM
(This post was last modified: 04-12-2017, 02:05 PM by dlmorgan999.)
I use Grafana and InfluxDB at work, and it's fairly quick and easy to set up for graphing time-series data (especially if you have a Docker host, which I do).  I decided it might be interesting to try integrating it with CQC.  There are a few ways to get data in, and one of the more straightforward methods is by doing an HTTP POST.  Here is an example of how you would do it using curl:
Code: curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'
You can also log multiple points with one call, which is much more efficient:
Code: curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load_short,host=server02 value=0.67
cpu_load_short,host=server02,region=us-west value=0.55 1422568543702900257
cpu_load_short,direction=in,host=server01,region=us-west value=2.0 1422568543702900257'
I did a bit of searching in the forum but didn't immediately find anything.  Is there a way to do something like this in CQC?  If so, it would be fun to write a CML macro that runs periodically and logs various CQC device properties for graphing.
Posts: 3,415
Threads: 158
Joined: Jan 2006
04-12-2017, 02:07 PM
(This post was last modified: 04-12-2017, 02:08 PM by wuench.)
Posts: 475
Threads: 68
Joined: May 2015
Perfect - thanks for the pointer, and the fast response! 
Posts: 3,415
Threads: 158
Joined: Jan 2006
Here's an example:
Code: Method LoadURL([In] IPEndPoint ip, [In] String strURL, [In] String strData, [In] Card4 c4Timeout,
   [In] Boolean bParse, [In] Boolean bPost) Returns Boolean
   Begin
       Locals=
           String      strContType;
           String      strRepText;
           String      strTemp;
           String      strAccept("*/*");
           LinesList   lstHeader;
           LinesList   lstNull;
           Card4       c4Count(0);
           Card4       c4RetCount;
           Card4       c4RetVal;
           Card4       c4BufSize;
           URL         urlLoc;
           MemBuf      bufTemp;
           HTTPClient  http;
           Boolean     bData(False);
           DataSrc     dataTemp;
       EndLocals;
   Try
       // Determine if there is content
       If (strData != "")
           bData := True;
           c4Count := strData.GetLength();
           bufTemp.ImportString(strData, c4Count);
       EndIf;
       c4BufSize := bufTemp.GetMaxSize();
       strAccept := "text";
       strRepText := "blah";  
       // Setup DataSrc
       dataTemp.TCPSetup(ip, False);    
       // Set the URL
       urlLoc.Set(strURL, FQTypes.DontCare);
       LogIt(LogMsgs.URL, "LoadURL", strURL, c4Timeout, bPost);
       If (bPost)
           // Send the HTTP POST
           http.SendPOST2(urlLoc, c4Timeout, "CQC", "*/*", strRepText,
                             lstHeader, strAccept, bufTemp, c4Count, bData, lstNull);
       Else
           c4RetVal := http.SendRUGET(urlLoc, c4Timeout, "CQC", "*/*", strRepText,
                   lstHeader, strAccept, bufTemp, c4Count, False, lstNull, dataTemp);
           dataTemp.Close();
       EndIf;
       If (!bParse)
           // Skip parsing response
           Return True;
       EndIf;
       If (c4Count > 0)
           LogIt(LogMsgs.URLResp1, "LoadURL", strURL, c4Count, "");
           bufTemp.ExportString(strTemp, c4Count);
           m_strConfig.Append(strTemp);
       EndIf;
       
       LogIt(LogMsgs.URLResp2, "LoadURL", m_strConfig,"","");
       
       If (ParseJSON())
          Return True;
       Else
          LogIt(LogMsgs.URLParseErr, "LoadURL", "","","");
          Return False;
       EndIf;
   EndTry;
   Catch
       LogIt(LogMsgs.Exception, "LoadURL-Exception", $Exception.GetErrorText(), "", "");
       Return False;
   EndCatch;
EndMethod;
Posts: 475
Threads: 68
Joined: May 2015
I've done basically no web development, so I apologize if this is a newbie question, but I could use a bit of help on exactly how to construct the SendPOST2 call.  I have a test macro written, and I think I have most everything set correctly, but I'm not seeing anything get written to the database.
Here is an example of an actual command I sent using curl (which successfully wrote to the database):
Code: curl -i -XPOST 'http://192.168.59.177:8086/write?db=cqc' --data-binary 'temperature,thermostat=outdoor value=50'
For the SendPOST2 call, I set the URL parameter to "http://192.168.59.177:8086/write?db=cqc" and the memory buffer to "temperature,thermostat=theater value=63".  Is this correct?
Posts: 40,483
Threads: 491
Joined: Aug 2002
You'd have to create a URL object and set it to that URL. For the memory buffer, yeh, as in the example above, just import it into the memory buffer to convert to bytes. That will tell you the number of bytes it put into the buffer, which is the number of bytes to indicate as the outgoing body size.
The --data-binary may translate into some MIME type that you will need to send as the outgoing data type.
Dean Roddey
Explorans limites defectum
Posts: 475
Threads: 68
Joined: May 2015
This is what I have so far:
Code:    Method Start() Returns Int4
   Begin
       Locals=
           String      strContType;
           String      strRepText;
           String      strTemp;
           String      strAccept("*/*");
           LinesList   lstHeader;
           LinesList   lstNull;
           Card4       c4Count(0);
           Card4       c4RetCount;
           Card4       c4RetVal;
           Card4       c4BufSize;
           URL         urlLoc;
           MemBuf      bufTemp;
           HTTPClient  http;
           Boolean     bData(False);
           DataSrc     dataTemp;
           String      strData;
       EndLocals;
       urlLoc.Set("http://192.168.59.177:8086/write?db=cqc", FQTypes.DontCare);
       strData := "temperature,thermostat=theater value=63";
       c4Count := strData.GetLength();
       bufTemp.ImportString(strData, c4Count);
       http.SendPOST2(urlLoc, 5, "CQC", "*/*", strRepText, lstHeader, strAccept, bufTemp, c4Count, bData, lstNull);
       Return 0;
   EndMethod;
I wondered about the binary bit.  I'll have to do some more research, as I don't know what that does for curl.
Posts: 475
Threads: 68
Joined: May 2015
From the curl man page:
--data-binary <data>
(HTTP) This posts data exactly as specified with no extra processing whatsoever.
Based on that, it seems like I shouldn't need to do anything special with SendPOST2, should I?
Posts: 40,483
Threads: 491
Joined: Aug 2002
That looks reasonable.
Dean Roddey
Explorans limites defectum
Posts: 40,483
Threads: 491
Joined: Aug 2002
If it's literally sending binary data, then you should probably set the outgoing MIME type to "application/octet-stream".
Dean Roddey
Explorans limites defectum
|