1444 lines
38 KiB
JSON
1444 lines
38 KiB
JSON
[
|
|
{
|
|
"id": "tab1",
|
|
"type": "tab",
|
|
"label": "Dashboard Demo",
|
|
"disabled": false,
|
|
"info": ""
|
|
},
|
|
{
|
|
"id": "5f31529b3e749ebe",
|
|
"type": "mqtt in",
|
|
"z": "tab1",
|
|
"name": "MQTT Sensor",
|
|
"topic": "iot/sensor",
|
|
"qos": "0",
|
|
"datatype": "auto",
|
|
"broker": "mqtt_broker_local",
|
|
"nl": false,
|
|
"rap": true,
|
|
"rh": 0,
|
|
"inputs": 0,
|
|
"x": 300,
|
|
"y": 580,
|
|
"wires": [
|
|
[
|
|
"e81e5db8c5529bb0"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "e81e5db8c5529bb0",
|
|
"type": "json",
|
|
"z": "tab1",
|
|
"name": "Parse JSON",
|
|
"property": "payload",
|
|
"action": "",
|
|
"pretty": false,
|
|
"x": 480,
|
|
"y": 580,
|
|
"wires": [
|
|
[
|
|
"a4575ed03e736231",
|
|
"94dd8dde94285a13"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "37d04d285e6d7864",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": " Get Data Filter",
|
|
"func": "// Simpan pilihan ke flow untuk digunakan tombol ambil data\nflow.set(\"sensor_selected\", msg.payload);\nreturn null;\n",
|
|
"outputs": 1,
|
|
"timeout": "",
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 540,
|
|
"y": 780,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "a4575ed03e736231",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "Split Sensor Data",
|
|
"func": "return [\n { payload: msg.payload.weight },\n { payload: msg.payload.humidity },\n { payload: msg.payload.soil }\n];",
|
|
"outputs": 3,
|
|
"timeout": "",
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 690,
|
|
"y": 560,
|
|
"wires": [
|
|
[
|
|
"1815f02556163f1d",
|
|
"6452681ddc0cd6cd"
|
|
],
|
|
[
|
|
"edf401a2960b5562",
|
|
"22b8f2858da8ce95"
|
|
],
|
|
[
|
|
"8992134a9099bffa",
|
|
"e03f9616d12ff1df"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "5a0b35725a51d4dc",
|
|
"type": "sqlite",
|
|
"z": "tab1",
|
|
"mydb": "sqlite_local",
|
|
"sqlquery": "msg.topic",
|
|
"sql": "",
|
|
"name": "Simpan ke SQLite",
|
|
"x": 810,
|
|
"y": 700,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "1815f02556163f1d",
|
|
"type": "ui_gauge",
|
|
"z": "tab1",
|
|
"name": "Weight",
|
|
"group": "ui_group_main",
|
|
"order": 2,
|
|
"width": 6,
|
|
"height": 0,
|
|
"gtype": "gage",
|
|
"title": "Weight (g)",
|
|
"label": "g",
|
|
"format": "{{value}}",
|
|
"min": 0,
|
|
"max": "200",
|
|
"colors": [
|
|
"#00b500",
|
|
"#e6e600",
|
|
"#ca3838"
|
|
],
|
|
"seg1": "300",
|
|
"seg2": "700",
|
|
"diff": false,
|
|
"className": "",
|
|
"x": 890,
|
|
"y": 520,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "edf401a2960b5562",
|
|
"type": "ui_gauge",
|
|
"z": "tab1",
|
|
"name": "Humidity",
|
|
"group": "ui_group_main",
|
|
"order": 1,
|
|
"width": 6,
|
|
"height": 0,
|
|
"gtype": "gage",
|
|
"title": "Humidity (%)",
|
|
"label": "%",
|
|
"format": "{{value}}",
|
|
"min": 0,
|
|
"max": "100",
|
|
"colors": [
|
|
"#00b500",
|
|
"#e6e600",
|
|
"#ca3838"
|
|
],
|
|
"seg1": "40",
|
|
"seg2": "70",
|
|
"diff": false,
|
|
"className": "",
|
|
"x": 900,
|
|
"y": 560,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "8992134a9099bffa",
|
|
"type": "ui_gauge",
|
|
"z": "tab1",
|
|
"name": "Soil Moisture",
|
|
"group": "ui_group_main",
|
|
"order": 3,
|
|
"width": 6,
|
|
"height": 0,
|
|
"gtype": "gage",
|
|
"title": "Soil Moisture",
|
|
"label": "%",
|
|
"format": "{{value}}",
|
|
"min": 0,
|
|
"max": 100,
|
|
"colors": [
|
|
"#00b500",
|
|
"#e6e600",
|
|
"#ca3838"
|
|
],
|
|
"seg1": "30",
|
|
"seg2": "60",
|
|
"diff": false,
|
|
"className": "",
|
|
"x": 910,
|
|
"y": 600,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "6452681ddc0cd6cd",
|
|
"type": "ui_chart",
|
|
"z": "tab1",
|
|
"name": "Chart Weight",
|
|
"group": "ui_group_main",
|
|
"order": 5,
|
|
"width": 6,
|
|
"height": 0,
|
|
"label": "Weight History",
|
|
"chartType": "line",
|
|
"legend": "false",
|
|
"xformat": "HH:mm:ss",
|
|
"interpolate": "linear",
|
|
"nodata": "Waiting...",
|
|
"dot": false,
|
|
"ymin": "0",
|
|
"ymax": "1000",
|
|
"removeOlder": "3",
|
|
"removeOlderPoints": "100",
|
|
"removeOlderUnit": "60",
|
|
"cutout": 0,
|
|
"useOneColor": false,
|
|
"useUTC": false,
|
|
"colors": [
|
|
"#1f77b4",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000"
|
|
],
|
|
"outputs": 1,
|
|
"useDifferentColor": false,
|
|
"className": "",
|
|
"x": 1110,
|
|
"y": 520,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "22b8f2858da8ce95",
|
|
"type": "ui_chart",
|
|
"z": "tab1",
|
|
"name": "Chart Humidity",
|
|
"group": "ui_group_main",
|
|
"order": 4,
|
|
"width": 6,
|
|
"height": 0,
|
|
"label": "Humidity History",
|
|
"chartType": "line",
|
|
"legend": "false",
|
|
"xformat": "HH:mm:ss",
|
|
"interpolate": "linear",
|
|
"nodata": "Waiting...",
|
|
"dot": false,
|
|
"ymin": "0",
|
|
"ymax": "100",
|
|
"removeOlder": "3",
|
|
"removeOlderPoints": "100",
|
|
"removeOlderUnit": "60",
|
|
"cutout": 0,
|
|
"useOneColor": false,
|
|
"useUTC": false,
|
|
"colors": [
|
|
"#ff7f0e",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000"
|
|
],
|
|
"outputs": 1,
|
|
"useDifferentColor": false,
|
|
"className": "",
|
|
"x": 1120,
|
|
"y": 560,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "e03f9616d12ff1df",
|
|
"type": "ui_chart",
|
|
"z": "tab1",
|
|
"name": "Chart Soil",
|
|
"group": "ui_group_main",
|
|
"order": 6,
|
|
"width": 6,
|
|
"height": 0,
|
|
"label": "Soil Moisture History",
|
|
"chartType": "line",
|
|
"legend": "false",
|
|
"xformat": "HH:mm:ss",
|
|
"interpolate": "linear",
|
|
"nodata": "Waiting...",
|
|
"dot": false,
|
|
"ymin": "0",
|
|
"ymax": "100",
|
|
"removeOlder": "3",
|
|
"removeOlderPoints": "100",
|
|
"removeOlderUnit": "60",
|
|
"cutout": 0,
|
|
"useOneColor": false,
|
|
"useUTC": false,
|
|
"colors": [
|
|
"#2ca02c",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000",
|
|
"#000000"
|
|
],
|
|
"outputs": 1,
|
|
"useDifferentColor": false,
|
|
"className": "",
|
|
"x": 1130,
|
|
"y": 600,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "d3167a81e47894f4",
|
|
"type": "cronplus",
|
|
"z": "tab1",
|
|
"name": "Cron Setiap 10 Menit",
|
|
"outputField": "payload",
|
|
"timeZone": "",
|
|
"storeName": "",
|
|
"commandResponseMsgOutput": "output1",
|
|
"defaultLocation": "",
|
|
"defaultLocationType": "default",
|
|
"outputs": 1,
|
|
"options": [
|
|
{
|
|
"name": "cron1menit",
|
|
"topic": "filter/weight",
|
|
"payloadType": "default",
|
|
"payload": "",
|
|
"expressionType": "cron",
|
|
"expression": "0 */10 * * * *",
|
|
"location": "",
|
|
"offset": "0",
|
|
"solarType": "all",
|
|
"solarEvents": "sunrise,sunset"
|
|
}
|
|
],
|
|
"x": 340,
|
|
"y": 700,
|
|
"wires": [
|
|
[
|
|
"1b56edf14dd48a3e"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "1b56edf14dd48a3e",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "Ambil dan Simpan DB",
|
|
"func": "var data = flow.get(\"last_sensor_data\");\n\nif (data) {\n msg.topic = `INSERT INTO sensor_data (weight, humidity, soil, timestamp) \n VALUES (${data.weight}, ${data.humidity}, ${data.soil}, datetime('now', 'localtime'))`;\n return msg;\n} else {\n return null;\n}\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 580,
|
|
"y": 700,
|
|
"wires": [
|
|
[
|
|
"5a0b35725a51d4dc"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "94dd8dde94285a13",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "Simpan data di Flow",
|
|
"func": "flow.set(\"last_sensor_data\", msg.payload);\nreturn null;\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 640,
|
|
"y": 640,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "bbbaab907e1d9ba1",
|
|
"type": "ui_dropdown",
|
|
"z": "tab1",
|
|
"name": "",
|
|
"label": "Pilih Data Sensor ",
|
|
"tooltip": "",
|
|
"place": "Select option",
|
|
"group": "a5d4d4b9.0e5d58",
|
|
"order": 1,
|
|
"width": 0,
|
|
"height": 0,
|
|
"passthru": true,
|
|
"multiple": false,
|
|
"options": [
|
|
{
|
|
"label": "Weight",
|
|
"value": "weight",
|
|
"type": "str"
|
|
},
|
|
{
|
|
"label": "Humidity",
|
|
"value": "humidity",
|
|
"type": "str"
|
|
},
|
|
{
|
|
"label": "Soil",
|
|
"value": "soil",
|
|
"type": "str"
|
|
}
|
|
],
|
|
"payload": "",
|
|
"topic": "topic",
|
|
"topicType": "msg",
|
|
"className": "",
|
|
"x": 330,
|
|
"y": 780,
|
|
"wires": [
|
|
[
|
|
"37d04d285e6d7864"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "f302ee7fa549388d",
|
|
"type": "ui_button",
|
|
"z": "tab1",
|
|
"name": "Ambil Data",
|
|
"group": "a5d4d4b9.0e5d58",
|
|
"order": 5,
|
|
"width": 0,
|
|
"height": 0,
|
|
"passthru": false,
|
|
"label": "Lihat Data 1 Jam Terakhir",
|
|
"tooltip": "",
|
|
"color": "",
|
|
"bgcolor": "",
|
|
"className": "",
|
|
"icon": "",
|
|
"payload": "",
|
|
"payloadType": "str",
|
|
"topic": "topic",
|
|
"topicType": "msg",
|
|
"x": 330,
|
|
"y": 840,
|
|
"wires": [
|
|
[
|
|
"9dea1ff0914d9df1"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "9dea1ff0914d9df1",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "Ambil Data Sensor",
|
|
"func": "let sensor = flow.get(\"sensor_selected\") || \"weight\"; // default berat\nmsg.topic = `\n SELECT timestamp, ${sensor} AS value\n FROM sensor_data\n WHERE timestamp >= datetime('now', '-1 hour', 'localtime')\n ORDER BY timestamp ASC\n`;\nreturn msg;\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 530,
|
|
"y": 840,
|
|
"wires": [
|
|
[
|
|
"b3c205b6f30ee3a1"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "9c2ff6f5414057d6",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "Ubah Format Chart",
|
|
"func": "let labels = [];\nlet values = [];\n\nmsg.payload.forEach(row => {\n labels.push(row.timestamp);\n values.push(row.value);\n});\n\nreturn {\n payload: [{\n series: [\"Sensor\"],\n data: [values],\n labels: labels\n }]\n};\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 910,
|
|
"y": 800,
|
|
"wires": [
|
|
[
|
|
"a1e5f5cd0e18215a"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "b3c205b6f30ee3a1",
|
|
"type": "sqlite",
|
|
"z": "tab1",
|
|
"mydb": "sqlite_local",
|
|
"sqlquery": "msg.topic",
|
|
"sql": "",
|
|
"name": "Ambil Data",
|
|
"x": 730,
|
|
"y": 840,
|
|
"wires": [
|
|
[
|
|
"9c2ff6f5414057d6",
|
|
"f29389be4bd7f771"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "a1e5f5cd0e18215a",
|
|
"type": "ui_chart",
|
|
"z": "tab1",
|
|
"name": "Chart 1 Jam Terakhir",
|
|
"group": "a5d4d4b9.0e5d58",
|
|
"order": 3,
|
|
"width": "9",
|
|
"height": "9",
|
|
"label": "chart",
|
|
"chartType": "line",
|
|
"legend": "false",
|
|
"xformat": "HH:mm:ss",
|
|
"interpolate": "linear",
|
|
"nodata": "",
|
|
"dot": false,
|
|
"ymin": "",
|
|
"ymax": "",
|
|
"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,
|
|
"className": "",
|
|
"x": 1140,
|
|
"y": 800,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "f29389be4bd7f771",
|
|
"type": "ui_table",
|
|
"z": "tab1",
|
|
"group": "a5d4d4b9.0e5d58",
|
|
"name": "Tabel Data Sensor 1 Jam",
|
|
"order": 6,
|
|
"width": "9",
|
|
"height": "9",
|
|
"columns": [],
|
|
"outputs": 0,
|
|
"cts": false,
|
|
"x": 930,
|
|
"y": 880,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "1faca8d668b6c953",
|
|
"type": "mqtt in",
|
|
"z": "tab1",
|
|
"name": "MQTT IN",
|
|
"topic": "iot/sensor",
|
|
"qos": "2",
|
|
"datatype": "auto-detect",
|
|
"broker": "mqtt_broker_local",
|
|
"nl": false,
|
|
"rap": true,
|
|
"rh": 0,
|
|
"inputs": 0,
|
|
"x": 260,
|
|
"y": 920,
|
|
"wires": [
|
|
[
|
|
"43e20a522799a074"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "43e20a522799a074",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "Logika Otomasi",
|
|
"func": "let auto = flow.get(\"autoMode\") || \"OFF\";\nlet min = flow.get(\"minThreshold\") || 60;\nlet max = flow.get(\"maxThreshold\") || 90;\nlet humidity = msg.payload.humidity;\n\nif (auto === \"ON\") {\n if (humidity > max || (humidity <= max && humidity >= min)) {\n return {\n payload: {\n kipas: \"ON\",\n ptc: \"ON\"\n }\n };\n } else if (humidity < min) {\n return {\n payload: {\n kipas: \"OFF\",\n ptc: \"OFF\"\n }\n };\n }\n}\n\nreturn null; // Auto OFF → ESP32 logika lokal\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 500,
|
|
"y": 980,
|
|
"wires": [
|
|
[
|
|
"5c1f51279e899535"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "5c1f51279e899535",
|
|
"type": "mqtt out",
|
|
"z": "tab1",
|
|
"name": "MQTT OUT",
|
|
"topic": "iot/control/relay",
|
|
"qos": "0",
|
|
"retain": "true",
|
|
"respTopic": "",
|
|
"contentType": "",
|
|
"userProps": "",
|
|
"correl": "",
|
|
"expiry": "",
|
|
"broker": "mqtt_broker_local",
|
|
"x": 730,
|
|
"y": 920,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "d89d2771a3657743",
|
|
"type": "ui_switch",
|
|
"z": "tab1",
|
|
"name": "Auto Mode",
|
|
"label": "Auto Mode",
|
|
"tooltip": "",
|
|
"group": "077642f35af224dd",
|
|
"order": 1,
|
|
"width": 0,
|
|
"height": 0,
|
|
"passthru": true,
|
|
"decouple": "false",
|
|
"topic": "auto",
|
|
"topicType": "str",
|
|
"style": "",
|
|
"onvalue": "ON",
|
|
"onvalueType": "str",
|
|
"onicon": "",
|
|
"oncolor": "",
|
|
"offvalue": "OFF",
|
|
"offvalueType": "str",
|
|
"officon": "",
|
|
"offcolor": "",
|
|
"animate": false,
|
|
"className": "",
|
|
"x": 270,
|
|
"y": 980,
|
|
"wires": [
|
|
[
|
|
"e6969d414614df2a"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "e6969d414614df2a",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "Set Auto Mode",
|
|
"func": "flow.set(\"autoMode\", msg.payload);\n\nlet mode = msg.payload;\n\nif (mode === \"ON\") {\n let min = flow.get(\"minThreshold\") || 60;\n let max = flow.get(\"maxThreshold\") || 90;\n\n return {\n payload: {\n auto: \"ON\",\n min: min,\n max: max\n }\n };\n} else {\n return {\n payload: {\n auto: \"OFF\"\n }\n };\n}\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 520,
|
|
"y": 1040,
|
|
"wires": [
|
|
[
|
|
"c648c08be1a9d688"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "c648c08be1a9d688",
|
|
"type": "mqtt out",
|
|
"z": "tab1",
|
|
"name": "MQTT OUT",
|
|
"topic": "iot/control/relay",
|
|
"qos": "0",
|
|
"retain": "true",
|
|
"respTopic": "",
|
|
"contentType": "",
|
|
"userProps": "",
|
|
"correl": "",
|
|
"expiry": "",
|
|
"broker": "mqtt_broker_local",
|
|
"x": 730,
|
|
"y": 980,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "300d03d320030023",
|
|
"type": "ui_numeric",
|
|
"z": "tab1",
|
|
"name": "",
|
|
"label": "Min Threshold",
|
|
"tooltip": "",
|
|
"group": "077642f35af224dd",
|
|
"order": 2,
|
|
"width": 0,
|
|
"height": 0,
|
|
"wrap": false,
|
|
"passthru": true,
|
|
"topic": "min",
|
|
"topicType": "str",
|
|
"format": "{{value}}",
|
|
"min": 0,
|
|
"max": "100",
|
|
"step": 1,
|
|
"className": "",
|
|
"x": 280,
|
|
"y": 1040,
|
|
"wires": [
|
|
[
|
|
"176a870347715cfa"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "1157d77839be828e",
|
|
"type": "ui_numeric",
|
|
"z": "tab1",
|
|
"name": "Max Threshold",
|
|
"label": "Max Threshold",
|
|
"tooltip": "",
|
|
"group": "077642f35af224dd",
|
|
"order": 3,
|
|
"width": 0,
|
|
"height": 0,
|
|
"wrap": false,
|
|
"passthru": true,
|
|
"topic": "max",
|
|
"topicType": "str",
|
|
"format": "{{value}}",
|
|
"min": 0,
|
|
"max": "100",
|
|
"step": 1,
|
|
"className": "",
|
|
"x": 280,
|
|
"y": 1100,
|
|
"wires": [
|
|
[
|
|
"bcea903c811a2674"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "176a870347715cfa",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "MIn Threshold",
|
|
"func": "flow.set(\"minThreshold\", msg.payload);\nreturn null;\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 520,
|
|
"y": 1100,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "bcea903c811a2674",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "Max Threshold",
|
|
"func": "flow.set(\"maxThreshold\", msg.payload);\nreturn null;\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 500,
|
|
"y": 1160,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "eabf72d94dda646b",
|
|
"type": "ui_form",
|
|
"z": "tab1",
|
|
"name": "",
|
|
"label": "Input Tanggal untuk Cek Tabel Hasil Sensor",
|
|
"group": "a5d4d4b9.0e5d58",
|
|
"order": 10,
|
|
"width": 0,
|
|
"height": 0,
|
|
"options": [
|
|
{
|
|
"label": "StartDate",
|
|
"value": "StartDate",
|
|
"type": "date",
|
|
"required": true,
|
|
"rows": null
|
|
},
|
|
{
|
|
"label": "EndDate",
|
|
"value": "EndDate",
|
|
"type": "date",
|
|
"required": true,
|
|
"rows": null
|
|
}
|
|
],
|
|
"formValue": {
|
|
"StartDate": "",
|
|
"EndDate": ""
|
|
},
|
|
"payload": "",
|
|
"submit": "Load Data",
|
|
"cancel": "Cancel",
|
|
"topic": "topic",
|
|
"topicType": "msg",
|
|
"splitLayout": "",
|
|
"className": "",
|
|
"x": 890,
|
|
"y": 1080,
|
|
"wires": [
|
|
[
|
|
"a924537ad40c9a35"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "a924537ad40c9a35",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "function 1",
|
|
"func": "var start = msg.payload.StartDate;\nvar end = msg.payload.EndDate;\n\nmsg.topic = `SELECT ID, timestamp, weight, humidity, soil\n FROM sensor_data\n WHERE timestamp BETWEEN '${start}' AND '${end}'\n ORDER BY timestamp ASC`;\n\nreturn msg;\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 1180,
|
|
"y": 1080,
|
|
"wires": [
|
|
[
|
|
"94ab216e7402fe83"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "94ab216e7402fe83",
|
|
"type": "sqlite",
|
|
"z": "tab1",
|
|
"mydb": "sqlite_local",
|
|
"sqlquery": "msg.topic",
|
|
"sql": "",
|
|
"name": "",
|
|
"x": 980,
|
|
"y": 1160,
|
|
"wires": [
|
|
[
|
|
"06b6b6875d1ef97f",
|
|
"009cc5fdaef1059b"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "06b6b6875d1ef97f",
|
|
"type": "ui_table",
|
|
"z": "tab1",
|
|
"group": "a5d4d4b9.0e5d58",
|
|
"name": "",
|
|
"order": 11,
|
|
"width": "18",
|
|
"height": "9",
|
|
"columns": [],
|
|
"outputs": 0,
|
|
"cts": false,
|
|
"x": 1310,
|
|
"y": 1160,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "0e1cb4193c91927d",
|
|
"type": "ui_chart",
|
|
"z": "tab1",
|
|
"name": "",
|
|
"group": "",
|
|
"order": 12,
|
|
"width": "9",
|
|
"height": "9",
|
|
"label": "Grafik Hasil Sensor",
|
|
"chartType": "line",
|
|
"legend": "true",
|
|
"xformat": "HH:mm",
|
|
"interpolate": "linear",
|
|
"nodata": "",
|
|
"dot": false,
|
|
"ymin": "",
|
|
"ymax": "",
|
|
"removeOlder": "24",
|
|
"removeOlderPoints": "",
|
|
"removeOlderUnit": "3600",
|
|
"cutout": 0,
|
|
"useOneColor": false,
|
|
"useUTC": false,
|
|
"colors": [
|
|
"#1f77b4",
|
|
"#aec7e8",
|
|
"#ff7f0e",
|
|
"#2ca02c",
|
|
"#98df8a",
|
|
"#d62728",
|
|
"#ff9896",
|
|
"#9467bd",
|
|
"#c5b0d5"
|
|
],
|
|
"outputs": 1,
|
|
"useDifferentColor": false,
|
|
"className": "",
|
|
"x": 3730,
|
|
"y": 2780,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "d40f0c435b9f0739",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "function 2",
|
|
"func": "let hasil = [];\nlet terakhirJam = null;\n\nfor (let row of msg.payload) {\n let waktu = new Date(row.timestamp);\n let jam = waktu.getHours();\n\n if (jam !== terakhirJam) {\n let t = waktu.getTime();\n hasil.push(\n { topic: \"weight\", payload: row.weight, x: t },\n { topic: \"humidity\", payload: row.humidity, x: t },\n { topic: \"soil\", payload: row.soil, x: t }\n );\n terakhirJam = jam;\n }\n}\n\nreturn [hasil];\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 3740,
|
|
"y": 2620,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "009cc5fdaef1059b",
|
|
"type": "debug",
|
|
"z": "tab1",
|
|
"name": "debug 1",
|
|
"active": true,
|
|
"tosidebar": true,
|
|
"console": true,
|
|
"tostatus": true,
|
|
"complete": "payload",
|
|
"targetType": "msg",
|
|
"statusVal": "payload",
|
|
"statusType": "auto",
|
|
"x": 1010,
|
|
"y": 1220,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "44417d6d5c88b067",
|
|
"type": "debug",
|
|
"z": "tab1",
|
|
"name": "debug 2",
|
|
"active": true,
|
|
"tosidebar": true,
|
|
"console": false,
|
|
"tostatus": false,
|
|
"complete": "payload",
|
|
"targetType": "msg",
|
|
"statusVal": "",
|
|
"statusType": "auto",
|
|
"x": 3900,
|
|
"y": 2640,
|
|
"wires": []
|
|
},
|
|
{
|
|
"id": "e24142f27563c8f7",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "function 3",
|
|
"func": "let hasil = [];\n\nfor (let row of msg.payload) {\n let waktu = new Date(row.timestamp);\n let t = waktu.getTime(); // ubah ke milidetik\n\n hasil.push(\n { topic: \"weight\", payload: row.weight, x: t },\n { topic: \"humidity\", payload: row.humidity, x: t },\n { topic: \"soil\", payload: row.soil, x: t }\n );\n}\n\nreturn [hasil];\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 3740,
|
|
"y": 2680,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "2274b4168fa225ab",
|
|
"type": "ui_button",
|
|
"z": "tab1",
|
|
"name": "Clear Chart",
|
|
"group": "",
|
|
"order": 13,
|
|
"width": 0,
|
|
"height": 0,
|
|
"passthru": false,
|
|
"label": "Clear Chart",
|
|
"tooltip": "",
|
|
"color": "",
|
|
"bgcolor": "",
|
|
"className": "",
|
|
"icon": "",
|
|
"payload": "",
|
|
"payloadType": "str",
|
|
"topic": "topic",
|
|
"topicType": "msg",
|
|
"x": 3510,
|
|
"y": 2920,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "f6a49940e4446c3e",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "function 6",
|
|
"func": "return [\n { topic: \"weight\", payload: [] },\n { topic: \"humidity\", payload: [] },\n { topic: \"soil\", payload: [] }\n];\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 3520,
|
|
"y": 2840,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "21536e5562e29615",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "filter 2jam",
|
|
"func": "let hasil = [];\nlet terakhirWaktu = null;\nconst intervalMs = 60 * 60 * 1000; // 1 jam = 3600000 ms\n\nfor (let row of msg.payload) {\n let waktu = new Date(row.timestamp);\n if (isNaN(waktu.getTime())) continue;\n\n let t = waktu.getTime();\n\n // Ambil hanya satu data per jam\n if (terakhirWaktu === null || (t - terakhirWaktu) >= intervalMs) {\n hasil.push(\n { topic: \"weight\", payload: row.weight, x: t },\n { topic: \"humidity\", payload: row.humidity, x: t },\n { topic: \"soil\", payload: row.soil, x: t }\n );\n terakhirWaktu = t;\n }\n}\n\nreturn [hasil];\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 3520,
|
|
"y": 2780,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "c6422797ed00af54",
|
|
"type": "ui_form",
|
|
"z": "tab1",
|
|
"name": "",
|
|
"label": "Input Waktu untuk Hitung Durasi Nyala Alat",
|
|
"group": "cfa831704ecb774e",
|
|
"order": 1,
|
|
"width": 0,
|
|
"height": 0,
|
|
"options": [
|
|
{
|
|
"label": "Waktu Nyala Awal",
|
|
"value": "start_date",
|
|
"type": "date",
|
|
"required": true,
|
|
"rows": null
|
|
},
|
|
{
|
|
"label": "Waktu Nyala Akhir",
|
|
"value": "end_date",
|
|
"type": "date",
|
|
"required": true,
|
|
"rows": null
|
|
}
|
|
],
|
|
"formValue": {
|
|
"start_date": "",
|
|
"end_date": ""
|
|
},
|
|
"payload": "",
|
|
"submit": "submit",
|
|
"cancel": "cancel",
|
|
"topic": "topic",
|
|
"topicType": "msg",
|
|
"splitLayout": "",
|
|
"className": "",
|
|
"x": 310,
|
|
"y": 1260,
|
|
"wires": [
|
|
[
|
|
"6ab3a01515f3839f"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "6ab3a01515f3839f",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "query database cari waktu",
|
|
"func": "let start = msg.payload.start_date;\nlet end = msg.payload.end_date;\n\nmsg.topic = `\n SELECT timestamp, weight FROM sensor_data \n WHERE timestamp BETWEEN '${start} 00:00:00' AND '${end} 23:59:59' \n ORDER BY timestamp ASC;\n`;\nreturn msg;\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 670,
|
|
"y": 1260,
|
|
"wires": [
|
|
[
|
|
"cf6c9c8b56973d03"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "cf6c9c8b56973d03",
|
|
"type": "sqlite",
|
|
"z": "tab1",
|
|
"mydb": "sqlite_local",
|
|
"sqlquery": "msg.topic",
|
|
"sql": "",
|
|
"name": "",
|
|
"x": 500,
|
|
"y": 1340,
|
|
"wires": [
|
|
[
|
|
"6d4b3c89d262ec1b"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "6d4b3c89d262ec1b",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "hitung waktu",
|
|
"func": "let data = msg.payload;\n\nif (!Array.isArray(data) || data.length < 2) {\n msg.payload = \"Data tidak cukup untuk menghitung durasi pengeringan.\";\n return msg;\n}\n\n// Ganti spasi jadi T agar bisa dibaca Date()\nlet waktu1 = new Date(data[0].timestamp.replace(\" \", \"T\"));\nlet waktu2 = new Date(data[data.length - 1].timestamp.replace(\" \", \"T\"));\n\nif (isNaN(waktu1) || isNaN(waktu2)) {\n msg.payload = \"Format waktu tidak valid dari database.\";\n return msg;\n}\n\nlet selisihMs = Math.abs(waktu2 - waktu1);\nlet jam = Math.floor(selisihMs / (1000 * 60 * 60));\nlet menit = Math.floor((selisihMs % (1000 * 60 * 60)) / (1000 * 60));\n\nmsg.payload = `Durasi Lama Menyala Alat: ${jam} jam ${menit} menit`;\nreturn msg;\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 2,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 330,
|
|
"y": 1420,
|
|
"wires": [
|
|
[
|
|
"d7165d9095fce54c"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "d7165d9095fce54c",
|
|
"type": "ui_text_input",
|
|
"z": "tab1",
|
|
"name": "Durasi Alat Menyala",
|
|
"label": "",
|
|
"tooltip": "",
|
|
"group": "cfa831704ecb774e",
|
|
"order": 2,
|
|
"width": "14",
|
|
"height": "2",
|
|
"passthru": true,
|
|
"mode": "text",
|
|
"delay": 300,
|
|
"topic": "topic",
|
|
"sendOnBlur": true,
|
|
"className": "",
|
|
"topicType": "msg",
|
|
"x": 600,
|
|
"y": 1420,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "1d392868362ac611",
|
|
"type": "ui_form",
|
|
"z": "tab1",
|
|
"name": "",
|
|
"label": "Input Berat Awal dan Akhir",
|
|
"group": "cfa831704ecb774e",
|
|
"order": 3,
|
|
"width": 0,
|
|
"height": 0,
|
|
"options": [
|
|
{
|
|
"label": "Berat Awal",
|
|
"value": "berat_awal",
|
|
"type": "number",
|
|
"required": true,
|
|
"rows": null
|
|
},
|
|
{
|
|
"label": "Berat Akhir",
|
|
"value": "berat_akhir",
|
|
"type": "number",
|
|
"required": true,
|
|
"rows": null
|
|
}
|
|
],
|
|
"formValue": {
|
|
"berat_awal": "",
|
|
"berat_akhir": ""
|
|
},
|
|
"payload": "",
|
|
"submit": "submit",
|
|
"cancel": "cancel",
|
|
"topic": "topic",
|
|
"topicType": "msg",
|
|
"splitLayout": "",
|
|
"className": "",
|
|
"x": 360,
|
|
"y": 1500,
|
|
"wires": [
|
|
[
|
|
"f9c308cbef39eb24"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "f9c308cbef39eb24",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "query database cari waktu",
|
|
"func": "let berat_awal = msg.payload.berat_awal;\nlet berat_akhir = msg.payload.berat_akhir;\n\nmsg.topic = `\n SELECT timestamp, weight \n FROM sensor_data \n WHERE weight IN (${berat_awal}, ${berat_akhir})\n ORDER BY timestamp ASC;\n`;\nreturn msg;\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 0,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 670,
|
|
"y": 1500,
|
|
"wires": [
|
|
[
|
|
"36ad9d1719f51b71"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "36ad9d1719f51b71",
|
|
"type": "sqlite",
|
|
"z": "tab1",
|
|
"mydb": "sqlite_local",
|
|
"sqlquery": "msg.topic",
|
|
"sql": "",
|
|
"name": "",
|
|
"x": 500,
|
|
"y": 1580,
|
|
"wires": [
|
|
[
|
|
"4dc76c949c967437"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "4dc76c949c967437",
|
|
"type": "function",
|
|
"z": "tab1",
|
|
"name": "hitung waktu",
|
|
"func": "let data = msg.payload;\n\nif (data.length < 2) {\n msg.payload = \"Tidak ditemukan dua titik berat dalam database.\";\n return msg;\n}\n\n// Ubah ke format Date (pastikan format timestamp dari DB: 'YYYY-MM-DD HH:MM:SS')\nlet waktu1 = new Date(data[0].timestamp.replace(\" \", \"T\"));\nlet waktu2 = new Date(data[1].timestamp.replace(\" \", \"T\"));\n\nif (isNaN(waktu1) || isNaN(waktu2)) {\n msg.payload = \"Waktu tidak valid.\";\n return msg;\n}\n\nlet selisihMs = Math.abs(waktu2 - waktu1);\nlet jam = Math.floor(selisihMs / (1000 * 60 * 60));\nlet menit = Math.floor((selisihMs % (1000 * 60 * 60)) / (1000 * 60));\n\nmsg.payload = `Durasi Lama Proses Pengeringan: ${jam} jam ${menit} menit`;\nreturn msg;\n",
|
|
"outputs": 1,
|
|
"timeout": 0,
|
|
"noerr": 2,
|
|
"initialize": "",
|
|
"finalize": "",
|
|
"libs": [],
|
|
"x": 330,
|
|
"y": 1660,
|
|
"wires": [
|
|
[
|
|
"2ddc72cd58c4a8b2"
|
|
]
|
|
]
|
|
},
|
|
{
|
|
"id": "2ddc72cd58c4a8b2",
|
|
"type": "ui_text_input",
|
|
"z": "tab1",
|
|
"name": "Durasi Pengering",
|
|
"label": "",
|
|
"tooltip": "",
|
|
"group": "cfa831704ecb774e",
|
|
"order": 4,
|
|
"width": "14",
|
|
"height": "2",
|
|
"passthru": true,
|
|
"mode": "text",
|
|
"delay": 300,
|
|
"topic": "topic",
|
|
"sendOnBlur": true,
|
|
"className": "",
|
|
"topicType": "msg",
|
|
"x": 590,
|
|
"y": 1660,
|
|
"wires": [
|
|
[]
|
|
]
|
|
},
|
|
{
|
|
"id": "mqtt_broker_local",
|
|
"type": "mqtt-broker",
|
|
"name": "Local MQTT",
|
|
"broker": "localhost",
|
|
"port": "1883",
|
|
"clientid": "",
|
|
"autoConnect": true,
|
|
"usetls": false,
|
|
"protocolVersion": 4,
|
|
"keepalive": "60",
|
|
"cleansession": true,
|
|
"autoUnsubscribe": true,
|
|
"birthTopic": "",
|
|
"birthQos": "0",
|
|
"birthPayload": "",
|
|
"birthMsg": {},
|
|
"closeTopic": "",
|
|
"closePayload": "",
|
|
"closeMsg": {},
|
|
"willTopic": "",
|
|
"willQos": "0",
|
|
"willPayload": "",
|
|
"willMsg": {},
|
|
"userProps": "",
|
|
"sessionExpiry": ""
|
|
},
|
|
{
|
|
"id": "sqlite_local",
|
|
"type": "sqlitedb",
|
|
"db": "C:\\Users\\Moch Alif Ridho A\\Documents\\sensor_data.db",
|
|
"mode": "RWC"
|
|
},
|
|
{
|
|
"id": "ui_group_main",
|
|
"type": "ui_group",
|
|
"name": "Sensor Monitor",
|
|
"tab": "ui_tab_main",
|
|
"order": 1,
|
|
"disp": true,
|
|
"width": "18",
|
|
"collapse": false,
|
|
"className": ""
|
|
},
|
|
{
|
|
"id": "a5d4d4b9.0e5d58",
|
|
"type": "ui_group",
|
|
"name": "Filter Data Sensor",
|
|
"tab": "c75362e0.9e6a38",
|
|
"order": 1,
|
|
"disp": true,
|
|
"width": "18",
|
|
"collapse": false,
|
|
"className": ""
|
|
},
|
|
{
|
|
"id": "077642f35af224dd",
|
|
"type": "ui_group",
|
|
"name": "Kontrol Relay",
|
|
"tab": "c94c9feca08755da",
|
|
"order": 1,
|
|
"disp": true,
|
|
"width": "18",
|
|
"collapse": false,
|
|
"className": ""
|
|
},
|
|
{
|
|
"id": "cfa831704ecb774e",
|
|
"type": "ui_group",
|
|
"name": "Hitung Lama Pengeringan",
|
|
"tab": "2e2f751f9fd061a0",
|
|
"order": 1,
|
|
"disp": true,
|
|
"width": "18",
|
|
"collapse": false,
|
|
"className": ""
|
|
},
|
|
{
|
|
"id": "ui_tab_main",
|
|
"type": "ui_tab",
|
|
"name": "Dashboard Monitoring",
|
|
"icon": "dashboard",
|
|
"order": 2,
|
|
"disabled": false,
|
|
"hidden": false
|
|
},
|
|
{
|
|
"id": "c75362e0.9e6a38",
|
|
"type": "ui_tab",
|
|
"name": "Dashboard Database ",
|
|
"icon": "dashboard",
|
|
"order": 3,
|
|
"disabled": false,
|
|
"hidden": false
|
|
},
|
|
{
|
|
"id": "c94c9feca08755da",
|
|
"type": "ui_tab",
|
|
"name": "Otomasi Relay",
|
|
"icon": "dashboard",
|
|
"order": 5,
|
|
"disabled": false,
|
|
"hidden": false
|
|
},
|
|
{
|
|
"id": "2e2f751f9fd061a0",
|
|
"type": "ui_tab",
|
|
"name": "Hitung Durasi Proses Pengeringan",
|
|
"icon": "dashboard",
|
|
"order": 5,
|
|
"disabled": false,
|
|
"hidden": false
|
|
}
|
|
] |