Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How do to graphing with Grafana
#1
I've been using a Graphing application called Grafana for about two years at work.  I just recently realized that I might be able to get that to work for CQC, and in very short order I got it working.  In my case, I installed Grafana (and InfluxDB which is the backing database) as Docker containers (using the instructions from this page).  You can just as easily install it standalone though (that's how we run it at work) or on a VM, if desired.

My CQC macro is still very much in raw form right now, and I'm about to be out for a long weekend, so I won't have time to clean it up for a while, but I'll post what I have now here anyway in case anyone wants to play over the weekend. ;-)

Code:
Class=[NonFinal]
   ClassPath MEng.User.GrafanaTest;
   ParentClass MEng.Object;
EndClass;

Imports=
   MEng.System.Runtime.HTTPClient;
   MEng.System.Runtime.URL;
   MEng.System.Runtime.DataSrc;
   MEng.System.CQC.Runtime.SimpleFldClient;
EndImports;

Members=
EndMembers;


Methods=[Public,Final]

   Constructor()
   Begin
   EndConstructor;

   Method Start() Returns Int4
   Begin

       Locals=
           String      strContType;
           String      strRepText;
           String      strTemp;
           LinesList   lstHeader;
           LinesList   lstNull;
           Card4       bodyLen(0);
           Card4       c4RetVal;
           Card4       c4BufSize;
           URL         urlLoc;
           MemBuf      bufBody;
           HTTPClient  http;
           String      strBody;
           String      temp;
           SimpleFldClient     field;
       EndLocals;

       urlLoc.Set("http://192.168.59.177:8086/write?db=cqc", FQTypes.DontCare);

       strContType := "*/*";

       strBody := "Temperature,thermostat=Main value=" + field.ReadField2("OmniProII.THERM#Main~CurrentTemp");
       strBody += "\nTemperature,thermostat=Office value=" + field.ReadField2("OmniProII.THERM#Office~CurrentTemp");
       strBody += "\nTemperature,thermostat=MasterBedroom value=" + field.ReadField2("OmniProII.THERM#Master_Bed~CurrentTemp");
       strBody += "\nTemperature,thermostat=Computer value=" + field.ReadField2("OmniProII.THERM#Computer~CurrentTemp");
       strBody += "\nTemperature,thermostat=Outdoor value=" + field.ReadField2("OmniProII.Outdoor_temp_CurVal");
       strBody += "\nTemperature,thermostat=Theater value=" + field.ReadField2("OmniProII.THERM#Theater~CurrentTemp");
       strBody += "\nWeather,Field=WindSpeed value=" + field.ReadField2("Weather.CurWindSpeed");

       bodyLen := strBody.GetLength();
       bufBody.ImportString(strBody, bodyLen);

       http.SendPOST2(urlLoc, 5, "CQC", "*/*", strRepText, lstHeader, strContType, bufBody, bodyLen, True, lstNull);

       Return 0;
   EndMethod;

EndMethods;

Right now I'm just graphing temperatures from my various thermostats, but I suspect there are a number of things I will find this useful for over time.  I'll continue to update this thread as a work-in-progress , but also feel free to post any questions you may have.
Reply
#2
Just some things to look at later...

Ultimately it would probably be best to have a local private method to get the value of each field. That way, if one of them is in error, you can catch the exception and return some null value to be written in that round, or not right it that round if that's appropriate. And also catch any failure of the POST and log something instead of letting it propagate out.
Dean Roddey
Software Geek Extraordinaire
Reply
#3
Indeed, there is much work yet to do, but your feedback and suggestions are quite welcome!  Smile

I am about to head out now, so I don't have more time for testing, but I had an odd issue this morning.  I changed the macro from using an IP address, to using a URL (influxdb.local).  After doing that, I was getting very regular errors stating that the request timed-out.  I changed it back to the (new static) IP address, and it worked fine again.  I don't see the connection, and it may have been a fluke, but I figured I would mention it.
Reply
#4
You still included the :xxx port bit, right? Also, do a ping from another machine and see what IP that address is resolving to. Do it a few times to make sure it's consistent. Unless you have a local Windows domain, typically the machine addresses don't have any suffix on them, and that would tend to make name resolution go looking off network to resolve the address.
Dean Roddey
Software Geek Extraordinaire
Reply
#5
I'm still working on figuring out what all I want to graph, but here is a screenshot of what I set up so far.  Grafana has a kiosk mode (which can easily be enabled via the URL).  When enabled, it removes most of the Grafana UI, leaving just the graphs.  This is perfect for consumption in CQC.  I've also learned that the Grafana UI is very responsive, and handles differing resolutions quite well.


Attached Files
.png   GrafanaDashboard.png (Size: 121.9 KB / Downloads: 18)
Reply
#6
(04-14-2017, 09:24 AM)Dean Roddey Wrote: You still included the :xxx port bit, right? Also, do a ping from another machine and see what IP that address is resolving to. Do it a few times to make sure it's consistent. Unless you have a local Windows domain, typically the machine addresses don't have any suffix on them, and that would tend to make name resolution go looking off network to resolve the address.

I discovered that this is still happening, even when using the IP address.  I do the posts once a minute, and most (but not all) of the time, I am getting "HTTP client request failed.  Timed out waiting for message" errors in the log, but the data does still get posted to InfluxDB.

The VM that is hosting InfluxDB and Grafana is very lightly loaded, and I'm on a wired gigabit network, so the timeouts don't make sense to me.  Any suggestions?
Reply
#7
Can you post an example of the error message, with all of the surrounding info, i.e. not just the message text.
Dean Roddey
Software Geek Extraordinaire
Reply
#8
Here you go:

Code:
04/22 14:11:01-CQC-MASTER, CQCEventSrv, CQCEventWorkerThread1
{
   CQCEventSrv, CQCEventSrv_ThisFacility.cpp.2080, Info/App Status
   Started processing scheduled event
   Default Title
}
04/22 14:11:01-CQC-MASTER, CQCEventSrv, CQCEventWorkerThread1
{
   CQCKit, CQCMEng_MEngErrHandler.cpp.88, Status/App Status
   A macro language exception occured during macro execution
}
04/22 14:11:01-CQC-MASTER, CQCEventSrv, CQCEventWorkerThread1
{
   CQCKit, MEng.System.Runtime.HTTPClient.58, Status/Data Format
   HTTPClientErrors.PostError
   HTTP client request failed. Timed out waiting for message
}
04/22 14:11:01-CQC-MASTER, CQCEventSrv, CQCEventWorkerThread1
{
   CIDMacroEng, CIDMacroEng_Engine.cpp.1808, Status/App Status
   Exception 'HTTPClientErrors.PostError' was thrown from line 58
   MEng.System.Runtime.HTTPClient
}
04/22 14:11:01-CQC-MASTER, CQCEventSrv, CQCEventWorkerThread1
{
   CQCAct, CQCAct_StdCmdTargets.cpp.2041, Status/Cannot Do, Error: 757/0/0
   Macro MEng.User.GrafanaTest failed with an exception. See the logs
}
04/22 14:11:01-CQC-MASTER, CQCEventSrv, CQCEventWorkerThread1
{
   CQCEventSrv, CQCEventSrv_ThisFacility.cpp.2142, Status/App Status
   Scheduled/Triggered event failed
   Default Title
}
Reply
#9
Are you sure it's always actually returning something? Maybe it doesn't always send back a reply. Or is this still only happening when you use the domain name instead of the IP address?
Dean Roddey
Software Geek Extraordinaire
Reply
#10
Is grafan all self contained? I spun up a docker and it's asking me to create a user, I assume that's a local thing.
|Z-Wave|Sonos|Tivo|Hue|Plex|Roku|MyMovies|Echo|
Nest|Harmony|Neeo|LG TV|Smarthings|
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)