Operating time - cflurin/node-red-contrib-dsm GitHub Wiki

The operating time dsm calculates the time a device is on.

Usage

topic action
on starts or continues counting
off stops counting
reset sets the counter to 0

Settings

"data": {
   ....
   "interval": 1,
   "interval_output": true,
   "hms_format": true
}
  • interval: time in seconds
  • interval_output: true > a msg is sent after every interval
  • interval_output: false > a msg is only sent at stop
  • hms_format: true > time format hh:mm:ss
  • hms_format: false > time in seconds

operating_time

Configuration

{
    "currentState": "stopped",
    "states": {
        "stopped": {
            "on": "started"
        },
        "started": {
            "inc": "counting",
            "off": "stopped"
        },
        "counting": {
            "inc": "counting",
            "off": "stopped"
        }
    },
    "data": {
        "prev_time": null,
        "time": 0,
        "seconds": 0,
        "interval": 1,
        "interval_output": true,
        "hms_format": true
    },
    "methods": {
        "init": [
            "sm.calc_time = function() {",
            "   var now = Date.now();",
            "   sm.data.time += now - sm.data.prev_time;",
            "   sm.data.prev_time = now;",
            "   sm.data.seconds = Math.round(sm.data.time / 1000);",
            "};",
            "sm.sec2hhmmss = function(sec) {",
                "var t = {};",
                "t.h = pad(Math.floor(sec / 3600));",
                "sec %= 3600;",
                "t.m = pad(Math.floor(sec / 60));",
                "t.s = pad(sec % 60);",
                "return t.h+':'+t.m+':'+t.s;",
            "};"
        ],
        "on": [
            "if (sm.currentState === 'started') {",
            "   sm.data.prev_time = Date.now();",
            "   resume('inc', msg);",
            "}",
            "output = false;"
        ],
        "inc": [
            "timeout.interval = setTimeout(function() {",
            "   sm.calc_time();",
            "   msg.data = sm.data;",
            "   if (sm.data.interval_output) {",
            "       msg.payload = sm.data.hms_format ? sm.sec2hhmmss(sm.data.seconds): sm.data.seconds;",
            "       node.send(msg);",
            "   }",
            "   resume('inc', msg);",
            "}, sm.data.interval*1000);",
            "output = false;"
        ],
        "off": [
            "clearTimeout(timeout.interval);",
            "sm.calc_time();",
            "msg.payload = sm.data.hms_format ? sm.sec2hhmmss(sm.data.seconds): sm.data.seconds;"
        ],
        "reset": [
            "sm.data.time = 0;",
            "sm.data.seconds = 0;"
        ],
        "status": {
            "fill": {
                "get": "sm.currentState === 'counting' ? 'green' : 'grey';"
            },
            "shape": "dot",
            "text": {
                "get": "'time ' + (sm.data.hms_format ? sm.sec2hhmmss(sm.data.seconds): sm.data.seconds);"
            }
        }
    }
}

Flow

[{"id":"e04a7aba.3df938","type":"inject","z":"6ff0723.8c6b78c","name":"on","topic":"on","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":2440,"wires":["7496eabc.a510c4"](/cflurin/node-red-contrib-dsm/wiki/"7496eabc.a510c4")},{"id":"2f45d52f.e2488a","type":"inject","z":"6ff0723.8c6b78c","name":"off","topic":"off","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":2480,"wires":["7496eabc.a510c4"](/cflurin/node-red-contrib-dsm/wiki/"7496eabc.a510c4")},{"id":"c308d218.4b2b3","type":"inject","z":"6ff0723.8c6b78c","name":"reset","topic":"reset","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":2520,"wires":["7496eabc.a510c4"](/cflurin/node-red-contrib-dsm/wiki/"7496eabc.a510c4")},{"id":"e992fe0b.d58b5","type":"debug","z":"6ff0723.8c6b78c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":530,"y":2480,"wires":[]},{"id":"7496eabc.a510c4","type":"dsm","z":"6ff0723.8c6b78c","name":"operating time","sm_config":"{\n    \"currentState\": \"stopped\",\n    \"states\": {\n        \"stopped\": {\n            \"on\": \"started\"\n        },\n        \"started\": {\n            \"inc\": \"counting\",\n            \"off\": \"stopped\"\n        },\n        \"counting\": {\n            \"inc\": \"counting\",\n            \"off\": \"stopped\"\n        }\n    },\n    \"data\": {\n        \"prev_time\": null,\n        \"time\": 0,\n        \"seconds\": 0,\n        \"interval\": 1,\n        \"interval_output\": true,\n        \"hms_format\": true\n    },\n    \"methods\": {\n        \"init\": [\n            \"sm.calc_time = function() {\",\n            \"   var now = Date.now();\",\n            \"   sm.data.time += now - sm.data.prev_time;\",\n            \"   sm.data.prev_time = now;\",\n            \"   sm.data.seconds = Math.round(sm.data.time / 1000);\",\n            \"};\",\n            \"sm.sec2hhmmss = function(sec) {\",\n                \"var t = {};\",\n                \"t.h = pad(Math.floor(sec / 3600));\",\n                \"sec %= 3600;\",\n                \"t.m = pad(Math.floor(sec / 60));\",\n                \"t.s = pad(sec % 60);\",\n                \"return t.h+':'+t.m+':'+t.s;\",\n            \"};\"\n        ],\n        \"on\": [\n            \"if (sm.currentState === 'started') {\",\n            \"   sm.data.prev_time = Date.now();\",\n            \"   resume('inc', msg);\",\n            \"}\",\n            \"output = false;\"\n        ],\n        \"inc\": [\n            \"timeout.interval = setTimeout(function() {\",\n            \"   sm.calc_time();\",\n            \"   msg.data = sm.data;\",\n            \"   if (sm.data.interval_output) {\",\n            \"       msg.payload = sm.data.hms_format ? sm.sec2hhmmss(sm.data.seconds): sm.data.seconds;\",\n            \"       node.send(msg);\",\n            \"   }\",\n            \"   resume('inc', msg);\",\n            \"}, sm.data.interval*1000);\",\n            \"output = false;\"\n        ],\n        \"off\": [\n            \"clearTimeout(timeout.interval);\",\n            \"sm.calc_time();\",\n            \"msg.payload = sm.data.hms_format ? sm.sec2hhmmss(sm.data.seconds): sm.data.seconds;\"\n        ],\n        \"reset\": [\n            \"sm.data.time = 0;\",\n            \"sm.data.seconds = 0;\"\n        ],\n        \"status\": {\n            \"fill\": {\n                \"get\": \"sm.currentState === 'counting' ? 'green' : 'grey';\"\n            },\n            \"shape\": \"dot\",\n            \"text\": {\n                \"get\": \"'time ' + (sm.data.hms_format ? sm.sec2hhmmss(sm.data.seconds): sm.data.seconds);\"\n            }\n        }\n    }\n}\n","x":350,"y":2480,"wires":["e992fe0b.d58b5"](/cflurin/node-red-contrib-dsm/wiki/"e992fe0b.d58b5")}]