conkw documentation - Built-in UI reference

Specific elements

The body tag

The body tag contains global flags for the entire page. It can take a few attributes:

Specialized tags

Some HTML tags can be used through their id. ConkW will then override their content (through innerText or innerHTML) every time it runs. Here is their list:

Date special elements and clock.

To display the date, ConkW look into cw-date elements. Their ID will determine what to display in them, quite explicitely:

The analog clock is displayed inside a tag that reads cw-clock. All is needed is something like:

<cw-clock style="width:240px;height:240px;overflow: hidden;padding-top:3px;margin:auto" onclick="ConkW.dates.rotateClockFace(event, this)"></cw-clock>

Where the style is your own choice and the onclick is here to rotate the clockface when the user clicks on it. From there, ConkW will handle everything to have your clock displayed.

Generic UI - Displaying the grabbed metrics

Namespace

Any html element can be used to display data with conkw. For an element to be used by ConkW, it must have a cw-ns attribute, which stands for ConkW namespace. It is the name of a grabber instance, that must be declared in the cw-grabbers part of the body tag.

For example:

<a href="" cw-ns="spotify">Some text</a>

This instruct ConkW to look for other cw- attributes in the tag, and execute them in the context of the spotify data returned by the API.

Those attributes will assign behaviors to the html element. They are heavily based on the ConkW expressions. Let's have a look at them.

Expressions

Expressions is the way the page author will tell ConkW which value should be used. Values can be used as content, title, color, sioze, etc. Basically any HTML attribute can be used.

Let's take a simple example:

m:num:time:uptime

The basics

All basic expressions are built on four values, separated by colons :.

The metrics expressions

Those are expressions starting with m:.

Let's take the example of the net.pieroxy.conkw.webapp.grabbers.procgrabber.ProcGrabber grabber, configured with an instance called proc. First, let's have a look at the data extracted by this grabber:

{
  "timestamp": 1624092027928,
  "extracted": [
    "hostname",
    "battery",
    "mdstat"
  ],
  "extractor": "ProcGrabber",
  "name": "proc",
  "num": {
    "bat_exists": 0,
    "loadavg3": 1.8,
    "max$write_bytes_sdc": 162325547.09418836,
    "loadavg2": 1.56,
    "max$write_bytes_sdd": 25477120,
    "loadavg1": 2.47,
    "swapTotal": 68719472640
    ...
  },
  "timestamps": {},
  "elapsedToGrab": 23,
  "str": {
    "allbd": "sda,sdb,sdc,sdd,nvme0n1",
    "hostname": "pieroxy-dev",
    ...
  }
}

The interesting thing here is the num and str nodes. Depending on the data type of the expression, one or the other will be used.

The extended expressions

Those are expressions starting with e:. We will use the same data as the section above, with the proc sample data.

The value of these expressions is basically an ES6 template literal expression. The accessible model is the entire model of the grabber extraction as shown above.

Examples with the model above:

As you can see, this unlocks logic that you can apply to the metrics collected by ConkW for the purpose of the UI. All standard JS libraries are available here (such as Math for example), but the totality of the global scope is accessible, so any function or object you might add in the window object will be available here. The world is your oyster.

For example, if somewhere in my code I define window.myValue = 35, then I can use myValue as a global variable and the expression e:num::${myValue} will be evaluated as 35.

As an illustration, here is one expression I use to compute the "amount of rain" that will happen:

e:str::${Math.min(100, 10*num.daily_pop_1 * Math.max(num.daily_rain_1, num.daily_snow_1))}%

Value

Identified by the attribute cw-value. It will replace the content of the node through the innerHTML or innerText property, meaning:

Note that if the value resolves as undefined, (for a metric expression, if the metric is actually not there,) the element will be added the css class cw-stale. The text will be rendered as dark gray to indicate the value is not present. The last value will be kept to show what it was before it vanished.

Let's look at an example:

<div cw-ns="spotify" cw-value="m:str::album_artist"></div>

This empty DIV will be filled with the album_artist value of the strings extracted by the spotify grabber. After interpolation from the UI, it will look like:

<div cw-ns="spotify" cw-value="m:str::album_artist">AC/DC</div>

Value Warning

Any html tag with the cw-value attribute can have a cw-value-warn attribute.

Its directive will be a condition upon which the html tag will be added the class cw-error, which renders in a red background in the default CSS. This is used to alert whoever is watching the dashboard of an abnormal condition.

Here are the exhaustive list of directives one can use in a cw-value-warn expression:

Let's look at some examples in the default UIs provided:

<cw-label cw-value-warn="l:num:valuebelow:20" cw-ns="proc" cw-value="m:num:prc:bat_prc"></cw-label>

This html tag will display the percentage of battery remaining in your laptop. It will be displayed on a red background if below 20%.

Note that the expression for the cw-value-warn is a literal, and uses the directive valuebelow.

<cw-label cw-ns="proc" cw-value-warn="l:str:valuecontains:&lt;" cw-value="m:str::mdstatSummary"></cw-label>

This html tag will display the summary string of the mdadm arrays in the system. It will be displayed on a red background if it contains the character <. Per the documentation, this happens when the mdadm array is being reconstructed. As the performance of the array is greatly reduced during that time, it's best the user is aware of it.

Standalone Warning

Identified by the attribute cw-warn. Any html tag with the cw-warn must have a cw-warn-value attribute.

It will act like the couple cw-value and cw-value-warn seen above.

Let's look at some examples in the default UIs provided:

<div cw-ns="proc" cw-style-display="e:str::${num.mdstatNbDevices==0?'none':''}" cw-warn="l:num:isnot:0" cw-warn-value="m:num::mdstatFailed">
  blah blah blah some UI elements here
</div>

First of all, this div will only be displayed if the number of mdstat devices is not zero.

Then, it will have the CSS class cw-error if the metric num.mdstatFailed is not zero, presumably there are drives failures in the mdstat array.

Properties based elements

Identified by the attribute cw-prop-anything. It will replace the html property anything with the value of the expression.

Note cw-prop-innerHTML is similar to cw-value seen above.

Apart from innerHTML, any html property can be set by ConkW. The two most useful that come to mind are title to define a tooltip, and src for images tags to define which image to go fetch. But any property is available. For style property, see the section right below.

Here is an example in the default UI for OpenWeatherMap:

<IMG cw-ns="owm" cw-prop-src="m:str::hourly_icon_1" cw-prop-title="m:str::hourly_desc_1"/>

ConkW will set both the title and src property with whatever the owm grabber returns.

Style based elements

Identified by the attribute cw-style-anything. It will replace the style property anything with the value of the expression.

Most used style properties are:

Example with the ProcGrabber default UI:

<div cw-ns="proc" cw-style-display="e:str::${num.bat_exists==1?'none':''}">
  No battery detected
</div>
<div cw-ns="proc" cw-style-display="e:str::${num.bat_exists!=1?'none':''}">
  Some stuff here irrelevant to the example.
</div>

So, depending on the value of num.bat_exists in the ProcGrabber output, two different things will be displayed. Note that this could have been handled by a cw-value with a ternary expression. Except that the content of the second div is a bunch of HTML hard to stuff in a cw-value expression.

Stale properties

Identified by the attribute cw-stale. Will add the cw-stale css class to the element when the referenced metric is older than the specified delay. Only works with metrics expressions.

Let's have a look at the example from the BingNewsGrabber default UI:

<div cw-stale="m:str:olderThan.1h:news_name_0" cw-ns="bingnews">

This instructs conkw to add the cw-stale css class when the metric str.news_name_0 is older than one hour. As the default refresh rate for this grabber is once every hour, the user will be informed if the grabber failed to grab the latest news.

See the concepts page for the duration format.

Gauges

Identified by the attribute cw-gauge0. It allows to have a simple gauge such as the examples below:

Attributes:

Let's have a look at some examples from ProcGrabber default UI:

<heading>CPU /proc</heading>
<label>      used: </label>
<cw-label cw-value-warn="l:num:valueabove:80" cw-ns="proc" cw-value="m:num:cpu:cpu_usg_used"></cw-label>
<gauge cw-ns="proc" cw-min="l:num::0" cw-max="l:num::100" cw-gauge0="#5b5:m:num::cpu_usg_sys" cw-gauge1="#474:m:num::cpu_usg_user" cw-gauge2="#252:m:num::cpu_usg_nice" cw-gauge3="#252:m:num::cpu_usg_wait"></gauge>

The gauge goes from 0 to 100, that's easy. It overlaps the sys, user, nice and wait time with four different colors. As I don't want to discard the different colors even when above 80%, I decided to make the label turn red.

<cw-label cw-value-warn="m:num:valueabove:nbcpu_threads" cw-ns="proc" cw-value="m:num::loadavg1"></cw-label>
<gauge cw-ns="proc" cw-gauge0="default:m:num::loadavg1" cw-min="l:num::0" cw-max="e:num::${num.nbcpu_threads*2}" cw-value-warn="m:num::nbcpu_threads"></gauge>

Both the label and the gauge have a maximum set. As I have 8 cores hyperthreaded on my computer, the limit is set at 16 for the warning.

Note as the red value limit shows in the background of the gauges that did not reach it yet.

<label cw-ns="httpscert" cw-prop-title="m:num:time_ms:ts_pieroxy.net" style="width:160px; text-align: right; overflow: hidden; text-overflow: ellipsis;">pieroxy.net: </label><gauge cw-prop-title="m:num:tstodatetime:date_pieroxy.net" cw-ns="httpscert" cw-min="l:num::0" cw-max="l:num::90" cw-value-warn="l:num:valuebelow:20" cw-gauge0="default:m:num::days_pieroxy.net"></gauge><br>

Here the limit for the warning is expressed by a tiny black vertical bar in the green gauge element, since it is a minimum and not a maximum. Below that value the gauge element will be red.

Gauges with history

Identified by the attribute cw-hgauge0. It allows to have gauges with history such as the examples below:

Attributes:

Note that hgauges can display a red vertical bar, as you can see below:

This means the gathering of data stopped for a while and started again, so there is a time gap from the left side of the bar to the right side of the bar greater than 5 seconds.

Also note that the heartbeat of conkw is once every second. This means there will be a new datapoint every second. So a 60px wide hgauge will display 1 minute of data, and a 120px gauge two minutes.

Let's have a look as some examples.

<hgauge cw-bgcolor="#202040" style="height:4em;" cw-ns="proc"
        cw-hgauge0="#5b5:m:num::cpu_usg_sys" 
        cw-hgauge1="#474:m:num::cpu_usg_user" 
        cw-hgauge2="#252:m:num::cpu_usg_nice" 
        cw-hgauge3="#252:m:num::cpu_usg_wait"
        cw-min="l:num::0" cw-max="l:num::100"></hgauge>

There are four values being displayed, as you can see with the four cw-hgauge<n> elements. It goes from 0 to 100 and the cw-bgcolor is set to the default value, so it could be removed.

<hgauge cw-bgcolor="#202040" cw-ns="proc" style="height:2em" cw-log="true"
        cw-hgauge0="#208020:m:num::netp_in" 
        cw-min="l:num::0" cw-max="m:num::max$netp_in"></hgauge>
<hgauge cw-bgcolor="#202040" cw-ns="proc" style="height:2em" cw-log="true"
        cw-hgauge0="#208020:m:num::netp_out"
        cw-min="l:num::0" cw-max="m:num::max$netp_out"></hgauge>

There is a gauge for inbound traffic and one for outbound traffic. The gauges are set to a logarithmic scale otherwise you would see an empty gauge most of the time. Note that the maximum is set to the auto computed value so that conkw automatically determines the maximum throughput of your network interface to what it observes.

Multi-values holders

Identified by the attribute cw-multinode-pattern. It allows generation of multiple nodes like a for loop in a template. The example below would take 576 lines, but with a multivalue tag, it only takes 12.

Attributes:

Let's take a simple example:

<img cw-ns="owm" cw-prop-src="m:str::hourly_icon_0" cw-prop-title="m:str::hourly_desc_0">

The line above will display an image that will display the icon for the first forecasted hour. If you want the forecast for the next 48 hours, you will have to define 48 lines like this, only changing the 0 with the hour you want:

<img cw-ns="owm" cw-prop-src="m:str::hourly_icon_0" cw-prop-title="m:str::hourly_desc_0">
<img cw-ns="owm" cw-prop-src="m:str::hourly_icon_1" cw-prop-title="m:str::hourly_desc_1">
<img cw-ns="owm" cw-prop-src="m:str::hourly_icon_2" cw-prop-title="m:str::hourly_desc_2">
...
<img cw-ns="owm" cw-prop-src="m:str::hourly_icon_47" cw-prop-title="m:str::hourly_desc_47">

This is not optimal, because whenever you will have an update you want, such as adding a style attribute or changing the tooltip, you will have to propagate the update to all of the 48 lines.

Instead, you can use a multivalue tag, like this:

<div cw-ns="owm" cw-multinode-from="l:num::0" cw-multinode-to="l:num::47" cw-multinode-pattern="$">
  <img cw-ns="owm" cw-prop-src="m:str::hourly_icon_$" cw-prop-title="m:str::hourly_desc_$">
</div>

When seeing this, ConkW will duplicate the content of the div 48 times, replacing the $ with the actual value from 0 to 47.

Note that both from and to use an expression that is here a literal but may be computed.

Let's have a look at another example with the in directive, from the OshiGrabber default UI:

We want to display the read throughput of every block devices that are attached. And there are a few.

<heading>DISK IOs</heading>
<span cw-ns="oshi" cw-multinode-in="m:str::diskios_disks" cw-multinode-pattern="#">
  <label>R </label><cw-label cw-ns="oshi" cw-value="m:num:size:diskios_read_bytes_#"></cw-label>/s
  <label class="softlabel"><cw-label cw-ns="oshi" cw-value="m:num:size:max$diskios_read_bytes_#"></cw-label>/s</label>
  <label style="font-weight:bold"><cw-label>#</cw-label></label>
  <br/>
</span>

As you can see here, the multinode is defined with cw-multinode-in="m:str::diskios_disks". If you inspect closely the output of the API, diskios_disks has the value /dev/sdd,/dev/sda,/dev/sdb,/dev/sdc,/dev/nvme0n1 on my system, a comma separated list of the names of the block devices.

Hence, ConkW will duplicate thecontent of the divs for each one ot those block devices, replacing all instances of the pattern # with the name of the block device.