├── docs
└── img
│ ├── ui.png
│ └── nodes.png
├── README.md
└── iot-device-simulator.json
/docs/img/ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farmassistX/farmassist-iot-device-simulator/HEAD/docs/img/ui.png
--------------------------------------------------------------------------------
/docs/img/nodes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farmassistX/farmassist-iot-device-simulator/HEAD/docs/img/nodes.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Farmassist IoT Device Simulator
2 |
3 | *[Ray Jasson](mailto:holmesqueen2070@yahoo.com)*
4 | *31/01/2021*
5 |
6 |
7 |
8 | ## :satellite: IoT Device Simulation
9 |
10 | This is a minimal IoT device simulator built using [Node-RED](https://nodered.org/). It sends telemetry data to [Firebase Realtime Database](https://firebase.google.com/docs/database) for Farmassist app. There are 5 types of telemetry data:
11 | - Air Humidity (%)
12 | - Air Temperature (°C)
13 | - Soil Moisture (%)
14 | - Soil pH (pH)
15 | - Soil Salinity (Millisiemens/cm)
16 |
17 |

18 | Connected Nodes in Node-RED editor
19 |
20 |
21 |
22 | 
23 | UI Dashboard of the IoT Device Simulator
24 |
25 |
26 |
27 | ## :computer: How to Run the IoT Device Simulator
28 |
29 | The IoT device simulator is a Node-RED flow stored using JSON. The functions are written in JavaScript.
30 |
31 | ### Run the Node-RED flow locally
32 |
33 | - To run the simulator locally, you will need a supported version of Node.js and Node-RED editor.
34 | - To install Node.js, download the recent version from [here](https://nodejs.org/en/download/).
35 | - To install Node-RED editor, run:
36 | ```
37 | npm install -g --unsafe-perm node-red
38 | ```
39 | - Open Node-RED editor by running:
40 | ```
41 | node-red start
42 | ```
43 | - Open [http://localhost:1880](http://localhost:1880) to view the editor in the browser.
44 | - 2 extra node modules: `node-red-dashboard` and `node-red-contrib-firebase-data`, are required to run the simulator. `node-red-dashboard` is used to create a dashboard, whereas `node-red-contrib-firebase-data` is used to connect the nodes to Firebase Realtime Database. To install them, run:
45 | ```
46 | npm install node-red-dashboard
47 | npm install node-red-contrib-firebase-data
48 | ```
49 | - Download the JSON file and import it into the Node-RED editor. You will see the import option at the upper-right corner of the editor.
50 |
51 | ### Customize the simulator
52 |
53 | - You need to add your Realtime Database URL into the configuration node. You can find the URL in the Realtime Database section of your Firebase console. The configuration node :gear: is located at the third option in the right panel.
54 | - Double-click `Add Firebase` node to configure your Firebase URL and set the child path to where the telemetry data is stored in the database. Also, there are several methods for you to write data into Realtime Database, for example, `set`, `push` or `update`. The default method in the JSON file is `update`.
55 | - Remember to click "Deploy" to save your configurations.
56 | - Open the dashboard, and use the sliders to select the range of the telemetry data you would want to send.
57 | - Toggle the switch to start/stop sending the telemetry data.
58 |
59 |
60 |
61 | ## :black_nib: References
62 |
63 | - [A YouTube tutorial teaching you how to build a Node-RED IoT Device Simulator](https://www.youtube.com/watch?v=2GcVvD08nGE)
64 | - [Reference for types of telemetry data from Microsoft Azure Virtual Hackathon 2020 in Asia Pacific](https://news.microsoft.com/apac/2020/08/20/drones-data-science-and-innovation-at-the-microsoft-azure-virtual-hackathon-in-asia-pacific/)
--------------------------------------------------------------------------------
/iot-device-simulator.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "bb155f83.a4277",
4 | "type": "tab",
5 | "label": "main",
6 | "disabled": false,
7 | "info": ""
8 | },
9 | {
10 | "id": "7f15f7f9.621a48",
11 | "type": "subflow",
12 | "name": "airTemperature",
13 | "info": "",
14 | "category": "",
15 | "in": [{ "x": 320, "y": 340, "wires": [{ "id": "1624d34d.8c440d" }] }],
16 | "out": [
17 | { "x": 900, "y": 340, "wires": [{ "id": "13b9c3ef.f5db2c", "port": 0 }] }
18 | ],
19 | "env": [],
20 | "color": "#DDAA99"
21 | },
22 | {
23 | "id": "5d3f7c11.023534",
24 | "type": "subflow",
25 | "name": "airHumidity",
26 | "info": "",
27 | "category": "",
28 | "in": [{ "x": 320, "y": 340, "wires": [{ "id": "c620f442.386f18" }] }],
29 | "out": [
30 | { "x": 900, "y": 340, "wires": [{ "id": "ed27784e.86a9d8", "port": 0 }] }
31 | ],
32 | "env": [],
33 | "color": "#DDAA99"
34 | },
35 | {
36 | "id": "41719d6c.3cfb44",
37 | "type": "subflow",
38 | "name": "soilMoisture",
39 | "info": "",
40 | "category": "",
41 | "in": [{ "x": 320, "y": 340, "wires": [{ "id": "66d8b839.f565a8" }] }],
42 | "out": [
43 | { "x": 900, "y": 340, "wires": [{ "id": "d0abdcdc.837d", "port": 0 }] }
44 | ],
45 | "env": [],
46 | "color": "#DDAA99"
47 | },
48 | {
49 | "id": "f9d383cb.41058",
50 | "type": "subflow",
51 | "name": "soilpH",
52 | "info": "",
53 | "category": "",
54 | "in": [{ "x": 320, "y": 340, "wires": [{ "id": "a841f15a.dfbdf" }] }],
55 | "out": [
56 | { "x": 880, "y": 340, "wires": [{ "id": "bdca0114.d69de", "port": 0 }] }
57 | ],
58 | "env": [],
59 | "color": "#DDAA99"
60 | },
61 | {
62 | "id": "7a111b85.eca174",
63 | "type": "subflow",
64 | "name": "soilSalinity",
65 | "info": "",
66 | "category": "",
67 | "in": [{ "x": 320, "y": 340, "wires": [{ "id": "578fce88.15de5" }] }],
68 | "out": [
69 | { "x": 860, "y": 340, "wires": [{ "id": "f33a2102.a728", "port": 0 }] }
70 | ],
71 | "env": [],
72 | "color": "#DDAA99"
73 | },
74 | {
75 | "id": "74df1345.04015c",
76 | "type": "firebaseCertificate",
77 | "z": "",
78 | "firebaseurl": "",
79 | "loginType": "none"
80 | },
81 | {
82 | "id": "8c5b05a2.ccb108",
83 | "type": "ui_base",
84 | "theme": {
85 | "name": "theme-light",
86 | "lightTheme": {
87 | "default": "#0094CE",
88 | "baseColor": "#4a8a3d",
89 | "baseFont": "Arial,Arial,Helvetica,sans-serif",
90 | "edited": true,
91 | "reset": false
92 | },
93 | "darkTheme": {
94 | "default": "#097479",
95 | "baseColor": "#097479",
96 | "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif",
97 | "edited": false
98 | },
99 | "customTheme": {
100 | "name": "Untitled Theme 1",
101 | "default": "#4B7930",
102 | "baseColor": "#4B7930",
103 | "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"
104 | },
105 | "themeState": {
106 | "base-color": {
107 | "default": "#0094CE",
108 | "value": "#4a8a3d",
109 | "edited": true
110 | },
111 | "page-titlebar-backgroundColor": {
112 | "value": "#4a8a3d",
113 | "edited": false
114 | },
115 | "page-backgroundColor": { "value": "#fafafa", "edited": false },
116 | "page-sidebar-backgroundColor": { "value": "#ffffff", "edited": false },
117 | "group-textColor": { "value": "#6cb75c", "edited": false },
118 | "group-borderColor": { "value": "#ffffff", "edited": false },
119 | "group-backgroundColor": { "value": "#ffffff", "edited": false },
120 | "widget-textColor": { "value": "#111111", "edited": false },
121 | "widget-backgroundColor": { "value": "#4a8a3d", "edited": false },
122 | "widget-borderColor": { "value": "#ffffff", "edited": false },
123 | "base-font": { "value": "Arial,Arial,Helvetica,sans-serif" }
124 | },
125 | "angularTheme": {
126 | "primary": "indigo",
127 | "accents": "blue",
128 | "warn": "red",
129 | "background": "grey"
130 | }
131 | },
132 | "site": {
133 | "name": "IoT Device Simulator",
134 | "hideToolbar": "false",
135 | "allowSwipe": "false",
136 | "lockMenu": "false",
137 | "allowTempTheme": "true",
138 | "dateFormat": "DD/MM/YYYY",
139 | "sizes": {
140 | "sx": 48,
141 | "sy": 48,
142 | "gx": 6,
143 | "gy": 6,
144 | "cx": 6,
145 | "cy": 6,
146 | "px": 0,
147 | "py": 0
148 | }
149 | }
150 | },
151 | {
152 | "id": "d82b4e88.7d197",
153 | "type": "ui_tab",
154 | "z": "",
155 | "name": "IoT Device Simulator",
156 | "icon": "dashboard",
157 | "order": 1,
158 | "disabled": false,
159 | "hidden": false
160 | },
161 | {
162 | "id": "a1f71297.5b069",
163 | "type": "ui_group",
164 | "z": "",
165 | "name": "Simulation Control",
166 | "tab": "d82b4e88.7d197",
167 | "order": 1,
168 | "disp": true,
169 | "width": "25",
170 | "collapse": false
171 | },
172 | {
173 | "id": "5d47cc2.fe17834",
174 | "type": "ui_group",
175 | "z": "",
176 | "name": "Air Temperature",
177 | "tab": "d82b4e88.7d197",
178 | "order": 3,
179 | "disp": true,
180 | "width": "5",
181 | "collapse": false
182 | },
183 | {
184 | "id": "856d803c.8b0cc",
185 | "type": "ui_group",
186 | "z": "",
187 | "name": "Air Humidity",
188 | "tab": "d82b4e88.7d197",
189 | "order": 2,
190 | "disp": true,
191 | "width": "5",
192 | "collapse": false
193 | },
194 | {
195 | "id": "b9c3ab84.f017f8",
196 | "type": "ui_group",
197 | "z": "",
198 | "name": "Soil Moisture",
199 | "tab": "d82b4e88.7d197",
200 | "order": 4,
201 | "disp": true,
202 | "width": "5",
203 | "collapse": false
204 | },
205 | {
206 | "id": "99a1466b.ac8278",
207 | "type": "ui_group",
208 | "z": "",
209 | "name": "Soil pH",
210 | "tab": "d82b4e88.7d197",
211 | "order": 5,
212 | "disp": true,
213 | "width": "5",
214 | "collapse": false
215 | },
216 | {
217 | "id": "bc339738.e6a1e8",
218 | "type": "ui_group",
219 | "z": "",
220 | "name": "Soil Salinity",
221 | "tab": "d82b4e88.7d197",
222 | "order": 6,
223 | "disp": true,
224 | "width": "5",
225 | "collapse": false
226 | },
227 | {
228 | "id": "13f27471.8ac73c",
229 | "type": "ui_spacer",
230 | "name": "spacer",
231 | "group": "91dd813.4ee908",
232 | "order": 8,
233 | "width": "0",
234 | "height": "0"
235 | },
236 | {
237 | "id": "bb58c10d.e7b37",
238 | "type": "ui_spacer",
239 | "name": "spacer",
240 | "group": "88de906.e68327",
241 | "order": 7,
242 | "width": "4",
243 | "height": "18"
244 | },
245 | {
246 | "id": "b1d0e473.439698",
247 | "type": "addFirebase",
248 | "z": "bb155f83.a4277",
249 | "firebaseCertificate": "",
250 | "client_email": "",
251 | "private_key": "",
252 | "data": "",
253 | "childpath": "",
254 | "propertyType": "str",
255 | "method": "update",
256 | "newchildpath": "",
257 | "x": 710,
258 | "y": 300,
259 | "wires": [["7c8b78a0.1d4308"]]
260 | },
261 | {
262 | "id": "23447946.4dc476",
263 | "type": "inject",
264 | "z": "bb155f83.a4277",
265 | "name": "Timestamp",
266 | "props": [{ "p": "payload" }],
267 | "repeat": "5",
268 | "crontab": "",
269 | "once": false,
270 | "onceDelay": 0.1,
271 | "topic": "",
272 | "payload": "",
273 | "payloadType": "date",
274 | "x": 130,
275 | "y": 260,
276 | "wires": [["db2c7552.3980f8"]]
277 | },
278 | {
279 | "id": "bf37538d.4e7b9",
280 | "type": "ui_switch",
281 | "z": "bb155f83.a4277",
282 | "name": "Start/Stop",
283 | "label": "Start/Stop Simulation",
284 | "tooltip": "Start sending telemetry data to Firebase Realtime Database",
285 | "group": "a1f71297.5b069",
286 | "order": 2,
287 | "width": 0,
288 | "height": 0,
289 | "passthru": true,
290 | "decouple": "false",
291 | "topic": "gate",
292 | "style": "",
293 | "onvalue": "true",
294 | "onvalueType": "bool",
295 | "onicon": "",
296 | "oncolor": "",
297 | "offvalue": "false",
298 | "offvalueType": "bool",
299 | "officon": "",
300 | "offcolor": "",
301 | "x": 100,
302 | "y": 340,
303 | "wires": [["db2c7552.3980f8"]]
304 | },
305 | {
306 | "id": "3c7bbdb4.397652",
307 | "type": "ui_slider",
308 | "z": "7f15f7f9.621a48",
309 | "name": "Min",
310 | "label": "Min",
311 | "tooltip": "Minimum value of air temperature",
312 | "group": "5d47cc2.fe17834",
313 | "order": 1,
314 | "width": 0,
315 | "height": 0,
316 | "passthru": true,
317 | "outs": "all",
318 | "topic": "",
319 | "min": 0,
320 | "max": "100",
321 | "step": 1,
322 | "x": 90,
323 | "y": 80,
324 | "wires": [["3cc63cd5.bfd614", "19e8c238.3d103e"]]
325 | },
326 | {
327 | "id": "de94d6da.924528",
328 | "type": "ui_slider",
329 | "z": "7f15f7f9.621a48",
330 | "name": "Max",
331 | "label": "Max",
332 | "tooltip": "Maximum value of air temperature",
333 | "group": "5d47cc2.fe17834",
334 | "order": 3,
335 | "width": 0,
336 | "height": 0,
337 | "passthru": true,
338 | "outs": "all",
339 | "topic": "",
340 | "min": 0,
341 | "max": "100",
342 | "step": 1,
343 | "x": 90,
344 | "y": 200,
345 | "wires": [["bc16f7a3.5459e8", "af5ddc0e.7a70d"]]
346 | },
347 | {
348 | "id": "b4177b1d.a5f0b8",
349 | "type": "subflow:7f15f7f9.621a48",
350 | "z": "bb155f83.a4277",
351 | "name": "airTemperature",
352 | "env": [],
353 | "x": 500,
354 | "y": 220,
355 | "wires": [["663e13b2.82511c"]]
356 | },
357 | {
358 | "id": "3cc63cd5.bfd614",
359 | "type": "ui_text",
360 | "z": "7f15f7f9.621a48",
361 | "group": "5d47cc2.fe17834",
362 | "order": 2,
363 | "width": 0,
364 | "height": 0,
365 | "name": "Value",
366 | "label": "Value:",
367 | "format": "{{msg.payload}}",
368 | "layout": "row-spread",
369 | "x": 250,
370 | "y": 80,
371 | "wires": []
372 | },
373 | {
374 | "id": "bc16f7a3.5459e8",
375 | "type": "ui_text",
376 | "z": "7f15f7f9.621a48",
377 | "group": "5d47cc2.fe17834",
378 | "order": 4,
379 | "width": 0,
380 | "height": 0,
381 | "name": "Value",
382 | "label": "Value:",
383 | "format": "{{msg.payload}}",
384 | "layout": "row-spread",
385 | "x": 250,
386 | "y": 200,
387 | "wires": []
388 | },
389 | {
390 | "id": "e2b7dec9.cfb4",
391 | "type": "subflow:5d3f7c11.023534",
392 | "z": "bb155f83.a4277",
393 | "name": "airHumidity",
394 | "env": [],
395 | "x": 490,
396 | "y": 140,
397 | "wires": [["fe4fd7ce.70c838"]]
398 | },
399 | {
400 | "id": "22c0bacc.5c2df6",
401 | "type": "subflow:41719d6c.3cfb44",
402 | "z": "bb155f83.a4277",
403 | "name": "soilMoisture",
404 | "env": [],
405 | "x": 490,
406 | "y": 300,
407 | "wires": [["b1d0e473.439698"]]
408 | },
409 | {
410 | "id": "1f165dbf.a39cb2",
411 | "type": "subflow:f9d383cb.41058",
412 | "z": "bb155f83.a4277",
413 | "name": "soilpH",
414 | "env": [],
415 | "x": 470,
416 | "y": 380,
417 | "wires": [["4085dcbe.3c7024"]]
418 | },
419 | {
420 | "id": "636bbabe.171a84",
421 | "type": "subflow:7a111b85.eca174",
422 | "z": "bb155f83.a4277",
423 | "name": "soilSalinity",
424 | "env": [],
425 | "x": 490,
426 | "y": 460,
427 | "wires": [["59fd8bd1.dc7b84"]]
428 | },
429 | {
430 | "id": "19e8c238.3d103e",
431 | "type": "function",
432 | "z": "7f15f7f9.621a48",
433 | "name": "minValue",
434 | "func": "flow.set(\"airTemperatureMin\", msg.payload);\nreturn msg;",
435 | "outputs": 1,
436 | "noerr": 0,
437 | "initialize": "",
438 | "finalize": "",
439 | "x": 260,
440 | "y": 140,
441 | "wires": [["1624d34d.8c440d"]]
442 | },
443 | {
444 | "id": "af5ddc0e.7a70d",
445 | "type": "function",
446 | "z": "7f15f7f9.621a48",
447 | "name": "maxValue",
448 | "func": "flow.set(\"airTemperatureMax\", msg.payload);\nreturn msg;",
449 | "outputs": 1,
450 | "noerr": 0,
451 | "initialize": "",
452 | "finalize": "",
453 | "x": 260,
454 | "y": 260,
455 | "wires": [["1624d34d.8c440d"]]
456 | },
457 | {
458 | "id": "1624d34d.8c440d",
459 | "type": "function",
460 | "z": "7f15f7f9.621a48",
461 | "name": "airTemperature",
462 | "func": "if (global.get(\"control\") === true) {\n let min = flow.get(\"airTemperatureMin\");\n let max = flow.get(\"airTemperatureMax\");\n let airTemperature = (Math.random() * (max - min) + min).toFixed(2);\n global.set(\"airTemperature\", airTemperature);\n msg.payload = airTemperature;\n return msg;\n}\nelse {\n return null;\n}",
463 | "outputs": 1,
464 | "noerr": 0,
465 | "initialize": "",
466 | "finalize": "",
467 | "x": 480,
468 | "y": 180,
469 | "wires": [["c5dd25cb.aafdd8", "5e05ee13.787a1", "13b9c3ef.f5db2c"]]
470 | },
471 | {
472 | "id": "c5dd25cb.aafdd8",
473 | "type": "ui_gauge",
474 | "z": "7f15f7f9.621a48",
475 | "name": "airTemperatureReading",
476 | "group": "5d47cc2.fe17834",
477 | "order": 5,
478 | "width": 0,
479 | "height": 0,
480 | "gtype": "gage",
481 | "title": "°C",
482 | "label": "°C",
483 | "format": "{{value}}",
484 | "min": 0,
485 | "max": "100",
486 | "colors": ["#00b500", "#e6e600", "#ca3838"],
487 | "seg1": "",
488 | "seg2": "",
489 | "x": 750,
490 | "y": 180,
491 | "wires": []
492 | },
493 | {
494 | "id": "5e05ee13.787a1",
495 | "type": "ui_chart",
496 | "z": "7f15f7f9.621a48",
497 | "name": "airTemperatureChart",
498 | "group": "5d47cc2.fe17834",
499 | "order": 6,
500 | "width": 0,
501 | "height": 0,
502 | "label": "Air temperature last minute",
503 | "chartType": "line",
504 | "legend": "false",
505 | "xformat": "HH:mm:ss",
506 | "interpolate": "linear",
507 | "nodata": "Awaiting new data",
508 | "dot": true,
509 | "ymin": "0",
510 | "ymax": "100",
511 | "removeOlder": 1,
512 | "removeOlderPoints": "",
513 | "removeOlderUnit": "60",
514 | "cutout": 0,
515 | "useOneColor": false,
516 | "useUTC": false,
517 | "colors": [
518 | "#1f77b4",
519 | "#aec7e8",
520 | "#ff7f0e",
521 | "#2ca02c",
522 | "#98df8a",
523 | "#d62728",
524 | "#ff9896",
525 | "#9467bd",
526 | "#c5b0d5"
527 | ],
528 | "outputs": 1,
529 | "x": 740,
530 | "y": 260,
531 | "wires": [[]]
532 | },
533 | {
534 | "id": "db2c7552.3980f8",
535 | "type": "function",
536 | "z": "bb155f83.a4277",
537 | "name": "control",
538 | "func": "if (msg.topic === \"gate\") {\n context.pass = (msg.payload === true) ? true : false;\n global.set(\"control\", context.pass);\n return null;\n}\nif (context.pass) {\n return msg;\n}\nreturn null;",
539 | "outputs": 1,
540 | "noerr": 0,
541 | "initialize": "",
542 | "finalize": "",
543 | "x": 310,
544 | "y": 300,
545 | "wires": [
546 | [
547 | "e2b7dec9.cfb4",
548 | "22c0bacc.5c2df6",
549 | "b4177b1d.a5f0b8",
550 | "1f165dbf.a39cb2",
551 | "636bbabe.171a84"
552 | ]
553 | ]
554 | },
555 | {
556 | "id": "4befd78.7f55828",
557 | "type": "ui_slider",
558 | "z": "5d3f7c11.023534",
559 | "name": "Min",
560 | "label": "Min",
561 | "tooltip": "Minimum value of air humidity",
562 | "group": "856d803c.8b0cc",
563 | "order": 1,
564 | "width": 0,
565 | "height": 0,
566 | "passthru": true,
567 | "outs": "all",
568 | "topic": "",
569 | "min": 0,
570 | "max": "100",
571 | "step": 1,
572 | "x": 90,
573 | "y": 80,
574 | "wires": [["8baae11d.e51f8", "fde2eb98.eee518"]]
575 | },
576 | {
577 | "id": "1ac7bd1.46aae43",
578 | "type": "ui_slider",
579 | "z": "5d3f7c11.023534",
580 | "name": "Max",
581 | "label": "Max",
582 | "tooltip": "Maximum value of air humidity",
583 | "group": "856d803c.8b0cc",
584 | "order": 3,
585 | "width": 0,
586 | "height": 0,
587 | "passthru": true,
588 | "outs": "all",
589 | "topic": "",
590 | "min": 0,
591 | "max": "100",
592 | "step": 1,
593 | "x": 90,
594 | "y": 200,
595 | "wires": [["ba3e7660.b71498", "1b3d24ba.a7f7fb"]]
596 | },
597 | {
598 | "id": "8baae11d.e51f8",
599 | "type": "ui_text",
600 | "z": "5d3f7c11.023534",
601 | "group": "856d803c.8b0cc",
602 | "order": 2,
603 | "width": 0,
604 | "height": 0,
605 | "name": "Value",
606 | "label": "Value:",
607 | "format": "{{msg.payload}}",
608 | "layout": "row-spread",
609 | "x": 250,
610 | "y": 80,
611 | "wires": []
612 | },
613 | {
614 | "id": "ba3e7660.b71498",
615 | "type": "ui_text",
616 | "z": "5d3f7c11.023534",
617 | "group": "856d803c.8b0cc",
618 | "order": 4,
619 | "width": 0,
620 | "height": 0,
621 | "name": "Value",
622 | "label": "Value:",
623 | "format": "{{msg.payload}}",
624 | "layout": "row-spread",
625 | "x": 250,
626 | "y": 200,
627 | "wires": []
628 | },
629 | {
630 | "id": "fde2eb98.eee518",
631 | "type": "function",
632 | "z": "5d3f7c11.023534",
633 | "name": "minValue",
634 | "func": "flow.set(\"airHumidityMin\", msg.payload);\nreturn msg;",
635 | "outputs": 1,
636 | "noerr": 0,
637 | "initialize": "",
638 | "finalize": "",
639 | "x": 260,
640 | "y": 140,
641 | "wires": [["c620f442.386f18"]]
642 | },
643 | {
644 | "id": "1b3d24ba.a7f7fb",
645 | "type": "function",
646 | "z": "5d3f7c11.023534",
647 | "name": "maxValue",
648 | "func": "flow.set(\"airHumidityMax\", msg.payload);\nreturn msg;",
649 | "outputs": 1,
650 | "noerr": 0,
651 | "initialize": "",
652 | "finalize": "",
653 | "x": 260,
654 | "y": 260,
655 | "wires": [["c620f442.386f18"]]
656 | },
657 | {
658 | "id": "c620f442.386f18",
659 | "type": "function",
660 | "z": "5d3f7c11.023534",
661 | "name": "airHumidity",
662 | "func": "if (global.get(\"control\") === true) {\n let min = flow.get(\"airHumidityMin\");\n let max = flow.get(\"airHumidityMax\");\n let airHumidity = (Math.random() * (max - min) + min).toFixed(2);\n global.set(\"airHumidity\", airHumidity);\n msg.payload = airHumidity;\n return msg;\n}\nelse {\n return null;\n}",
663 | "outputs": 1,
664 | "noerr": 0,
665 | "initialize": "",
666 | "finalize": "",
667 | "x": 470,
668 | "y": 180,
669 | "wires": [["1b3ce38d.277eac", "ffda1a6.b3b41e8", "ed27784e.86a9d8"]]
670 | },
671 | {
672 | "id": "1b3ce38d.277eac",
673 | "type": "ui_gauge",
674 | "z": "5d3f7c11.023534",
675 | "name": "airHumidityReading",
676 | "group": "856d803c.8b0cc",
677 | "order": 5,
678 | "width": 0,
679 | "height": 0,
680 | "gtype": "gage",
681 | "title": "%",
682 | "label": "%",
683 | "format": "{{value}}",
684 | "min": 0,
685 | "max": "100",
686 | "colors": ["#00b500", "#e6e600", "#ca3838"],
687 | "seg1": "",
688 | "seg2": "",
689 | "x": 730,
690 | "y": 180,
691 | "wires": []
692 | },
693 | {
694 | "id": "ffda1a6.b3b41e8",
695 | "type": "ui_chart",
696 | "z": "5d3f7c11.023534",
697 | "name": "airHumidityChart",
698 | "group": "856d803c.8b0cc",
699 | "order": 6,
700 | "width": 0,
701 | "height": 0,
702 | "label": "Air humidity last minute",
703 | "chartType": "line",
704 | "legend": "false",
705 | "xformat": "HH:mm:ss",
706 | "interpolate": "linear",
707 | "nodata": "Awaiting new data",
708 | "dot": true,
709 | "ymin": "0",
710 | "ymax": "100",
711 | "removeOlder": 1,
712 | "removeOlderPoints": "",
713 | "removeOlderUnit": "60",
714 | "cutout": 0,
715 | "useOneColor": false,
716 | "useUTC": false,
717 | "colors": [
718 | "#1f77b4",
719 | "#aec7e8",
720 | "#ff7f0e",
721 | "#2ca02c",
722 | "#98df8a",
723 | "#d62728",
724 | "#ff9896",
725 | "#9467bd",
726 | "#c5b0d5"
727 | ],
728 | "outputs": 1,
729 | "x": 730,
730 | "y": 260,
731 | "wires": [[]]
732 | },
733 | {
734 | "id": "182fcb04.d29485",
735 | "type": "ui_slider",
736 | "z": "f9d383cb.41058",
737 | "name": "Min",
738 | "label": "Min",
739 | "tooltip": "Minimum value of soil pH",
740 | "group": "99a1466b.ac8278",
741 | "order": 1,
742 | "width": 0,
743 | "height": 0,
744 | "passthru": true,
745 | "outs": "all",
746 | "topic": "",
747 | "min": 0,
748 | "max": "100",
749 | "step": 1,
750 | "x": 90,
751 | "y": 80,
752 | "wires": [["438558f7.43fa58", "59a3bae8.75fab4"]]
753 | },
754 | {
755 | "id": "20e93046.90f84",
756 | "type": "ui_slider",
757 | "z": "f9d383cb.41058",
758 | "name": "Max",
759 | "label": "Max",
760 | "tooltip": "Maximum value of soil pH",
761 | "group": "99a1466b.ac8278",
762 | "order": 3,
763 | "width": 0,
764 | "height": 0,
765 | "passthru": true,
766 | "outs": "all",
767 | "topic": "",
768 | "min": 0,
769 | "max": "100",
770 | "step": 1,
771 | "x": 90,
772 | "y": 200,
773 | "wires": [["69c13815.f100c8", "5ca1b6da.29b658"]]
774 | },
775 | {
776 | "id": "438558f7.43fa58",
777 | "type": "ui_text",
778 | "z": "f9d383cb.41058",
779 | "group": "99a1466b.ac8278",
780 | "order": 2,
781 | "width": 0,
782 | "height": 0,
783 | "name": "Value",
784 | "label": "Value:",
785 | "format": "{{msg.payload}}",
786 | "layout": "row-spread",
787 | "x": 250,
788 | "y": 80,
789 | "wires": []
790 | },
791 | {
792 | "id": "69c13815.f100c8",
793 | "type": "ui_text",
794 | "z": "f9d383cb.41058",
795 | "group": "99a1466b.ac8278",
796 | "order": 4,
797 | "width": 0,
798 | "height": 0,
799 | "name": "Value",
800 | "label": "Value:",
801 | "format": "{{msg.payload}}",
802 | "layout": "row-spread",
803 | "x": 250,
804 | "y": 200,
805 | "wires": []
806 | },
807 | {
808 | "id": "59a3bae8.75fab4",
809 | "type": "function",
810 | "z": "f9d383cb.41058",
811 | "name": "minValue",
812 | "func": "flow.set(\"soilpHMin\", msg.payload);\nreturn msg;",
813 | "outputs": 1,
814 | "noerr": 0,
815 | "initialize": "",
816 | "finalize": "",
817 | "x": 260,
818 | "y": 140,
819 | "wires": [["a841f15a.dfbdf"]]
820 | },
821 | {
822 | "id": "5ca1b6da.29b658",
823 | "type": "function",
824 | "z": "f9d383cb.41058",
825 | "name": "maxValue",
826 | "func": "flow.set(\"soilpHMax\", msg.payload);\nreturn msg;",
827 | "outputs": 1,
828 | "noerr": 0,
829 | "initialize": "",
830 | "finalize": "",
831 | "x": 260,
832 | "y": 260,
833 | "wires": [["a841f15a.dfbdf"]]
834 | },
835 | {
836 | "id": "a841f15a.dfbdf",
837 | "type": "function",
838 | "z": "f9d383cb.41058",
839 | "name": "soilpH",
840 | "func": "if (global.get(\"control\") === true) {\n let min = flow.get(\"soilpHMin\");\n let max = flow.get(\"soilpHMax\");\n let soilpH = (Math.random() * (max - min) + min).toFixed(2);\n global.set(\"soilpH\", soilpH);\n msg.payload = soilpH;\n return msg;\n}\nelse {\n return null;\n}",
841 | "outputs": 1,
842 | "noerr": 0,
843 | "initialize": "",
844 | "finalize": "",
845 | "x": 450,
846 | "y": 180,
847 | "wires": [["d342e64f.727438", "6d157a2c.bf8b94", "bdca0114.d69de"]]
848 | },
849 | {
850 | "id": "d342e64f.727438",
851 | "type": "ui_gauge",
852 | "z": "f9d383cb.41058",
853 | "name": "soilpHReading",
854 | "group": "99a1466b.ac8278",
855 | "order": 5,
856 | "width": 0,
857 | "height": 0,
858 | "gtype": "gage",
859 | "title": "pH",
860 | "label": "pH",
861 | "format": "{{value}}",
862 | "min": 0,
863 | "max": "100",
864 | "colors": ["#00b500", "#e6e600", "#ca3838"],
865 | "seg1": "",
866 | "seg2": "",
867 | "x": 720,
868 | "y": 180,
869 | "wires": []
870 | },
871 | {
872 | "id": "6d157a2c.bf8b94",
873 | "type": "ui_chart",
874 | "z": "f9d383cb.41058",
875 | "name": "soilpHChart",
876 | "group": "99a1466b.ac8278",
877 | "order": 6,
878 | "width": 0,
879 | "height": 0,
880 | "label": "Soil pH last minute",
881 | "chartType": "line",
882 | "legend": "false",
883 | "xformat": "HH:mm:ss",
884 | "interpolate": "linear",
885 | "nodata": "Awaiting new data",
886 | "dot": true,
887 | "ymin": "0",
888 | "ymax": "100",
889 | "removeOlder": 1,
890 | "removeOlderPoints": "",
891 | "removeOlderUnit": "60",
892 | "cutout": 0,
893 | "useOneColor": false,
894 | "useUTC": false,
895 | "colors": [
896 | "#1f77b4",
897 | "#aec7e8",
898 | "#ff7f0e",
899 | "#2ca02c",
900 | "#98df8a",
901 | "#d62728",
902 | "#ff9896",
903 | "#9467bd",
904 | "#c5b0d5"
905 | ],
906 | "outputs": 1,
907 | "x": 710,
908 | "y": 260,
909 | "wires": [[]]
910 | },
911 | {
912 | "id": "41bf3400.90221c",
913 | "type": "ui_slider",
914 | "z": "7a111b85.eca174",
915 | "name": "Min",
916 | "label": "Min",
917 | "tooltip": "Minimum value of soil salinity",
918 | "group": "bc339738.e6a1e8",
919 | "order": 1,
920 | "width": 0,
921 | "height": 0,
922 | "passthru": true,
923 | "outs": "all",
924 | "topic": "",
925 | "min": 0,
926 | "max": "100",
927 | "step": 1,
928 | "x": 90,
929 | "y": 80,
930 | "wires": [["fdf0cc7c.4ecee", "282064d6.5f80bc"]]
931 | },
932 | {
933 | "id": "1ffabc67.81cd24",
934 | "type": "ui_slider",
935 | "z": "7a111b85.eca174",
936 | "name": "Max",
937 | "label": "Max",
938 | "tooltip": "Maximum value of soil salinity",
939 | "group": "bc339738.e6a1e8",
940 | "order": 3,
941 | "width": 0,
942 | "height": 0,
943 | "passthru": true,
944 | "outs": "all",
945 | "topic": "",
946 | "min": 0,
947 | "max": "100",
948 | "step": 1,
949 | "x": 90,
950 | "y": 200,
951 | "wires": [["bf135961.f055d8", "3c191757.18a9c8"]]
952 | },
953 | {
954 | "id": "fdf0cc7c.4ecee",
955 | "type": "ui_text",
956 | "z": "7a111b85.eca174",
957 | "group": "bc339738.e6a1e8",
958 | "order": 2,
959 | "width": 0,
960 | "height": 0,
961 | "name": "Value",
962 | "label": "Value:",
963 | "format": "{{msg.payload}}",
964 | "layout": "row-spread",
965 | "x": 250,
966 | "y": 80,
967 | "wires": []
968 | },
969 | {
970 | "id": "bf135961.f055d8",
971 | "type": "ui_text",
972 | "z": "7a111b85.eca174",
973 | "group": "bc339738.e6a1e8",
974 | "order": 4,
975 | "width": 0,
976 | "height": 0,
977 | "name": "Value",
978 | "label": "Value:",
979 | "format": "{{msg.payload}}",
980 | "layout": "row-spread",
981 | "x": 250,
982 | "y": 200,
983 | "wires": []
984 | },
985 | {
986 | "id": "282064d6.5f80bc",
987 | "type": "function",
988 | "z": "7a111b85.eca174",
989 | "name": "minValue",
990 | "func": "flow.set(\"soilSalinityMin\", msg.payload);\nreturn msg;",
991 | "outputs": 1,
992 | "noerr": 0,
993 | "initialize": "",
994 | "finalize": "",
995 | "x": 260,
996 | "y": 140,
997 | "wires": [["578fce88.15de5"]]
998 | },
999 | {
1000 | "id": "3c191757.18a9c8",
1001 | "type": "function",
1002 | "z": "7a111b85.eca174",
1003 | "name": "maxValue",
1004 | "func": "flow.set(\"soilSalinityMax\", msg.payload);\nreturn msg;",
1005 | "outputs": 1,
1006 | "noerr": 0,
1007 | "initialize": "",
1008 | "finalize": "",
1009 | "x": 260,
1010 | "y": 260,
1011 | "wires": [["578fce88.15de5"]]
1012 | },
1013 | {
1014 | "id": "578fce88.15de5",
1015 | "type": "function",
1016 | "z": "7a111b85.eca174",
1017 | "name": "soilSalinity",
1018 | "func": "if (global.get(\"control\") === true) {\n let min = flow.get(\"soilSalinityMin\");\n let max = flow.get(\"soilSalinityMax\");\n let soilSalinity = (Math.random() * (max - min) + min).toFixed(2);\n global.set(\"soilSalinity\", soilSalinity);\n msg.payload = soilSalinity;\n return msg;\n}\nelse {\n return null;\n}",
1019 | "outputs": 1,
1020 | "noerr": 0,
1021 | "initialize": "",
1022 | "finalize": "",
1023 | "x": 470,
1024 | "y": 180,
1025 | "wires": [["42d8c053.597ff", "5aa01ca0.9391c4", "f33a2102.a728"]]
1026 | },
1027 | {
1028 | "id": "42d8c053.597ff",
1029 | "type": "ui_gauge",
1030 | "z": "7a111b85.eca174",
1031 | "name": "soilSalinityReading",
1032 | "group": "bc339738.e6a1e8",
1033 | "order": 5,
1034 | "width": 0,
1035 | "height": 0,
1036 | "gtype": "gage",
1037 | "title": "mS/cm",
1038 | "label": "mS/cm",
1039 | "format": "{{value}}",
1040 | "min": 0,
1041 | "max": "100",
1042 | "colors": ["#00b500", "#e6e600", "#ca3838"],
1043 | "seg1": "",
1044 | "seg2": "",
1045 | "x": 730,
1046 | "y": 180,
1047 | "wires": []
1048 | },
1049 | {
1050 | "id": "5aa01ca0.9391c4",
1051 | "type": "ui_chart",
1052 | "z": "7a111b85.eca174",
1053 | "name": "soilSalinityChart",
1054 | "group": "bc339738.e6a1e8",
1055 | "order": 6,
1056 | "width": 0,
1057 | "height": 0,
1058 | "label": "Soil salinity last minute",
1059 | "chartType": "line",
1060 | "legend": "false",
1061 | "xformat": "HH:mm:ss",
1062 | "interpolate": "linear",
1063 | "nodata": "Awaiting new data",
1064 | "dot": true,
1065 | "ymin": "0",
1066 | "ymax": "100",
1067 | "removeOlder": 1,
1068 | "removeOlderPoints": "",
1069 | "removeOlderUnit": "60",
1070 | "cutout": 0,
1071 | "useOneColor": false,
1072 | "useUTC": false,
1073 | "colors": [
1074 | "#1f77b4",
1075 | "#aec7e8",
1076 | "#ff7f0e",
1077 | "#2ca02c",
1078 | "#98df8a",
1079 | "#d62728",
1080 | "#ff9896",
1081 | "#9467bd",
1082 | "#c5b0d5"
1083 | ],
1084 | "outputs": 1,
1085 | "x": 720,
1086 | "y": 260,
1087 | "wires": [[]]
1088 | },
1089 | {
1090 | "id": "2111e35.d18c81c",
1091 | "type": "ui_slider",
1092 | "z": "41719d6c.3cfb44",
1093 | "name": "Min",
1094 | "label": "Min",
1095 | "tooltip": "Minimum value of soil moisture",
1096 | "group": "b9c3ab84.f017f8",
1097 | "order": 1,
1098 | "width": 0,
1099 | "height": 0,
1100 | "passthru": true,
1101 | "outs": "all",
1102 | "topic": "",
1103 | "min": 0,
1104 | "max": "100",
1105 | "step": 1,
1106 | "x": 90,
1107 | "y": 80,
1108 | "wires": [["8167486c.537088", "f1cf97bd.f58b08"]]
1109 | },
1110 | {
1111 | "id": "b69c67dc.a3f5e8",
1112 | "type": "ui_slider",
1113 | "z": "41719d6c.3cfb44",
1114 | "name": "Max",
1115 | "label": "Max",
1116 | "tooltip": "Maximum value of soil moisture",
1117 | "group": "b9c3ab84.f017f8",
1118 | "order": 3,
1119 | "width": 0,
1120 | "height": 0,
1121 | "passthru": true,
1122 | "outs": "all",
1123 | "topic": "",
1124 | "min": 0,
1125 | "max": "100",
1126 | "step": 1,
1127 | "x": 90,
1128 | "y": 200,
1129 | "wires": [["ae5b6533.924748", "8bb90da8.cfe89"]]
1130 | },
1131 | {
1132 | "id": "8167486c.537088",
1133 | "type": "ui_text",
1134 | "z": "41719d6c.3cfb44",
1135 | "group": "b9c3ab84.f017f8",
1136 | "order": 2,
1137 | "width": 0,
1138 | "height": 0,
1139 | "name": "Value",
1140 | "label": "Value:",
1141 | "format": "{{msg.payload}}",
1142 | "layout": "row-spread",
1143 | "x": 250,
1144 | "y": 80,
1145 | "wires": []
1146 | },
1147 | {
1148 | "id": "ae5b6533.924748",
1149 | "type": "ui_text",
1150 | "z": "41719d6c.3cfb44",
1151 | "group": "b9c3ab84.f017f8",
1152 | "order": 4,
1153 | "width": 0,
1154 | "height": 0,
1155 | "name": "Value",
1156 | "label": "Value:",
1157 | "format": "{{msg.payload}}",
1158 | "layout": "row-spread",
1159 | "x": 250,
1160 | "y": 200,
1161 | "wires": []
1162 | },
1163 | {
1164 | "id": "f1cf97bd.f58b08",
1165 | "type": "function",
1166 | "z": "41719d6c.3cfb44",
1167 | "name": "minValue",
1168 | "func": "flow.set(\"soilMoistureMin\", msg.payload);\nreturn msg;",
1169 | "outputs": 1,
1170 | "noerr": 0,
1171 | "initialize": "",
1172 | "finalize": "",
1173 | "x": 260,
1174 | "y": 140,
1175 | "wires": [["66d8b839.f565a8"]]
1176 | },
1177 | {
1178 | "id": "8bb90da8.cfe89",
1179 | "type": "function",
1180 | "z": "41719d6c.3cfb44",
1181 | "name": "maxValue",
1182 | "func": "flow.set(\"soilMoistureMax\", msg.payload);\nreturn msg;",
1183 | "outputs": 1,
1184 | "noerr": 0,
1185 | "initialize": "",
1186 | "finalize": "",
1187 | "x": 260,
1188 | "y": 260,
1189 | "wires": [["66d8b839.f565a8"]]
1190 | },
1191 | {
1192 | "id": "66d8b839.f565a8",
1193 | "type": "function",
1194 | "z": "41719d6c.3cfb44",
1195 | "name": "soilMoisture",
1196 | "func": "if (global.get(\"control\") === true) {\n let min = flow.get(\"soilMoistureMin\");\n let max = flow.get(\"soilMoistureMax\");\n let soilMoisture = (Math.random() * (max - min) + min).toFixed(2);\n global.set(\"soilMoisture\", soilMoisture);\n msg.payload = soilMoisture;\n return msg;\n}\nelse {\n return null;\n}",
1197 | "outputs": 1,
1198 | "noerr": 0,
1199 | "initialize": "",
1200 | "finalize": "",
1201 | "x": 470,
1202 | "y": 180,
1203 | "wires": [["a0795cf.c2a64a", "4f0a0648.5b31a8", "d0abdcdc.837d"]]
1204 | },
1205 | {
1206 | "id": "a0795cf.c2a64a",
1207 | "type": "ui_gauge",
1208 | "z": "41719d6c.3cfb44",
1209 | "name": "soilMoistureReading",
1210 | "group": "b9c3ab84.f017f8",
1211 | "order": 5,
1212 | "width": 0,
1213 | "height": 0,
1214 | "gtype": "gage",
1215 | "title": "%",
1216 | "label": "%",
1217 | "format": "{{value}}",
1218 | "min": 0,
1219 | "max": "100",
1220 | "colors": ["#00b500", "#e6e600", "#ca3838"],
1221 | "seg1": "",
1222 | "seg2": "",
1223 | "x": 740,
1224 | "y": 180,
1225 | "wires": []
1226 | },
1227 | {
1228 | "id": "4f0a0648.5b31a8",
1229 | "type": "ui_chart",
1230 | "z": "41719d6c.3cfb44",
1231 | "name": "soilMoistureChart",
1232 | "group": "b9c3ab84.f017f8",
1233 | "order": 6,
1234 | "width": 0,
1235 | "height": 0,
1236 | "label": "Soil moisture last minute",
1237 | "chartType": "line",
1238 | "legend": "false",
1239 | "xformat": "HH:mm:ss",
1240 | "interpolate": "linear",
1241 | "nodata": "Awaiting new data",
1242 | "dot": true,
1243 | "ymin": "0",
1244 | "ymax": "100",
1245 | "removeOlder": 1,
1246 | "removeOlderPoints": "",
1247 | "removeOlderUnit": "60",
1248 | "cutout": 0,
1249 | "useOneColor": false,
1250 | "useUTC": false,
1251 | "colors": [
1252 | "#1f77b4",
1253 | "#aec7e8",
1254 | "#ff7f0e",
1255 | "#2ca02c",
1256 | "#98df8a",
1257 | "#d62728",
1258 | "#ff9896",
1259 | "#9467bd",
1260 | "#c5b0d5"
1261 | ],
1262 | "outputs": 1,
1263 | "x": 730,
1264 | "y": 260,
1265 | "wires": [[]]
1266 | },
1267 | {
1268 | "id": "13b9c3ef.f5db2c",
1269 | "type": "function",
1270 | "z": "7f15f7f9.621a48",
1271 | "name": "airTemperatureMsg",
1272 | "func": "if (global.get(\"control\") === true) {\n let timestamp = Date.now();\n let airTemperature = global.get(\"airTemperature\");\n let payload = {\n [timestamp]: airTemperature,\n };\n msg.payload = payload;\n return msg;\n}\nelse {\n return null;\n}",
1273 | "outputs": 1,
1274 | "noerr": 0,
1275 | "initialize": "",
1276 | "finalize": "",
1277 | "x": 730,
1278 | "y": 340,
1279 | "wires": [[]]
1280 | },
1281 | {
1282 | "id": "ed27784e.86a9d8",
1283 | "type": "function",
1284 | "z": "5d3f7c11.023534",
1285 | "name": "airHumidityMsg",
1286 | "func": "if (global.get(\"control\") === true) {\n let timestamp = Date.now();\n let airHumidity = global.get(\"airHumidity\");\n let payload = {\n [timestamp]: airHumidity,\n };\n msg.payload = payload;\n return msg;\n}\nelse {\n return null;\n}",
1287 | "outputs": 1,
1288 | "noerr": 0,
1289 | "initialize": "",
1290 | "finalize": "",
1291 | "x": 720,
1292 | "y": 340,
1293 | "wires": [[]]
1294 | },
1295 | {
1296 | "id": "d0abdcdc.837d",
1297 | "type": "function",
1298 | "z": "41719d6c.3cfb44",
1299 | "name": "soilMoistureMsg",
1300 | "func": "if (global.get(\"control\") === true) {\n let timestamp = Date.now();\n let soilMoisture = global.get(\"soilMoisture\");\n let payload = {\n [timestamp]: soilMoisture,\n };\n msg.payload = payload;\n return msg;\n}\nelse {\n return null;\n}",
1301 | "outputs": 1,
1302 | "noerr": 0,
1303 | "initialize": "",
1304 | "finalize": "",
1305 | "x": 720,
1306 | "y": 340,
1307 | "wires": [[]]
1308 | },
1309 | {
1310 | "id": "bdca0114.d69de",
1311 | "type": "function",
1312 | "z": "f9d383cb.41058",
1313 | "name": "soilpHMsg",
1314 | "func": "if (global.get(\"control\") === true) {\n let timestamp = Date.now();\n let soilpH = global.get(\"soilpH\");\n let payload = {\n [timestamp]: soilpH,\n };\n msg.payload = payload;\n return msg;\n}\nelse {\n return null;\n}",
1315 | "outputs": 1,
1316 | "noerr": 0,
1317 | "initialize": "",
1318 | "finalize": "",
1319 | "x": 710,
1320 | "y": 340,
1321 | "wires": [[]]
1322 | },
1323 | {
1324 | "id": "f33a2102.a728",
1325 | "type": "function",
1326 | "z": "7a111b85.eca174",
1327 | "name": "soilSalinityMsg",
1328 | "func": "if (global.get(\"control\") === true) {\n let timestamp = Date.now();\n let soilSalinity = global.get(\"soilSalinity\");\n let payload = {\n [timestamp]: soilSalinity,\n };\n msg.payload = payload;\n return msg;\n}\nelse {\n return null;\n}",
1329 | "outputs": 1,
1330 | "noerr": 0,
1331 | "initialize": "",
1332 | "finalize": "",
1333 | "x": 720,
1334 | "y": 340,
1335 | "wires": [[]]
1336 | },
1337 | {
1338 | "id": "7c8b78a0.1d4308",
1339 | "type": "debug",
1340 | "z": "bb155f83.a4277",
1341 | "name": "debug",
1342 | "active": true,
1343 | "tosidebar": true,
1344 | "console": false,
1345 | "tostatus": false,
1346 | "complete": "payload",
1347 | "targetType": "msg",
1348 | "statusVal": "",
1349 | "statusType": "auto",
1350 | "x": 890,
1351 | "y": 300,
1352 | "wires": []
1353 | },
1354 | {
1355 | "id": "59fd8bd1.dc7b84",
1356 | "type": "addFirebase",
1357 | "z": "bb155f83.a4277",
1358 | "firebaseCertificate": "",
1359 | "client_email": "",
1360 | "private_key": "",
1361 | "data": "",
1362 | "childpath": "",
1363 | "propertyType": "str",
1364 | "method": "update",
1365 | "newchildpath": "",
1366 | "x": 710,
1367 | "y": 460,
1368 | "wires": [["7c8b78a0.1d4308"]]
1369 | },
1370 | {
1371 | "id": "4085dcbe.3c7024",
1372 | "type": "addFirebase",
1373 | "z": "bb155f83.a4277",
1374 | "firebaseCertificate": "",
1375 | "client_email": "",
1376 | "private_key": "",
1377 | "data": "",
1378 | "childpath": "",
1379 | "propertyType": "str",
1380 | "method": "update",
1381 | "newchildpath": "",
1382 | "x": 710,
1383 | "y": 380,
1384 | "wires": [["7c8b78a0.1d4308"]]
1385 | },
1386 | {
1387 | "id": "fe4fd7ce.70c838",
1388 | "type": "addFirebase",
1389 | "z": "bb155f83.a4277",
1390 | "firebaseCertificate": "",
1391 | "client_email": "",
1392 | "private_key": "",
1393 | "data": "",
1394 | "childpath": "",
1395 | "propertyType": "str",
1396 | "method": "update",
1397 | "newchildpath": "",
1398 | "x": 710,
1399 | "y": 140,
1400 | "wires": [["7c8b78a0.1d4308"]]
1401 | },
1402 | {
1403 | "id": "663e13b2.82511c",
1404 | "type": "addFirebase",
1405 | "z": "bb155f83.a4277",
1406 | "firebaseCertificate": "",
1407 | "client_email": "",
1408 | "private_key": "",
1409 | "data": "",
1410 | "childpath": "",
1411 | "propertyType": "str",
1412 | "method": "update",
1413 | "newchildpath": "",
1414 | "x": 710,
1415 | "y": 220,
1416 | "wires": [["7c8b78a0.1d4308"]]
1417 | }
1418 | ]
1419 |
--------------------------------------------------------------------------------