Milliseconds to human readable

I have a custom function that computes duration in milliseconds and constructs a payload object like.

    const payload = {
        energy: energy,
        duration: duration, // in milliseconds
    }

    msg.payload = payload;
    
    return msg;

I know I could write some JS in the function to format this to human form but I was wondering there is a more standard/reusable way to do this.

Either

  1. Registering global functions that could be used in any function
  2. hook up some templating functions like how you can with Twig or Jinja2

As when I use the payload It’s like

{"message": "Washing machine used {{payload.energy}} kwh and ran for {{payload.duration}} for the last cycle"}

Was thinking something like this:https://github.com/vitalk/flask-humanize

So you could do {{payload.duration|humanize('naturaldelta')}}

I do this with jsonata $fromMillis() - https://docs.jsonata.org/date-time-functions

I am assuming that your Washing machine is now going to run for days. So the “humanize” is unlikely to be “last week” !
In this case, you can use https://flows.nodered.org/node/node-red-contrib-sun-position it will very easily output the duration in minutes.
GV

@RogTPhow can I use jsonate? Is it baked in?

@greengolferperhaps humaize wasn’t the right example but was thinking more along the notion of filters. Nodered is based on mustache AFAIK and I dont think you can have such logic in templates :frowning:

Not sure I understand what you mean… If duration is accessible using msg.payload.duration as in your example, the node I have suggested works. But, maybe I missed something.
GV

My function outputs the payload as energy in kwh and duration in milliseconds.

How would I use what you proposed to format this into a human readable form?

Are you just wanting to show number of minutes? I didn’t read this well enough because $fromMillis() will turn an input millisecond into a date/time, but I don’t think that is what you want.

On a Node-Red change node you can just set payload.duration using jsonata (look like a bold J:) using $round(payload/1000) - JSONata Documentation · JSONata

I use the nodejs moment library.

For example this code

arr = msg.payload
let persons = []
arr.forEach(function(v){
    date = mom(new Date(v.last_changed)).calendar().toLowerCase()
    persons.push(v.attributes.friendly_name.toLowerCase()+' is '+v.state+' since '+date)
})

text = '`'+persons.join('\n')+'`'

return {payload:{data:{message:text,title:'*INFO*'}}};

will give me
ricardo is home since today at 1:30 pm

mom is the moment module defined in settings.js functionsGlobalContext

        mom:require('moment'),

You don’t need to use code though, there is a moment node available also

Here is more info, maybe you can find a ready to go method that gives your output

https://momentjs.com/docs/

Hello ! I am trying to replicate your flow in this link ( https://www.malachisoord.com/2020/04/08/washing-machine-cycle-notifications/)

but no message pass to the call-service node , is that flow rigth?

It’s working for me - so the message is not being passed to the final node?

Perhaps you can add some debug logs to the compute node to see what’s happening.

What’s pasted is exactly what I use.

Hello.

First off all, thanks for the very quick reply.

Yes every think is good, i just miss understand what it turns to be a very important step, in the first node ( state node ) choose- state type: boolean - i know you mention that, i just missed.

By the way you could edit the data there of the state node to match what you put in this topic:

{"message": "Washing machine used {{payload.energy}} kwh and ran for {{payload.duration}} for the last cycle"}

Very nice work, i,m just an ordinary begginner turning to medium user , so its easy to amuse me, but i must say that this was the most powerfull/usefull function i,ve seen in node red.

Congrats

Thanks for the heads up! It’s actually there but the framework I am using (jekyll) escaped it… I will fix this issue!

— Update –

It’s fixed!