# Remote device table sort by uptime

**URL:** <https://discourse.nodered.org/t/remote-device-table-sort-by-uptime/59076>\
**Category:** Dashboard\
**Created:** [27 February 2022 18:43 UTC](https://discourse.nodered.org/t/remote-device-table-sort-by-uptime/59076 "2022-02-27T18:43:40Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sean-McG](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/sean-mcg/32/54677_2.png) [@Sean-McG](https://discourse.nodered.org/u/Sean-McG)\
**Post date:** [27 February 2022 18:43 UTC](https://discourse.nodered.org/t/remote-device-table-sort-by-uptime/59076/1 "2022-02-27T18:43:40Z")

</div>

I'm using a flow by @Christian-Me to monitor my tasmota devices.  
[remote-device-table](https://discourse.nodered.org/t/announce-remote-device-table-and-collaboration-wanted/22505)

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 ?

---

<div class="post-metadata">

**Author:** ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)\
**Post date:** [1 March 2022 18:21 UTC](https://discourse.nodered.org/t/remote-device-table-sort-by-uptime/59076/2 "2022-03-01T18:21:43Z")

</div>

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:

```auto
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`

```json
            {
                "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(); }"
            }

```

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/1/5/15120f07d8343afd484bbb3ed02c537d8ca6d849.png)

---

<div class="post-metadata">

**Author:** ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)\
**Post date:** [1 March 2022 18:28 UTC](https://discourse.nodered.org/t/remote-device-table-sort-by-uptime/59076/3 "2022-03-01T18:28:00Z")

</div>

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

```auto
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

```auto
                    {
                        "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(); }"
                    }

```

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/d/e/deb4455000d9c8813961c4defc55e507d103c6fb.png)  
Here is my favorite device 😉 451d running without power off or unintentional reboot!

---

<div class="post-metadata">

**Author:** ![Sean-McG](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/sean-mcg/32/54677_2.png) [@Sean-McG](https://discourse.nodered.org/u/Sean-McG)\
**Post date:** [2 March 2022 01:35 UTC](https://discourse.nodered.org/t/remote-device-table-sort-by-uptime/59076/4 "2022-03-02T01:35:37Z")

</div>

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](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/c/fc0f2c0a6169ddc61073aef09579ab1eab39164a.png)

---

<div class="post-metadata">

**Author:** ![Christian-Me](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/christian-me/32/10774_2.png) [@Christian-Me](https://discourse.nodered.org/u/Christian-Me)\
**Post date:** [2 March 2022 10:46 UTC](https://discourse.nodered.org/t/remote-device-table-sort-by-uptime/59076/5 "2022-03-02T10:46:10Z")

</div>

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](http://tabulator.info/docs/4.3/sort#func-builtin)

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](https://stackoverflow.com/questions/65945239/tabulator-does-not-re-sort-data-after-adding-updating-row)

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:

```auto
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);
}

```

---

<div class="post-metadata">

**Author:** ![Sean-McG](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/sean-mcg/32/54677_2.png) [@Sean-McG](https://discourse.nodered.org/u/Sean-McG)\
**Post date:** [2 March 2022 16:01 UTC](https://discourse.nodered.org/t/remote-device-table-sort-by-uptime/59076/6 "2022-03-02T16:01:42Z")

</div>

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 😉

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [1 April 2022 16:02 UTC](https://discourse.nodered.org/t/remote-device-table-sort-by-uptime/59076/7 "2022-04-01T16:02:38Z")

</div>

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