refactoring of layout

This commit is contained in:
Wolfgang Hottgenroth 2022-01-11 08:32:02 +00:00
parent ff9a60241e
commit 3ce4c900b2
3 changed files with 978 additions and 9 deletions

View File

@ -2,18 +2,979 @@
{ {
"id": "f6f2187d.f17ca8", "id": "f6f2187d.f17ca8",
"type": "tab", "type": "tab",
"label": "Flow 1", "label": "Main Flows",
"disabled": false, "disabled": false,
"info": "" "info": ""
}, },
{ {
"id": "3cc11d24.ff01a2", "id": "21801ad4.5fea0e",
"type": "postgresdb",
"cfgname": "timescaledb",
"hostname": "172.16.10.27",
"port": "5432",
"db": "mainscnt",
"ssl": true
},
{
"id": "3358c20a.fe8336",
"type": "twitter-credentials",
"screen_name": "wollud1969"
},
{
"id": "bde268f2.c163d8",
"type": "ui_tab",
"name": "MainsCnt",
"icon": "dashboard",
"disabled": false,
"hidden": false
},
{
"id": "c5c107b9.c41048",
"type": "ui_base",
"theme": {
"name": "theme-light",
"lightTheme": {
"default": "#0094CE",
"baseColor": "#0094CE",
"baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif",
"edited": true,
"reset": false
},
"darkTheme": {
"default": "#097479",
"baseColor": "#097479",
"baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif",
"edited": false
},
"customTheme": {
"name": "Untitled Theme 1",
"default": "#4B7930",
"baseColor": "#4B7930",
"baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"
},
"themeState": {
"base-color": {
"default": "#0094CE",
"value": "#0094CE",
"edited": false
},
"page-titlebar-backgroundColor": {
"value": "#0094CE",
"edited": false
},
"page-backgroundColor": {
"value": "#fafafa",
"edited": false
},
"page-sidebar-backgroundColor": {
"value": "#ffffff",
"edited": false
},
"group-textColor": {
"value": "#1bbfff",
"edited": false
},
"group-borderColor": {
"value": "#ffffff",
"edited": false
},
"group-backgroundColor": {
"value": "#ffffff",
"edited": false
},
"widget-textColor": {
"value": "#111111",
"edited": false
},
"widget-backgroundColor": {
"value": "#0094ce",
"edited": false
},
"widget-borderColor": {
"value": "#ffffff",
"edited": false
},
"base-font": {
"value": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"
}
},
"angularTheme": {
"primary": "indigo",
"accents": "blue",
"warn": "red",
"background": "grey"
}
},
"site": {
"name": "Node-RED Dashboard",
"hideToolbar": "false",
"allowSwipe": "false",
"lockMenu": "false",
"allowTempTheme": "true",
"dateFormat": "DD.MM.YYYY",
"sizes": {
"sx": 48,
"sy": 48,
"gx": 6,
"gy": 6,
"cx": 6,
"cy": 6,
"px": 0,
"py": 0
}
}
},
{
"id": "a4c5e228.94ac28",
"type": "ui_group",
"name": "Deviation",
"tab": "bde268f2.c163d8",
"order": 2,
"disp": false,
"width": "12",
"collapse": false
},
{
"id": "b44c1611.48c72",
"type": "ui_group",
"name": "Frequency&Alarm",
"tab": "bde268f2.c163d8",
"order": 3,
"disp": false,
"width": "6",
"collapse": false
},
{
"id": "ee409cd5.fa48e8",
"type": "ui_spacer",
"name": "spacer",
"group": "b44c1611.48c72",
"order": 3,
"width": 1,
"height": 1
},
{
"id": "938dc565.b607f",
"type": "tls-config",
"name": "",
"cert": "",
"key": "",
"ca": "",
"certname": "wn-mainscnt-broker-client.crt",
"keyname": "wn-mainscnt-broker-client.pem",
"caname": "isrgrootx1.pem",
"servername": "broker.mainscnt.eu",
"verifyservercert": true
},
{
"id": "48a55c40.d99ddc",
"type": "mqtt-broker",
"name": "ExternalBroker",
"broker": "broker.mainscnt.eu",
"port": "8883",
"tls": "938dc565.b607f",
"clientid": "",
"usetls": true,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willPayload": "",
"willMsg": {},
"sessionExpiry": ""
},
{
"id": "911fb610.7082e",
"type": "function",
"z": "f6f2187d.f17ca8",
"name": "missing values",
"func": "msg.queryParameters = {\n \"threshold\": msg.threshold\n}\nmsg.payload = `\n SELECT count(freq) AS cnt, location\n FROM mainsfrequency\n WHERE time BETWEEN\n now() - interval '10 minutes' AND now() - interval '5 minutes'\n GROUP BY location\n HAVING count(freq) <= $threshold\n`\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 140,
"y": 180,
"wires": [
[
"b6ffa593.3030a8"
]
]
},
{
"id": "4faba5e0.e01474",
"type": "change",
"z": "f6f2187d.f17ca8",
"name": "Threshold 100",
"rules": [
{
"t": "set",
"p": "threshold",
"pt": "msg",
"to": "100",
"tot": "num"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 140,
"y": 140,
"wires": [
[
"911fb610.7082e"
]
]
},
{
"id": "b6ffa593.3030a8",
"type": "postgres",
"z": "f6f2187d.f17ca8",
"postgresdb": "21801ad4.5fea0e",
"name": "mainscnt",
"output": true,
"perrow": false,
"rowspermsg": "1",
"return_on_error": false,
"limit_queries": "0",
"limit_by": "payload",
"limit_value": "1",
"limit_drop_intermediate": false,
"limit_drop_if_in_queue": false,
"outputs": true,
"x": 160,
"y": 220,
"wires": [
[
"9dcb400a.e79da"
]
]
},
{
"id": "9dcb400a.e79da",
"type": "function",
"z": "f6f2187d.f17ca8",
"name": "Prepare",
"func": "if (msg.payload.length > 0) {\n msg.queryResult = msg.payload\n let output = \"Missing/too few values five minutes ago \"\n output += `(<= ${msg.threshold}), in `\n for (const [idx, item] of msg.payload.entries()) {\n output += `${item.location} (${item.cnt})`\n if (idx != msg.payload.length - 1) {\n output += \", \"\n }\n }\n output += \".\\n\"\n msg.payload = output\n msg.payloadLength = output.length\n return msg\n} else {\n return null\n}",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 160,
"y": 260,
"wires": [
[
"b38b3cf3.92f31"
]
]
},
{
"id": "b38b3cf3.92f31",
"type": "pushover",
"z": "f6f2187d.f17ca8",
"name": "MainsCntAlarm",
"device": "",
"title": "",
"priority": 0,
"sound": "",
"url": "",
"url_title": "",
"html": false,
"x": 140,
"y": 300,
"wires": []
},
{
"id": "e4b652d9.980e8",
"type": "inject",
"z": "f6f2187d.f17ca8",
"name": "Once a minute",
"props": [
{
"p": "payload"
}
],
"repeat": "60",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "true",
"payloadType": "bool",
"x": 140,
"y": 100,
"wires": [
[
"4faba5e0.e01474"
]
]
},
{
"id": "df8fb736.a86528",
"type": "function",
"z": "f6f2187d.f17ca8",
"name": "Frequency Average by Day",
"func": "msg.payload = `\n SELECT avg(freq) AS avg, \n count(freq) as cnt_freq, \n count(distinct location) as cnt_loc\n FROM mainsfrequency\n WHERE time >= current_date - interval '1 day' AND \n time < current_date AND\n valid = 1\n`\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 520,
"y": 140,
"wires": [
[
"8fc75864.aa5a18"
]
]
},
{
"id": "8fc75864.aa5a18",
"type": "postgres",
"z": "f6f2187d.f17ca8",
"postgresdb": "21801ad4.5fea0e",
"name": "mainscnt",
"output": true,
"perrow": false,
"rowspermsg": "1",
"return_on_error": false,
"limit_queries": "0",
"limit_by": "payload",
"limit_value": "1",
"limit_drop_intermediate": false,
"limit_drop_if_in_queue": false,
"outputs": true,
"x": 580,
"y": 180,
"wires": [
[
"bec353dd.5865c"
]
]
},
{
"id": "bec353dd.5865c",
"type": "function",
"z": "f6f2187d.f17ca8",
"name": "Prepare",
"func": "msg.result = msg.payload[0]\nmsg.result.avg = msg.result.avg.toFixed(3)\nmsg.result.cnt_freq = parseInt(msg.result.cnt_freq)\nmsg.result.cnt_loc = parseInt(msg.result.cnt_loc)\nmsg.result.pos_freq = msg.result.cnt_loc * 86400\nreturn msg",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 580,
"y": 220,
"wires": [
[
"cfef36ff.319b98"
]
]
},
{
"id": "eacf880.4329d78",
"type": "inject",
"z": "f6f2187d.f17ca8",
"name": "Once a day",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "30 09 * * *",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "true",
"payloadType": "bool",
"x": 570,
"y": 100,
"wires": [
[
"df8fb736.a86528"
]
]
},
{
"id": "cfef36ff.319b98",
"type": "template",
"z": "f6f2187d.f17ca8",
"name": "Format",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": "#netzfrequenz Yesterday, according to my measurement, the average mains frequency measured at {{result.cnt_loc}} locations and calculated from {{result.cnt_freq}} of {{result.pos_freq}} possible values was {{result.avg}} Hz. For details see https://grafana.mainscnt.eu \nPowered by #nodered, #timescaledb and #grafana.",
"output": "str",
"x": 580,
"y": 260,
"wires": [
[
"52acdab3.188644"
]
]
},
{
"id": "405ce4ce.49e93c",
"type": "twitter out",
"z": "f6f2187d.f17ca8",
"twitter": "3358c20a.fe8336",
"name": "Tweet",
"x": 590,
"y": 340,
"wires": []
},
{
"id": "52acdab3.188644",
"type": "jimp-image",
"z": "f6f2187d.f17ca8",
"name": "",
"data": "https://grafana.mainscnt.eu/render/d-solo/tg1-U6XGz/mainscnt?orgId=1&from=now-1d%2Fd&to=now-1d%2Fd&panelId=2&width=1000&height=1200&tz=UTC",
"dataType": "str",
"ret": "buf",
"parameter1": "",
"parameter1Type": "msg",
"parameter2": "",
"parameter2Type": "msg",
"parameter3": "",
"parameter3Type": "msg",
"parameter4": "",
"parameter4Type": "msg",
"parameter5": "",
"parameter5Type": "msg",
"parameter6": "",
"parameter6Type": "msg",
"parameter7": "",
"parameter7Type": "msg",
"parameter8": "",
"parameter8Type": "msg",
"sendProperty": "media",
"sendPropertyType": "msg",
"parameterCount": 0,
"jimpFunction": "none",
"selectedJimpFunction": {
"name": "none",
"fn": "none",
"description": "Just loads the image.",
"parameters": []
},
"x": 590,
"y": 300,
"wires": [
[
"405ce4ce.49e93c"
]
]
},
{
"id": "f6a43d0d.ebddc",
"type": "comment", "type": "comment",
"z": "f6f2187d.f17ca8", "z": "f6f2187d.f17ca8",
"name": "WARNING: please check you have started this container with a volume that is mounted to /data\\n otherwise any flow changes are lost when you redeploy or upgrade the container\\n (e.g. upgrade to a more recent node-red docker image).\\n If you are using named volumes you can ignore this warning.\\n Double click or see info side panel to learn how to start Node-RED in Docker to save your work", "name": "Missing Values",
"info": "\nTo start docker with a bind mount volume (-v option), for example:\n\n```\ndocker run -it -p 1880:1880 -v /home/user/node_red_data:/data --name mynodered nodered/node-red\n```\n\nwhere `/home/user/node_red_data` is a directory on your host machine where you want to store your flows.\n\nIf you do not do this then you can experiment and redploy flows, but if you restart or upgrade the container the flows will be disconnected and lost. \n\nThey will still exist in a hidden data volume, which can be recovered using standard docker techniques, but that is much more complex than just starting with a named volume as described above.", "info": "",
"x": 350, "x": 140,
"y": 80, "y": 60,
"wires": []
},
{
"id": "b73c5463.505428",
"type": "comment",
"z": "f6f2187d.f17ca8",
"name": "Daily Average Frequency Tweet",
"info": "",
"x": 510,
"y": 60,
"wires": []
},
{
"id": "56cef6df.8ecbe8",
"type": "inject",
"z": "f6f2187d.f17ca8",
"name": "Once a minute",
"props": [
{
"p": "payload"
}
],
"repeat": "60",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "true",
"payloadType": "bool",
"x": 920,
"y": 100,
"wires": [
[
"aad599a3.46ee48"
]
]
},
{
"id": "aad599a3.46ee48",
"type": "function",
"z": "f6f2187d.f17ca8",
"name": "Averaging Statement",
"func": "msg.payload = `\n SELECT avg(freq) AS mean\n FROM mainsfrequency\n WHERE valid = 1 AND \n time BETWEEN\n now() - interval '7 minutes' AND now() - interval '5 minutes'\n`\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 900,
"y": 140,
"wires": [
[
"efab1827.7067d8"
]
]
},
{
"id": "efab1827.7067d8",
"type": "postgres",
"z": "f6f2187d.f17ca8",
"postgresdb": "21801ad4.5fea0e",
"name": "mainscnt",
"output": true,
"perrow": false,
"rowspermsg": "1",
"return_on_error": false,
"limit_queries": "0",
"limit_by": "payload",
"limit_value": "1",
"limit_drop_intermediate": false,
"limit_drop_if_in_queue": false,
"outputs": true,
"x": 940,
"y": 180,
"wires": [
[
"27bc28c6.5d5b58"
]
]
},
{
"id": "27bc28c6.5d5b58",
"type": "function",
"z": "f6f2187d.f17ca8",
"name": "Extract (absolute) deviation",
"func": "let DESIRED_FREQUENCY = 50.0\nif (msg.payload.length > 0) {\n let v = msg.payload[0].mean\n node.status({fill:\"green\",shape:\"dot\",text:`${v}`})\n msg.payload = v\n return [ \n { 'payload': v.toFixed(3) }, \n { 'payload': (v - DESIRED_FREQUENCY).toFixed(3) }\n ]\n} else {\n node.status({fill:\"red\",shape:\"dot\",text:\"no data\"})\n node.error(\"no data\")\n return null\n}\n",
"outputs": 2,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 880,
"y": 220,
"wires": [
[
"5a6c06e7.dca6e8"
],
[
"5594701d.41a81",
"7c63eb69.6d1b24"
]
]
},
{
"id": "7c63eb69.6d1b24",
"type": "function",
"z": "f6f2187d.f17ca8",
"name": "Alarm",
"func": "let ALARM_THRESHOLD = 0.1\nlet RE_ARM_THRESHOLD = 0.075\nlet ARMED_STATE_KEY = 'ARMED_STATE'\nlet value = msg.payload\nlet absValue = Math.abs(value)\n\nif (! context.keys().includes(ARMED_STATE_KEY)) {\n context.set(ARMED_STATE_KEY, true)\n}\n\nlet armedState = context.get(ARMED_STATE_KEY)\nlet newEvent = false\nif (armedState) {\n if (absValue > ALARM_THRESHOLD) {\n armedState = false\n newEvent = true\n }\n} else {\n if (absValue < RE_ARM_THRESHOLD) {\n armedState = true\n newEvent = true\n }\n}\n\nnode.status(\n {\n fill: armedState ? \"green\" : \"red\",\n shape:\"dot\",\n text: armedState ? \"armed\" : \"alarm sent\"\n }\n)\n\ncontext.set(ARMED_STATE_KEY, armedState)\n\nreturn [ \n {'payload': armedState}, \n newEvent ?\n { \n 'payload': {\n 'value': value,\n 'state': armedState,\n 'high': ALARM_THRESHOLD,\n 'low': RE_ARM_THRESHOLD\n }\n } : null\n]",
"outputs": 2,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 950,
"y": 260,
"wires": [
[
"5701a2b2.9ca59c"
],
[
"85489c32.b49ff",
"33c01fa2.d6e88",
"13ebfe6b.4e6262"
]
]
},
{
"id": "5594701d.41a81",
"type": "ui_chart",
"z": "f6f2187d.f17ca8",
"name": "",
"group": "a4c5e228.94ac28",
"order": 1,
"width": "12",
"height": "9",
"label": "Deviation",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "",
"dot": true,
"ymin": "-0.15",
"ymax": "0.15",
"removeOlder": 1,
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": 0,
"useOneColor": false,
"useUTC": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"outputs": 1,
"useDifferentColor": false,
"x": 1140,
"y": 220,
"wires": [
[]
]
},
{
"id": "5a6c06e7.dca6e8",
"type": "ui_gauge",
"z": "f6f2187d.f17ca8",
"name": "",
"group": "b44c1611.48c72",
"order": 4,
"width": 0,
"height": 0,
"gtype": "gage",
"title": "Frequency",
"label": "Hz",
"format": "{{value}}",
"min": "49.85",
"max": "50.15",
"colors": [
"#ff0000",
"#00ff00",
"#ff0000"
],
"seg1": "49.9",
"seg2": "50.1",
"x": 1150,
"y": 180,
"wires": []
},
{
"id": "5701a2b2.9ca59c",
"type": "ui_switch",
"z": "f6f2187d.f17ca8",
"name": "",
"label": "Alarm",
"tooltip": "",
"group": "b44c1611.48c72",
"order": 1,
"width": 0,
"height": 0,
"passthru": true,
"decouple": "false",
"topic": "topic",
"topicType": "msg",
"style": "",
"onvalue": "true",
"onvalueType": "bool",
"onicon": "mood",
"oncolor": "green",
"offvalue": "false",
"offvalueType": "bool",
"officon": "mood_bad",
"offcolor": "red",
"animate": true,
"x": 1130,
"y": 260,
"wires": [
[]
]
},
{
"id": "88a1710c.11068",
"type": "twitter out",
"z": "f6f2187d.f17ca8",
"twitter": "3358c20a.fe8336",
"name": "MainsCntTweet",
"x": 920,
"y": 600,
"wires": []
},
{
"id": "c7c60031.05b2f",
"type": "pushover",
"z": "f6f2187d.f17ca8",
"name": "MainsCntAlarm",
"device": "",
"title": "",
"priority": 0,
"sound": "",
"url": "",
"url_title": "",
"html": false,
"x": 920,
"y": 560,
"wires": []
},
{
"id": "33c01fa2.d6e88",
"type": "function",
"z": "f6f2187d.f17ca8",
"name": "Prepare",
"func": "let info = `Deviation is ${msg.payload.value}, High mark is ${msg.payload.high}, Low mark is ${msg.payload.low}`\nlet status = msg.payload.state ? 'clear&armed' : 'alarm'\n\nlet output = \"Frequency Out of Range Alarm\\n\"\noutput += `Status: ${status}\\n`\noutput += `Absolute devivation ${info} Hz\\n`\noutput += \"https://shorty.mainscnt.eu/30m\"\nmsg.payload = output\nmsg.payloadLength = output.length\nreturn msg\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 940,
"y": 520,
"wires": [
[
"c7c60031.05b2f"
]
]
},
{
"id": "85489c32.b49ff",
"type": "function",
"z": "f6f2187d.f17ca8",
"name": "Alarm Event Statement",
"func": "msg.queryParameters = {\n 'info': `Deviation is ${msg.payload.value}, High mark is ${msg.payload.high}, Low mark is ${msg.payload.low}`,\n 'status': msg.payload.state ? 'clear&armed' : 'alarm'\n}\nmsg.payload = `\n INSERT INTO alarm_event_t\n (name, status, info)\n values('freq_out_of_range', $status, $info)\n`\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1190,
"y": 420,
"wires": [
[
"a392562a.918b58"
]
]
},
{
"id": "a392562a.918b58",
"type": "postgres",
"z": "f6f2187d.f17ca8",
"postgresdb": "21801ad4.5fea0e",
"name": "mainscnt",
"output": false,
"perrow": false,
"rowspermsg": "1",
"return_on_error": false,
"limit_queries": "0",
"limit_by": "payload",
"limit_value": "1",
"limit_drop_intermediate": false,
"limit_drop_if_in_queue": false,
"outputs": false,
"x": 1140,
"y": 460,
"wires": []
},
{
"id": "13ebfe6b.4e6262",
"type": "function",
"z": "f6f2187d.f17ca8",
"name": "EventCounter",
"func": "let cnt = context.get('EventCounter') || 0\ncnt += 1\ncontext.set('EventCounter', cnt)\nnode.status({fill:\"blue\",shape:\"dot\",text:`${cnt}`})\nmsg.payload = cnt\nreturn msg",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1160,
"y": 320,
"wires": [
[
"94287849.0ee7e8"
]
]
},
{
"id": "94287849.0ee7e8",
"type": "ui_text",
"z": "f6f2187d.f17ca8",
"group": "b44c1611.48c72",
"order": 2,
"width": 0,
"height": 0,
"name": "",
"label": "EventCnt",
"format": "{{msg.payload}}",
"layout": "row-spread",
"x": 1140,
"y": 360,
"wires": []
},
{
"id": "d7c897ea.2f7c78",
"type": "comment",
"z": "f6f2187d.f17ca8",
"name": "Frequency Out of Range Alarm",
"info": "",
"x": 870,
"y": 60,
"wires": []
},
{
"id": "f41aea58.180338",
"type": "mqtt in",
"z": "f6f2187d.f17ca8",
"name": "",
"topic": "MainsCnt/#",
"qos": "2",
"datatype": "json",
"broker": "48a55c40.d99ddc",
"nl": false,
"rap": true,
"rh": 0,
"x": 230,
"y": 540,
"wires": [
[
"776c7457.dfa35c"
]
]
},
{
"id": "f37a3ea0.54c97",
"type": "function",
"z": "f6f2187d.f17ca8",
"name": "Check and Prepare",
"func": "const LOWER_BOUND = 48.5\nconst UPPER_BOUND = 51.5\n\nlet valid = msg.incoming.Valid\nlet freq = msg.incoming.Freq\n\nif (freq < LOWER_BOUND || freq > UPPER_BOUND) {\n valid = false\n}\n\nmsg.queryParameters = {\n \"time\": msg.incoming.Time,\n \"freq\": freq,\n \"location\": msg.location,\n \"valid\": valid\n}\nmsg.payload = `\n INSERT INTO mainsfrequency\n (time, freq, location)\n VALUES($time, $freq, $location)\n`\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 210,
"y": 700,
"wires": [
[
"afbde352.0aaa6"
]
]
},
{
"id": "afbde352.0aaa6",
"type": "postgres",
"z": "f6f2187d.f17ca8",
"postgresdb": "21801ad4.5fea0e",
"name": "mainscnt",
"output": true,
"perrow": false,
"rowspermsg": "1",
"return_on_error": false,
"limit_queries": "0",
"limit_by": "payload",
"limit_value": "1",
"limit_drop_intermediate": false,
"limit_drop_if_in_queue": false,
"outputs": true,
"x": 240,
"y": 740,
"wires": [
[]
]
},
{
"id": "776c7457.dfa35c",
"type": "function",
"z": "f6f2187d.f17ca8",
"name": "FindDevice",
"func": "msg.incoming = msg.payload\nmsg.queryParameters = {\n \"deviceid\": msg.topic\n}\nmsg.payload = `\n SELECT location \n FROM device_t\n WHERE active = 't' AND\n deviceid = $deviceid\n`\nreturn msg",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 230,
"y": 580,
"wires": [
[
"b8c55ac0.707e08"
]
]
},
{
"id": "b8c55ac0.707e08",
"type": "postgres",
"z": "f6f2187d.f17ca8",
"postgresdb": "21801ad4.5fea0e",
"name": "mainscnt",
"output": true,
"perrow": false,
"rowspermsg": "1",
"return_on_error": false,
"limit_queries": "0",
"limit_by": "payload",
"limit_value": "1",
"limit_drop_intermediate": false,
"limit_drop_if_in_queue": false,
"outputs": true,
"x": 240,
"y": 620,
"wires": [
[
"46831f13.0e29d"
]
]
},
{
"id": "46831f13.0e29d",
"type": "function",
"z": "f6f2187d.f17ca8",
"name": "ExtractLocation",
"func": "if (msg.payload.length == 1) {\n msg.location = msg.payload[0].location\n return msg\n} else {\n return\n}",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 220,
"y": 660,
"wires": [
[
"f37a3ea0.54c97"
]
]
},
{
"id": "52a9852a.c634dc",
"type": "comment",
"z": "f6f2187d.f17ca8",
"name": "MQTT Ingress Processor",
"info": "",
"x": 190,
"y": 500,
"wires": [] "wires": []
} }
] ]

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,14 @@
{ {
"name": "nodered-mainscnt", "name": "nodered-mainscnt",
"description": "A Node-RED Project", "description": "Mainscnt - Ingress and Alarm Processor",
"version": "0.0.1", "version": "0.0.1",
"dependencies": {}, "dependencies": {
"node-red-contrib-image-tools": "2.0.2",
"node-red-contrib-re-postgres": "0.3.2",
"node-red-dashboard": "2.29.0",
"node-red-node-pushover": "0.0.24",
"node-red-node-twitter": "1.2.0"
},
"node-red": { "node-red": {
"settings": { "settings": {
"flowFile": "flows.json", "flowFile": "flows.json",