Set datetime with node red?

How is that done?
I have a input_datetime with both time and date, and I get API fail.

“Call-service API error. Error Message: Invalid datetime specified: for dictionary value @ data[‘datetime’]”

[{"id":"4fb106f4.26d9c8","type":"inject","z":"ae8e980a.d3b8f8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":1530,"y":880,"wires":[["8d1506b4.905c98"]]},{"id":"8d1506b4.905c98","type":"api-call-service","z":"ae8e980a.d3b8f8","name":"","server":"4bbca37b.1700ec","version":1,"debugenabled":false,"service_domain":"input_datetime","service":"set_datetime","entityId":"input_datetime.laddare_vardagsrum_tid","data":"{\"entity_id\":\"input_datetime.laddare_vardagsrum_tid\",\"datetime\":\"{{ ((as_timestamp(now()) | int + 7200) | timestamp_custom('%Y-%m-%d %H:%M:%S', true)) }}\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1780,"y":760,"wires":[[]]},{"id":"4bbca37b.1700ec","type":"server","z":"","name":"Home Assistant","addon":true}]

json:

{
    "entity_id": "input_datetime.laddare_vardagsrum_tid",
    "datetime": "{{ ((as_timestamp(now()) | int + 7200) | timestamp_custom('%Y-%m-%d %H:%M:%S', true)) }}"
}

So I try to set the time two hours ahead.
When I template the… template… it looks correct

I made a workaround.
I used a function node to create the time in javascript that then is passed to the call service node.

[{"id":"4fb106f4.26d9c8","type":"inject","z":"ae8e980a.d3b8f8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":1380,"y":860,"wires":[["51697d1f.5a21f4"]]},{"id":"51697d1f.5a21f4","type":"function","z":"ae8e980a.d3b8f8","name":"","func":"var d = new Date(); \nd.setMinutes(d.getMinutes() + 120);\n\nmsg.time = d.getFullYear() + \"-\" + ('0' + (d.getMonth()+1)).slice(-2) + \"-\" + d.getDate() + \" \" + d.getHours() + \":\" + d.getMinutes() + \":\" + d.getSeconds();\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1540,"y":860,"wires":[["39827a8d.b59b16","343b5b9a.233d54","8d1506b4.905c98"]]},{"id":"8d1506b4.905c98","type":"api-call-service","z":"ae8e980a.d3b8f8","name":"","server":"4bbca37b.1700ec","version":1,"debugenabled":false,"service_domain":"input_datetime","service":"set_datetime","entityId":"input_datetime.laddare_vardagsrum_tid","data":"{\"entity_id\":\"input_datetime.laddare_vardagsrum_tid\",\"datetime\":\"{{ time }}\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1780,"y":760,"wires":[[]]},{"id":"4bbca37b.1700ec","type":"server","z":"","name":"Home Assistant","addon":true}]

function node javascript:

var d = new Date(); 
d.setMinutes(d.getMinutes() + 120); // add 120 minutes to current time

// build the date time string
msg.time =  d.getFullYear() + "-" + ('0' + (d.getMonth()+1)).slice(-2) + "-" + d.getDate() + " " + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds();
// 2020-08-14 12:59:00
return msg;

and then in the call service I use:

{
    "entity_id": "input_datetime.laddare_vardagsrum_tid",
    "datetime": "{{ time }}"
}

not a very elegant solution but it works.

2 Likes

I just wanted to add to this, as I was having the same issue and came across this thread, but eventually found a more elegant solution.

Javascript’s Date.now timestamp is in milliseconds. input_datetime only accepts a timestamp in seconds, but as a float value (in fact, HA seems to record the timestamp attribute with 3 decimal places).

So I put together this basic function:

var t = Date.now();
msg.unix_time = t / 1000;
return msg;

Then in the call service, I added this to the data field:

{"timestamp":"{{unix_time}}"}

And that seems to work fine. I imagine this was also make adding time a lot easier as all you’d to do is figure out what you want to add in seconds and modify the function accordingly.

@Hellis81 For your issue, I used this function:

var t = Date.now();
msg.time = (t / 1000) + 7200;
return msg;