Remote device table sort by uptime

I'm using a flow by @Christian-Me to monitor my tasmota devices.
remote-device-table

The uptime column is sent # of seconds, but has custom formatting to display as Days hh:mm:ss.

Is there some way to make this sortable as number and string sort are no good ?

Hi ... yes you are right formatting before sending to ui-table was a bad idea. But fortunately the last seen timestamp is available. A custom formatter like below will do the trick:

function(cell, formatterParams, onRendered){
    var pad = function (num) {
        return ('0'+num).slice(-2);
    };     
    var secs = (Date.now() - Number(cell.getValue())) / 1000;
    if (Number.isNaN(secs)) return;
    var minutes = Math.floor(secs / 60);
    secs = secs % 60;
    var hours = Math.floor(minutes/60);
    minutes = minutes % 60;
    var days = Math.floor(hours/24);
    hours = hours%24;
    if (days>0) 
        return days+'d '+pad(hours)+':'+pad(minutes);
    else
        return pad(hours)+':'+pad(minutes)+':'+pad(secs); 
}

you might want to play with the code as you like. Sorting then happens on the unix timestamp before formatting. You have to change the field to lastSeenReady

            {
                "title": "last seen&nbsp;&nbsp;<i class='fa fa-clock-o fa-rotate-90'></i>",
                "field": "lastSeenready",
                "formatter": "function(cell, formatterParams, onRendered){     var pad = function (num) {         return ('0'+num).slice(-2);     };          var secs = (Date.now() - Number(cell.getValue())) / 1000;     if (Number.isNaN(secs)) return;     var minutes = Math.floor(secs / 60);     secs = secs % 60;     var hours = Math.floor(minutes/60);     minutes = minutes % 60;     var days = Math.floor(hours/24);     hours = hours%24;     if (days>0)          return days+'d '+pad(hours)+':'+pad(minutes);     else         return pad(hours)+':'+pad(minutes)+':'+pad(secs);  }",
                "width": 80,
                "align": "right",
                "tooltip": true,
                "headerVertical": "flip",
                "headerTooltip": "time since the device was sending $state updates",
                "headerContext": "function(e,column){ this.send({ui_control:{callback:'headerContext'},position:{\"x\":e.x,\"y\":e.y},payload:column._column.field}); e.preventDefault(); }"
            }

And ... The uptime column should already supports this, perhaps I added this later.

function(cell, formatterParams, onRendered){
    var pad = function (num) {
        return ('0'+num).slice(-2);
    };     
    var secs = Number(cell.getValue());
    if (Number.isNaN(secs)) return;
    var minutes = Math.floor(secs / 60);
    secs = secs % 60;
    var hours = Math.floor(minutes/60);
    minutes = minutes % 60;
    var days = Math.floor(hours/24);
    hours = hours%24;
    if (days>0) 
        return days+'d '+pad(hours)+':'+pad(minutes);
    else
        return pad(hours)+':'+pad(minutes)+':'+pad(secs); 
}

and

                    {
                        "title": "uptime&nbsp;&nbsp;<i class='fa fa-clock-o'></i>",
                        "field": "uptime",
                        "formatter": "function(cell, formatterParams, onRendered){     var pad = function (num) {         return ('0'+num).slice(-2);     };          var secs = Number(cell.getValue());     if (Number.isNaN(secs)) return;     var minutes = Math.floor(secs / 60);     secs = secs % 60;     var hours = Math.floor(minutes/60);     minutes = minutes % 60;     var days = Math.floor(hours/24);     hours = hours%24;     if (days>0)          return days+'d '+pad(hours)+':'+pad(minutes);     else         return pad(hours)+':'+pad(minutes)+':'+pad(secs);  }",
                        "width": 75,
                        "headerVertical": "flip",
                        "headerTooltip": "device uptime",
                        "headerContext": "function(e,column){ this.send({ui_control:{callback:'headerContext'},position:{\"x\":e.x,\"y\":e.y},payload:column._column.field}); e.preventDefault(); }"
                    }


Here is my favorite device :wink: 451d running without power off or unintentional reboot!

Thanks for getting back to me.

Looking at your image the last seen column is not sorted correctly ?

I checked uptime and it matches your code but this doesn't sort either as you can see -

image

Hi .... here on my side both uptime and last seen works as expected.

The problem could be (I see the red background on row 5) that the sorting is not applied on new data. In version 4.3 sorting takes place only on initial data or you have to call sorting by the setSort command after each update. more here

The sorting takes place on the raw data and the formatter does his business rendering the cell only

I don't have a quick solution to trigger sorting after each update and maintain the scroll position - I would not like the table jumping around on each update

Edit: javascript - Tabulator does not re-sort data after adding/updating row - Stack Overflow

but as you see the solution will scroll to the top position each update.

and there is a bug in formatting the lastSeen column with wired numbers. This should help:

function (cell, formatterParams, onRendered) {
    var pad = function (num) {
        return ('0' + num).slice(-2);
    };
    if (Number.isNaN(secs)) return;
    var secs = Math.floor((Date.now() - Number(cell.getValue())) / 1000);
    var minutes = Math.floor(secs / 60);
    secs = secs % 60;
    var hours = Math.floor(minutes / 60);
    minutes = minutes % 60;
    var days = Math.floor(hours / 24);
    hours = hours % 24;
    if (days > 0)
        return days + 'd ' + pad(hours) + ':' + pad(minutes);
    else
        return pad(hours) + ':' + pad(minutes) + ':' + pad(secs);
}

I added this to the uptime column and that seems to have fixed it

"sorter": "number",

Not sure why I need this and you don't though ?

I'm not too bothered about last seen as I like the formated version better as its easier to read.
I might see if I can replicate that formating in the table :wink:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.