Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
HTTP POST?
#1
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.
Reply
#2
The CML HTTPClient will do POSTs - http://www.charmedquark.com/Web2/ExtCont...Client.htm
Wuench
My Home Theater/Automation Website

[THREAD=5957]BlueGlass CQC Config[/THREAD]
[THREAD=10624]Wuench's CQC Drivers[/THREAD]
Reply
#3
Perfect - thanks for the pointer, and the fast response!  Smile
Reply
#4
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;
Wuench
My Home Theater/Automation Website

[THREAD=5957]BlueGlass CQC Config[/THREAD]
[THREAD=10624]Wuench's CQC Drivers[/THREAD]
Reply
#5
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?
Reply
#6
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
Reply
#7
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.
Reply
#8
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?
Reply
#9
That looks reasonable.
Dean Roddey
Explorans limites defectum
Reply
#10
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
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Curious About Usage Post Public Domain kblagron 18 2,518 11-01-2022, 08:01 AM
Last Post: karenlee
  Get Field Value via HTTP znelbok 3 1,388 06-11-2020, 03:43 PM
Last Post: Dean Roddey
  HTTP Trigger and Parameters znelbok 1 1,141 06-11-2020, 03:41 PM
Last Post: Dean Roddey
  HTTP SendPUT simplextech 3 1,657 01-21-2020, 03:05 PM
Last Post: simplextech
  CQC HTTP Events? bjkiller 26 9,271 01-11-2020, 07:27 AM
Last Post: simplextech
  Set value via HTTP Call simplextech 2 1,348 01-07-2020, 04:39 PM
Last Post: simplextech
  HTTP Trigger Driver - see trained URL's? Shaky 1 1,832 09-15-2019, 12:25 PM
Last Post: Dean Roddey
  HTTP Get driver not working znelbok 10 5,638 08-28-2018, 10:10 AM
Last Post: Dean Roddey
  Http Post zra 17 7,499 08-05-2018, 01:55 PM
Last Post: zra
  HTTP Post zra 7 3,701 05-18-2018, 08:47 AM
Last Post: zra

Forum Jump:


Users browsing this thread: 1 Guest(s)