The timestamp comes into the first function as the msg.payload.
I'm not trying to reinvent anything here, just using what others have supplied (I'd have never of got this far on my own! ), and trying to tweak it a little. The timer works just fine as it is, and I've managed to add some buttons for adding and removing time successfully. It just seems to be something in the formatting that isn't quite right, or non existing, for when it goes into minus time. It's for an escape room timer/gamemaster software, so there's other buttons and arduinos going to be linked into it all, but I here (I think) are all the parts that relate to the timer section:
[
{
"id": "906339c5.ce4fa",
"type": "inject",
"z": "29662af6.96a146",
"name": "Setup",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 190,
"y": 100,
"wires": [
[
"becf850a.cbcee"
]
]
},
{
"id": "becf850a.cbcee",
"type": "change",
"z": "29662af6.96a146",
"name": "",
"rules": [
{
"t": "set",
"p": "gameState",
"pt": "flow",
"to": "stopped",
"tot": "str"
},
{
"t": "set",
"p": "timeRemaining",
"pt": "flow",
"to": "3600000",
"tot": "str"
},
{
"t": "set",
"p": "currentTime",
"pt": "flow",
"to": "payload",
"tot": "msg"
},
{
"t": "set",
"p": "logging",
"pt": "flow",
"to": "true",
"tot": "bool"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 360,
"y": 100,
"wires": [
[
"cc5aea0b.1742e"
]
]
},
{
"id": "ca343107.aec8b",
"type": "inject",
"z": "29662af6.96a146",
"name": "Start",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 190,
"y": 240,
"wires": [
[
"49b44f5a.132568"
]
]
},
{
"id": "9266125d.112b38",
"type": "inject",
"z": "29662af6.96a146",
"name": "Stop",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 610,
"y": 240,
"wires": [
[
"8157f92c.9324e"
]
]
},
{
"id": "49b44f5a.132568",
"type": "change",
"z": "29662af6.96a146",
"name": "",
"rules": [
{
"t": "set",
"p": "gameState",
"pt": "flow",
"to": "playing",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 380,
"y": 240,
"wires": [
[]
]
},
{
"id": "8157f92c.9324e",
"type": "change",
"z": "29662af6.96a146",
"name": "",
"rules": [
{
"t": "set",
"p": "gameState",
"pt": "flow",
"to": "stopped",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 810,
"y": 240,
"wires": [
[]
]
},
{
"id": "91ccf9a6.2af778",
"type": "inject",
"z": "29662af6.96a146",
"name": "Reset",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 1030,
"y": 240,
"wires": [
[
"b8b19971.5380a8"
]
]
},
{
"id": "b8b19971.5380a8",
"type": "change",
"z": "29662af6.96a146",
"name": "",
"rules": [
{
"t": "set",
"p": "timeRemaining",
"pt": "flow",
"to": "3600000",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1240,
"y": 240,
"wires": [
[]
]
},
{
"id": "bf54624f.1f05b8",
"type": "ui_button",
"z": "29662af6.96a146",
"name": "",
"group": "e28e9683.8bc2e8",
"order": 4,
"width": 2,
"height": 2,
"passthru": true,
"label": "Start",
"tooltip": "",
"color": "",
"bgcolor": "green",
"icon": "",
"payload": "start",
"payloadType": "str",
"topic": "TIMER",
"x": 170,
"y": 180,
"wires": [
[
"49b44f5a.132568",
"e070cc33.ebeea"
]
]
},
{
"id": "cf24c6ee.702378",
"type": "ui_button",
"z": "29662af6.96a146",
"name": "",
"group": "e28e9683.8bc2e8",
"order": 5,
"width": 2,
"height": 2,
"passthru": true,
"label": "Stop",
"tooltip": "",
"color": "",
"bgcolor": "red",
"icon": "",
"payload": "stop",
"payloadType": "str",
"topic": "TIMER",
"x": 610,
"y": 180,
"wires": [
[
"8157f92c.9324e",
"b7ffebb9.b20958"
]
]
},
{
"id": "47ca99f6.2d9bf",
"type": "ui_button",
"z": "29662af6.96a146",
"name": "",
"group": "e28e9683.8bc2e8",
"order": 6,
"width": "2",
"height": 2,
"passthru": false,
"label": "<b>!!! Reset !!!</b>",
"tooltip": "",
"color": "",
"bgcolor": "red",
"icon": "",
"payload": "reset",
"payloadType": "str",
"topic": "TIMER",
"x": 980,
"y": 180,
"wires": [
[
"b8b19971.5380a8",
"f03e9c77.072b48"
]
]
},
{
"id": "f03e9c77.072b48",
"type": "link out",
"z": "29662af6.96a146",
"name": "reset",
"links": [
"7105f2a1.21812c",
"ad7b2357.d2e098",
"c1443e15.6728c8",
"ab7c57db.9ca698",
"a6cd94c7.4d6bd",
"b91d3509.17212",
"66ce8743.b007a8",
"f6e1656c.d7af6",
"a7abf569.ae721",
"2d230649.2da632"
],
"x": 1155,
"y": 180,
"wires": []
},
{
"id": "ad7b2357.d2e098",
"type": "link in",
"z": "29662af6.96a146",
"name": "reset-stop",
"links": [
"f03e9c77.072b48",
"6a781a22.d020c4"
],
"x": 515,
"y": 180,
"wires": [
[
"cf24c6ee.702378"
]
]
},
{
"id": "9b7fbc0.3a3a0c8",
"type": "change",
"z": "29662af6.96a146",
"name": "",
"rules": [
{
"t": "set",
"p": "timeRemaining",
"pt": "flow",
"to": "timeRemaining",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 620,
"y": 300,
"wires": [
[]
]
},
{
"id": "a3531003.a731d",
"type": "ui_button",
"z": "29662af6.96a146",
"name": "",
"group": "e28e9683.8bc2e8",
"order": 7,
"width": 2,
"height": "2",
"passthru": false,
"label": "+1 min",
"tooltip": "",
"color": "",
"bgcolor": "",
"icon": "",
"payload": "+1 min",
"payloadType": "str",
"topic": "TIMER",
"x": 170,
"y": 300,
"wires": [
[
"77f6da55.553bcc",
"ec0c7f2f.eb6ab8"
]
]
},
{
"id": "77f6da55.553bcc",
"type": "function",
"z": "29662af6.96a146",
"name": "",
"func": "var timeRemaining = flow.get(\"timeRemaining\") || 0;\nvar addOne = 60000\n\ntimeRemaining += addOne;\n \nflow.set(\"timeRemaining\", timeRemaining);\n\nmsg.timeRemaining = timeRemaining;\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 420,
"y": 300,
"wires": [
[
"9b7fbc0.3a3a0c8"
]
]
},
{
"id": "d74ba333.870fc8",
"type": "change",
"z": "29662af6.96a146",
"name": "",
"rules": [
{
"t": "set",
"p": "timeRemaining",
"pt": "flow",
"to": "timeRemaining",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1240,
"y": 300,
"wires": [
[]
]
},
{
"id": "6873a943.66294",
"type": "ui_button",
"z": "29662af6.96a146",
"name": "",
"group": "e28e9683.8bc2e8",
"order": 8,
"width": 2,
"height": "2",
"passthru": false,
"label": "+5 min",
"tooltip": "",
"color": "",
"bgcolor": "",
"icon": "",
"payload": "+5 min",
"payloadType": "str",
"topic": "TIMER",
"x": 810,
"y": 300,
"wires": [
[
"e69b3482.115b38",
"16cc4509.c631bb"
]
]
},
{
"id": "e69b3482.115b38",
"type": "function",
"z": "29662af6.96a146",
"name": "",
"func": "var timeRemaining = flow.get(\"timeRemaining\") || 0;\nvar addOne = 60000*5\n\ntimeRemaining += addOne;\n \nflow.set(\"timeRemaining\", timeRemaining);\n\nmsg.timeRemaining = timeRemaining;\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 1040,
"y": 300,
"wires": [
[
"d74ba333.870fc8"
]
]
},
{
"id": "e070cc33.ebeea",
"type": "link out",
"z": "29662af6.96a146",
"name": "start",
"links": [
"c1443e15.6728c8"
],
"x": 295,
"y": 180,
"wires": []
},
{
"id": "b7ffebb9.b20958",
"type": "link out",
"z": "29662af6.96a146",
"name": "stop",
"links": [
"c1443e15.6728c8"
],
"x": 735,
"y": 180,
"wires": []
},
{
"id": "ec0c7f2f.eb6ab8",
"type": "link out",
"z": "29662af6.96a146",
"name": "+1min",
"links": [
"c1443e15.6728c8"
],
"x": 275,
"y": 300,
"wires": []
},
{
"id": "16cc4509.c631bb",
"type": "link out",
"z": "29662af6.96a146",
"name": "+5min",
"links": [
"c1443e15.6728c8"
],
"x": 915,
"y": 300,
"wires": []
},
{
"id": "e17ffd4e.433bf",
"type": "change",
"z": "29662af6.96a146",
"name": "",
"rules": [
{
"t": "set",
"p": "timeRemaining",
"pt": "flow",
"to": "timeRemaining",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 620,
"y": 360,
"wires": [
[]
]
},
{
"id": "486e099f.3951b",
"type": "ui_button",
"z": "29662af6.96a146",
"name": "",
"group": "e28e9683.8bc2e8",
"order": 10,
"width": 2,
"height": "2",
"passthru": false,
"label": "-1 min",
"tooltip": "",
"color": "",
"bgcolor": "",
"icon": "",
"payload": "-1 min",
"payloadType": "str",
"topic": "TIMER",
"x": 170,
"y": 360,
"wires": [
[
"af55c2c6.06b228",
"ffd60e8e.f7d84"
]
]
},
{
"id": "af55c2c6.06b228",
"type": "function",
"z": "29662af6.96a146",
"name": "",
"func": "var timeRemaining = flow.get(\"timeRemaining\") || 0;\nvar addOne = 60000\n\ntimeRemaining -= addOne;\n \nflow.set(\"timeRemaining\", timeRemaining);\n\nmsg.timeRemaining = timeRemaining;\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 420,
"y": 360,
"wires": [
[
"e17ffd4e.433bf"
]
]
},
{
"id": "374eb5e7.9cc7a2",
"type": "change",
"z": "29662af6.96a146",
"name": "",
"rules": [
{
"t": "set",
"p": "timeRemaining",
"pt": "flow",
"to": "timeRemaining",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1240,
"y": 360,
"wires": [
[]
]
},
{
"id": "24347276.8a2706",
"type": "ui_button",
"z": "29662af6.96a146",
"name": "",
"group": "e28e9683.8bc2e8",
"order": 11,
"width": 2,
"height": "2",
"passthru": false,
"label": "-5 min",
"tooltip": "",
"color": "",
"bgcolor": "",
"icon": "",
"payload": "-5 min",
"payloadType": "str",
"topic": "TIMER",
"x": 810,
"y": 360,
"wires": [
[
"dee13c37.ab0b",
"60a4437.54128bc"
]
]
},
{
"id": "dee13c37.ab0b",
"type": "function",
"z": "29662af6.96a146",
"name": "",
"func": "var timeRemaining = flow.get(\"timeRemaining\") || 0;\nvar addOne = 60000*5\n\ntimeRemaining -= addOne;\n \nflow.set(\"timeRemaining\", timeRemaining);\n\nmsg.timeRemaining = timeRemaining;\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 1040,
"y": 360,
"wires": [
[
"374eb5e7.9cc7a2"
]
]
},
{
"id": "ffd60e8e.f7d84",
"type": "link out",
"z": "29662af6.96a146",
"name": "-1min",
"links": [
"c1443e15.6728c8"
],
"x": 275,
"y": 360,
"wires": []
},
{
"id": "60a4437.54128bc",
"type": "link out",
"z": "29662af6.96a146",
"name": "-5min",
"links": [
"c1443e15.6728c8"
],
"x": 915,
"y": 360,
"wires": []
},
{
"id": "cc5aea0b.1742e",
"type": "link out",
"z": "29662af6.96a146",
"name": "",
"links": [],
"x": 495,
"y": 100,
"wires": []
},
{
"id": "a1304d26.6c6b98",
"type": "inject",
"z": "29662af6.96a146",
"name": "Loop",
"props": [
{
"p": "payload"
}
],
"repeat": "1",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 170,
"y": 480,
"wires": [
[
"f8f9c3af.4996c8"
]
]
},
{
"id": "f8f9c3af.4996c8",
"type": "function",
"z": "29662af6.96a146",
"name": "",
"func": "var currentTime = msg.payload;\nvar lastTickTime = flow.get(\"lastTickTime\") || currentTime;\nvar timeRemaining = flow.get(\"timeRemaining\") || 0;\nvar gameState = flow.get(\"gameState\");\n\nif(gameState == \"playing\") {\n\n timeRemaining -= (currentTime - lastTickTime);\n \n flow.set(\"timeRemaining\", timeRemaining);\n \n}\n\nmsg.timeRemaining = timeRemaining;\nflow.set(\"lastTickTime\", currentTime);\n\nnode.status({fill:\"green\", shape:\"dot\", text:timeRemaining});\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 340,
"y": 480,
"wires": [
[
"c7146f2b.9b30e"
]
]
},
{
"id": "c7146f2b.9b30e",
"type": "function",
"z": "29662af6.96a146",
"name": "Format time",
"func": "var t = msg.timeRemaining / 1000;\nvar m = Math.floor(t / 60);\nvar s = Math.floor(t%60 % 60);\n\nmsg.formattedTimeRemaining = (\"0\" + m).slice(-2) + \":\" + (\"0\" + s).slice(-2);\n\nnode.status({fill:\"green\", shape:\"dot\", msg:flow.formattedTimeRemaining});\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 530,
"y": 480,
"wires": [
[
"5970c5ac.84e9fc"
]
]
},
{
"id": "5970c5ac.84e9fc",
"type": "join",
"z": "29662af6.96a146",
"name": "",
"mode": "custom",
"build": "merged",
"property": "",
"propertyType": "full",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"accumulate": true,
"timeout": "",
"count": "1",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "num",
"reduceFixup": "",
"x": 1090,
"y": 480,
"wires": [
[
"3e91b62d.cfd2e2"
]
]
},
{
"id": "3e91b62d.cfd2e2",
"type": "uibuilder",
"z": "29662af6.96a146",
"name": "Game Timer and Clue Display",
"topic": "",
"url": "atlantis",
"fwdInMessages": false,
"allowScripts": false,
"allowStyles": false,
"copyIndex": true,
"showfolder": false,
"x": 1300,
"y": 480,
"wires": [
[],
[]
]
},
{
"id": "e28e9683.8bc2e8",
"type": "ui_group",
"z": "",
"name": "Timer",
"tab": "759f7fcb.6ad23",
"order": 1,
"disp": false,
"width": "8",
"collapse": false
},
{
"id": "759f7fcb.6ad23",
"type": "ui_tab",
"z": "",
"name": "Atlantis",
"icon": "dashboard",
"disabled": false,
"hidden": false
}
]