Data transfer from the dust sensor DSM501 and their processing.

Data transfer from the DSM501 sensor and their processing.
I have an air quality sensor. It sends me 2 values ​​via MQTT. I want from values ​​#1 - values ​​#2. But there is a feature which is this. Data from values ​​No. 1 arrives inconsistently in time (not simultaneously with values ​​No. 2).

What I have learned to do. I take the data of values ​​#1 and send it to an array and then to a google spreadsheet.

And I need to process the data for a period of time or when array 1 is full (because data from values ​​#1 (array 1) comes faster and more often, and data from values ​​#2 (array 2) is slower and not often) and do the calculation again reset the arrays and start filling arrays and calculate when array 1 is full (or take a time interval of 10 seconds and without waiting for the arrays to be filled, calculate the sum of the values ​​of array 1 minus the sum of the values ​​of array 2). At me the new data arrives and mixes up with old.

How can you imagine this for example: you have two taps of water and 2 cups. Beer is flowing rapidly from faucet 1, Water is slowly flowing from faucet 2. Task: to make it so that when at the same time substitute cups and draw beer and water (beer will be filled faster), and then stop taking liquid and from beer minus water we get alcohol. And send the sum further to the calculation (in my case, I will take PM1-2.5 =PM1 - PM2.5 (the value of the sum of array No. 1 - the values ​​of the sum of array No. 2) and calculate the number of aerosol particles per cubic meter (multiply by 0.063612) then I will compare the calculation with the value from the table and get AQI). Help with calculation. I don't learn much about Node-red because I'm new. And My language is not English.
1212

[
    {
        "id": "ce5f9295acae69c9",
        "type": "tab",
        "label": "Поток 1",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "c15babbc86b96938",
        "type": "mqtt in",
        "z": "ce5f9295acae69c9",
        "name": "5",
        "topic": "5",
        "qos": "0",
        "datatype": "auto",
        "broker": "c921ebcdcb990496",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 70,
        "y": 140,
        "wires": [
            [
                "dd0655b255ebba53",
                "c4fba6126fc48066"
            ]
        ]
    },
    {
        "id": "dd0655b255ebba53",
        "type": "json",
        "z": "ce5f9295acae69c9",
        "name": "",
        "property": "payload",
        "action": "obj",
        "pretty": false,
        "x": 230,
        "y": 140,
        "wires": [
            [
                "f4a795ba665dd443",
                "e837b2c033314bc0",
                "b5d22844641e410e"
            ]
        ]
    },
    {
        "id": "e837b2c033314bc0",
        "type": "ui_chart",
        "z": "ce5f9295acae69c9",
        "name": "",
        "group": "9df7d4a7be7d6ef8",
        "order": 2,
        "width": "0",
        "height": "0",
        "label": "chart 1",
        "chartType": "line",
        "legend": "true",
        "xformat": "auto",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "5000",
        "ymax": "50000",
        "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": 730,
        "y": 100,
        "wires": [
            []
        ]
    },
    {
        "id": "c4fba6126fc48066",
        "type": "debug",
        "z": "ce5f9295acae69c9",
        "name": "5",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 270,
        "y": 40,
        "wires": []
    },
    {
        "id": "f4a795ba665dd443",
        "type": "debug",
        "z": "ce5f9295acae69c9",
        "name": "5",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 530,
        "y": 60,
        "wires": []
    },
    {
        "id": "5fdad0a31e59a198",
        "type": "mqtt in",
        "z": "ce5f9295acae69c9",
        "name": "2",
        "topic": "2",
        "qos": "0",
        "datatype": "auto",
        "broker": "c921ebcdcb990496",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 70,
        "y": 460,
        "wires": [
            [
                "e088b00e0a941448",
                "82ef43acd07b8682"
            ]
        ]
    },
    {
        "id": "e088b00e0a941448",
        "type": "json",
        "z": "ce5f9295acae69c9",
        "name": "",
        "property": "payload",
        "action": "obj",
        "pretty": false,
        "x": 230,
        "y": 460,
        "wires": [
            [
                "c11182337f7a4c3b",
                "99a3a3479239a017",
                "148e6f5916686ae2"
            ]
        ]
    },
    {
        "id": "99a3a3479239a017",
        "type": "ui_chart",
        "z": "ce5f9295acae69c9",
        "name": "",
        "group": "9df7d4a7be7d6ef8",
        "order": 2,
        "width": "0",
        "height": "0",
        "label": "chart 2",
        "chartType": "line",
        "legend": "true",
        "xformat": "auto",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "5000",
        "ymax": "70000",
        "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": 390,
        "y": 440,
        "wires": [
            []
        ]
    },
    {
        "id": "82ef43acd07b8682",
        "type": "debug",
        "z": "ce5f9295acae69c9",
        "name": "2",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 250,
        "y": 400,
        "wires": []
    },
    {
        "id": "c11182337f7a4c3b",
        "type": "debug",
        "z": "ce5f9295acae69c9",
        "name": "2",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 430,
        "y": 500,
        "wires": []
    },
    {
        "id": "2f906ea82871ebc1",
        "type": "inject",
        "z": "ce5f9295acae69c9",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "2",
        "payloadType": "num",
        "x": 90,
        "y": 560,
        "wires": [
            [
                "e088b00e0a941448"
            ]
        ]
    },
    {
        "id": "3d249954550d23ce",
        "type": "GSheet",
        "z": "ce5f9295acae69c9",
        "creds": "80ad0a94372d6b76",
        "method": "append",
        "action": "",
        "sheet": "",
        "cells": "",
        "flatten": false,
        "name": "5",
        "x": 710,
        "y": 200,
        "wires": [
            [
                "c098d5b3068a9f5b"
            ]
        ]
    },
    {
        "id": "c098d5b3068a9f5b",
        "type": "debug",
        "z": "ce5f9295acae69c9",
        "name": "5",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 770,
        "y": 320,
        "wires": []
    },
    {
        "id": "f5ee2445bf0c7f9c",
        "type": "debug",
        "z": "ce5f9295acae69c9",
        "name": "2",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 730,
        "y": 160,
        "wires": []
    },
    {
        "id": "b5d22844641e410e",
        "type": "buffer-array",
        "z": "ce5f9295acae69c9",
        "name": "Array 1",
        "bufferLen": "3",
        "startWhenFilled": true,
        "x": 380,
        "y": 200,
        "wires": [
            [
                "e303d128b1a65822"
            ]
        ]
    },
    {
        "id": "e303d128b1a65822",
        "type": "change",
        "z": "ce5f9295acae69c9",
        "name": "Array Sum 1",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "$sum(payload)\t\t",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 550,
        "y": 200,
        "wires": [
            [
                "f5ee2445bf0c7f9c",
                "3d249954550d23ce"
            ]
        ]
    },
    {
        "id": "3a144eae801291e2",
        "type": "GSheet",
        "z": "ce5f9295acae69c9",
        "creds": "80ad0a94372d6b76",
        "method": "append",
        "action": "",
        "sheet": "",
        "cells": "",
        "flatten": false,
        "name": "2",
        "x": 710,
        "y": 620,
        "wires": [
            [
                "d22dd40082f64ff7"
            ]
        ]
    },
    {
        "id": "148e6f5916686ae2",
        "type": "buffer-array",
        "z": "ce5f9295acae69c9",
        "name": "Array 2",
        "bufferLen": "3",
        "startWhenFilled": true,
        "x": 420,
        "y": 620,
        "wires": [
            [
                "067a5a5ef005ecd6"
            ]
        ]
    },
    {
        "id": "067a5a5ef005ecd6",
        "type": "change",
        "z": "ce5f9295acae69c9",
        "name": "Array Sum 2",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "$sum(payload)\t\t",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 570,
        "y": 620,
        "wires": [
            [
                "3a144eae801291e2"
            ]
        ]
    },
    {
        "id": "d22dd40082f64ff7",
        "type": "debug",
        "z": "ce5f9295acae69c9",
        "name": "2",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 730,
        "y": 700,
        "wires": []
    },
    {
        "id": "c8603859a4f18752",
        "type": "ui_spacer",
        "z": "ce5f9295acae69c9",
        "name": "spacer",
        "group": "9df7d4a7be7d6ef8",
        "order": 1,
        "width": 1,
        "height": 1
    },
    {
        "id": "0745b821a53b8fcc",
        "type": "ui_spacer",
        "z": "ce5f9295acae69c9",
        "name": "spacer",
        "group": "9df7d4a7be7d6ef8",
        "order": 1,
        "width": 1,
        "height": 1
    },
    {
        "id": "c921ebcdcb990496",
        "type": "mqtt-broker",
        "name": "8266server",
        "broker": "",
        "port": "1883",
        "clientid": "10",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": false,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "sessionExpiry": ""
    },
    {
        "id": "9df7d4a7be7d6ef8",
        "type": "ui_group",
        "name": "Air purity",
        "tab": "33495f98ffb09225",
        "order": 1,
        "disp": true,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "80ad0a94372d6b76",
        "type": "gauth",
        "name": "Unknown"
    },
    {
        "id": "33495f98ffb09225",
        "type": "ui_tab",
        "name": "Home",
        "icon": "dashboard",
        "disabled": false,
        "hidden": false
    }
]

Would it be easier to join the payloiads and send on every time there is a new reading coming in. Not sure what your calc is but here is an example of how to set it up. I also put both your line charts into one chart, and outputted JS objects from your mqtt nodes..

[{"id":"c15babbc86b96938","type":"mqtt in","z":"ce5f9295acae69c9","name":"5","topic":"5","qos":"0","datatype":"json","broker":"c921ebcdcb990496","x":50,"y":140,"wires":[["c4fba6126fc48066","23fb5c8b.eb03f4"]]},{"id":"c4fba6126fc48066","type":"debug","z":"ce5f9295acae69c9","name":"input","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":250,"y":40,"wires":[]},{"id":"23fb5c8b.eb03f4","type":"change","z":"ce5f9295acae69c9","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"sensor_1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":250,"y":120,"wires":[["e837b2c033314bc0","55c6d3fe.c9a704"]]},{"id":"5fdad0a31e59a198","type":"mqtt in","z":"ce5f9295acae69c9","name":"2","topic":"2","qos":"0","datatype":"json","broker":"c921ebcdcb990496","x":50,"y":220,"wires":[["31e710ee.e5077","c4fba6126fc48066"]]},{"id":"e837b2c033314bc0","type":"ui_chart","z":"ce5f9295acae69c9","name":"","group":"9df7d4a7be7d6ef8","order":2,"width":"0","height":"0","label":"chart 1","chartType":"line","legend":"true","xformat":"auto","interpolate":"linear","nodata":"","dot":false,"ymin":"5000","ymax":"50000","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":520,"y":100,"wires":[[]]},{"id":"55c6d3fe.c9a704","type":"join","z":"ce5f9295acae69c9","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"1","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":190,"y":240,"wires":[["31a3e9a9.04f37e"]]},{"id":"31e710ee.e5077","type":"change","z":"ce5f9295acae69c9","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"sensor_2","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":250,"y":160,"wires":[["e837b2c033314bc0","55c6d3fe.c9a704"]]},{"id":"31a3e9a9.04f37e","type":"function","z":"ce5f9295acae69c9","name":"do calc with two readings","func":"let output = (msg.payload.sensor_1 - msg.payload.sensor_2) * 0.063612;\nmsg.payload = output\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":400,"y":240,"wires":[["d7a1701e.65f798"]]},{"id":"d7a1701e.65f798","type":"switch","z":"ce5f9295acae69c9","name":"","property":"payload","propertyType":"msg","rules":[{"t":"btwn","v":"0","vt":"num","v2":"50","v2t":"num"},{"t":"btwn","v":"51","vt":"num","v2":"100","v2t":"num"},{"t":"btwn","v":"101","vt":"num","v2":"150","v2t":"num"}],"checkall":"true","repair":false,"outputs":3,"x":620,"y":240,"wires":[["26ea6f84.66991"],["ab0f2177.64703"],["3a487ebf.4d0b12"]]},{"id":"26ea6f84.66991","type":"change","z":"ce5f9295acae69c9","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"Good","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":820,"y":200,"wires":[["f4a795ba665dd443"]]},{"id":"ab0f2177.64703","type":"change","z":"ce5f9295acae69c9","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"Moderate","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":820,"y":240,"wires":[["f4a795ba665dd443"]]},{"id":"3a487ebf.4d0b12","type":"change","z":"ce5f9295acae69c9","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"UnHealthy for Sensitive","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":820,"y":280,"wires":[["f4a795ba665dd443"]]},{"id":"f4a795ba665dd443","type":"debug","z":"ce5f9295acae69c9","name":"output","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":980,"y":140,"wires":[]},{"id":"c921ebcdcb990496","type":"mqtt-broker","name":"8266server","broker":"","port":"1883","clientid":"10","usetls":false,"keepalive":"60","cleansession":false,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"9df7d4a7be7d6ef8","type":"ui_group","name":"Air purity","tab":"33495f98ffb09225","order":1,"disp":true,"width":"6","collapse":false,"className":""},{"id":"33495f98ffb09225","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

The join node will initially wait for the two incoming messages, then output when either mqtt node sends a message, using the previous reading from the other sensor.

Hello. How to add a cycle so that array 1 is filled, then only the number is calculated, then the calculation goes further to the chart. It can be done? Or output the average. But there will be a lot of output values per day, and air pollution will need to be calculated in a moment in 5 - 10 minutes, for example. (For reference 2 and 5, data is output from one sensor). Thank you.

[
    {
        "id": "ce5f9295acae69c9",
        "type": "tab",
        "label": "Поток 1",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "d9e43cdbddefe610",
        "type": "mqtt in",
        "z": "ce5f9295acae69c9",
        "name": "5",
        "topic": "5",
        "qos": "0",
        "datatype": "json",
        "broker": "c921ebcdcb990496",
        "inputs": 0,
        "x": 90,
        "y": 140,
        "wires": [
            [
                "b3bc4699bc0dbba0"
            ]
        ]
    },
    {
        "id": "b3bc4699bc0dbba0",
        "type": "change",
        "z": "ce5f9295acae69c9",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "sensor_1",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 300,
        "y": 160,
        "wires": [
            [
                "c378cb77d7b54ce0"
            ]
        ]
    },
    {
        "id": "aa487c23869eb73b",
        "type": "mqtt in",
        "z": "ce5f9295acae69c9",
        "name": "2",
        "topic": "2",
        "qos": "0",
        "datatype": "json",
        "broker": "c921ebcdcb990496",
        "inputs": 0,
        "x": 90,
        "y": 260,
        "wires": [
            [
                "d738a36649209983"
            ]
        ]
    },
    {
        "id": "fdcf8bbc80d46954",
        "type": "ui_chart",
        "z": "ce5f9295acae69c9",
        "name": "",
        "group": "9df7d4a7be7d6ef8",
        "order": 2,
        "width": "0",
        "height": "0",
        "label": "chart 1",
        "chartType": "line",
        "legend": "true",
        "xformat": "auto",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "5000",
        "ymax": "50000",
        "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": 1030,
        "y": 560,
        "wires": [
            []
        ]
    },
    {
        "id": "c378cb77d7b54ce0",
        "type": "join",
        "z": "ce5f9295acae69c9",
        "name": "",
        "mode": "custom",
        "build": "object",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": "\\n",
        "joinerType": "str",
        "accumulate": true,
        "timeout": "1",
        "count": "2",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "",
        "reduceFixup": "",
        "x": 230,
        "y": 400,
        "wires": [
            [
                "fdd2ac07aa52f9c3"
            ]
        ]
    },
    {
        "id": "d738a36649209983",
        "type": "change",
        "z": "ce5f9295acae69c9",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "sensor_2",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 340,
        "y": 240,
        "wires": [
            [
                "c378cb77d7b54ce0"
            ]
        ]
    },
    {
        "id": "fdd2ac07aa52f9c3",
        "type": "function",
        "z": "ce5f9295acae69c9",
        "name": "do calc with two readings",
        "func": "let output = (msg.payload.sensor_1 - msg.payloadsensor_2) * 0.063612;\nif counter = 20 \n\nmsg.payload = output\n\nreturn counter;\n\nreturn msg;",
        "outputs": 1,
        "noerr": 3,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 450,
        "y": 400,
        "wires": [
            [
                "331d261ad0606b70"
            ]
        ]
    },
    {
        "id": "331d261ad0606b70",
        "type": "switch",
        "z": "ce5f9295acae69c9",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "btwn",
                "v": "0",
                "vt": "num",
                "v2": "50",
                "v2t": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 650,
        "y": 400,
        "wires": [
            [
                "e3136985eabd9c79"
            ]
        ]
    },
    {
        "id": "e3136985eabd9c79",
        "type": "change",
        "z": "ce5f9295acae69c9",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "Good",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 850,
        "y": 400,
        "wires": [
            [
                "a8ac8970ed9ff09d",
                "fdcf8bbc80d46954"
            ]
        ]
    },
    {
        "id": "a8ac8970ed9ff09d",
        "type": "debug",
        "z": "ce5f9295acae69c9",
        "name": "output",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1050,
        "y": 200,
        "wires": []
    },
    {
        "id": "c13464a3a951f783",
        "type": "counter",
        "z": "ce5f9295acae69c9",
        "name": "",
        "init": "0",
        "step": "1",
        "lower": "",
        "upper": "",
        "mode": "increment",
        "outputs": "2",
        "x": 440,
        "y": 520,
        "wires": [
            [],
            []
        ]
    },
    {
        "id": "c8603859a4f18752",
        "type": "ui_spacer",
        "z": "ce5f9295acae69c9",
        "name": "spacer",
        "group": "9df7d4a7be7d6ef8",
        "order": 1,
        "width": 1,
        "height": 1
    },
    {
        "id": "0745b821a53b8fcc",
        "type": "ui_spacer",
        "z": "ce5f9295acae69c9",
        "name": "spacer",
        "group": "9df7d4a7be7d6ef8",
        "order": 1,
        "width": 1,
        "height": 1
    },
    {
        "id": "c921ebcdcb990496",
        "type": "mqtt-broker",
        "name": "8266server",
        "broker": "",
        "port": "1883",
        "clientid": "10",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": false,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "sessionExpiry": ""
    },
    {
        "id": "9df7d4a7be7d6ef8",
        "type": "ui_group",
        "name": "Air purity",
        "tab": "33495f98ffb09225",
        "order": 1,
        "disp": true,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "33495f98ffb09225",
        "type": "ui_tab",
        "name": "Home",
        "icon": "dashboard",
        "disabled": false,
        "hidden": false
    }
]

mqtt node 1 sends 30 messages in 1 minute, and mqtt node 2 sends 10 messages in 1 minute. you need to collect all messages from the first minus the second, then after 1 minute send the result to the output, and reset the arrays and fill them again.

It doe not matter that there is a difference in message deliver time. You just use the last receive message to do calc when a new message from either sensor comes in. You are over complicating the flow.
You can then use the smooth node to average your calc output over a time period, or similar.

how to add a cycle? You will need to reset the accumulated calculations and count again. Perhaps you're right that I'm overcomplicating the task. If we consider your option, then the next question is how to average out of 100 values or in 1 minute.
Yes, I will have to think about averaging.

Use the smooth node to average input and then do calc after join, then add calc to payload object, then split to send to chart. The cycle would then be 1 minute, e.g.

[{"id":"a9d80c2a.3e1b98","type":"inject","z":"bf9e1e33.030598","name":"test sensor  1","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"2","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"$floor($random()*50)+100","payloadType":"jsonata","x":170,"y":2760,"wires":[["b62a7bb8.ca7658"]]},{"id":"b62a7bb8.ca7658","type":"smooth","z":"bf9e1e33.030598","name":"","property":"payload","action":"mean","count":"30","round":"2","mult":"single","reduce":true,"x":260,"y":2840,"wires":[["ac6565e9.8f9f08","a10a219.88c1be"]]},{"id":"dd4d76ff.350638","type":"mqtt in","z":"bf9e1e33.030598","name":"5","topic":"5","qos":"0","datatype":"json","broker":"d675b749.04b9c8","x":90,"y":2840,"wires":[["b62a7bb8.ca7658"]]},{"id":"ac6565e9.8f9f08","type":"change","z":"bf9e1e33.030598","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"sensor_1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":2860,"wires":[["39a033d5.2dd904"]]},{"id":"a10a219.88c1be","type":"debug","z":"bf9e1e33.030598","name":"input 1","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":460,"y":2780,"wires":[]},{"id":"39a033d5.2dd904","type":"join","z":"bf9e1e33.030598","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":390,"y":2980,"wires":[["99613269.8ed48"]]},{"id":"99613269.8ed48","type":"function","z":"bf9e1e33.030598","name":"do calc with two readings","func":"let output = (msg.payload.sensor_1 - msg.payload.sensor_2) * 0.063612;\nmsg.payload.quality = output\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":600,"y":2980,"wires":[["5fcb1310.16b994","5efd47b9.49dd58"]]},{"id":"e4ab8df4.256448","type":"change","z":"bf9e1e33.030598","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"sensor_2","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":2900,"wires":[["39a033d5.2dd904"]]},{"id":"5fcb1310.16b994","type":"split","z":"bf9e1e33.030598","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"topic","x":730,"y":2880,"wires":[["af2c094b.4549e8"]]},{"id":"5efd47b9.49dd58","type":"debug","z":"bf9e1e33.030598","name":"output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":940,"y":3000,"wires":[]},{"id":"86472664.d1f6a8","type":"smooth","z":"bf9e1e33.030598","name":"","property":"payload","action":"mean","count":"10","round":"2","mult":"single","reduce":true,"x":260,"y":2920,"wires":[["e4ab8df4.256448","7a569d7b.7ed9fc"]]},{"id":"af2c094b.4549e8","type":"ui_chart","z":"bf9e1e33.030598","name":"","group":"9df7d4a7be7d6ef8","order":2,"width":"0","height":"0","label":"combined chart","chartType":"line","legend":"true","xformat":"auto","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":900,"y":2880,"wires":[[]]},{"id":"6e47b612.c205a8","type":"mqtt in","z":"bf9e1e33.030598","name":"2","topic":"2","qos":"0","datatype":"json","broker":"d675b749.04b9c8","x":110,"y":2940,"wires":[["86472664.d1f6a8"]]},{"id":"c9179159.5dc0e","type":"inject","z":"bf9e1e33.030598","name":"test sensor 2","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"6","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"$floor($random()*50)+50","payloadType":"jsonata","x":190,"y":2880,"wires":[["86472664.d1f6a8"]]},{"id":"7a569d7b.7ed9fc","type":"debug","z":"bf9e1e33.030598","name":"input 2","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":450,"y":2820,"wires":[]},{"id":"171b05ad.8cdfaa","type":"inject","z":"bf9e1e33.030598","name":"reset","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[]","payloadType":"json","x":650,"y":2820,"wires":[["af2c094b.4549e8"]]},{"id":"d675b749.04b9c8","type":"mqtt-broker","name":"Localhost","broker":"localhost","port":"1883","clientid":"","usetls":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"9df7d4a7be7d6ef8","type":"ui_group","name":"Air purity","tab":"33495f98ffb09225","order":1,"disp":true,"width":"6","collapse":false,"className":""},{"id":"33495f98ffb09225","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

how it looks after 15 mins running

Hi. I think that you should not hope to get reliable data on air quality from the sensor in comparison with expensive devices from the store. Therefore, I came to the conclusion that it is necessary to create 2 environments for the sensor - this is clean air and dirty air, and then interpret the data into a graph.
I encountered difficulties in the program and I think that Nod red from lacks the simplicity and speed of creating programs. In general, the program is good, but if it had the ease and simplicity of the Flprog program, it would be better in its understanding. The problem is how to find what you need, then understand how it works - it takes a very long time, a lot of time is wasted. Thanks for the help.

[
    {
        "id": "3d679b098f700882",
        "type": "tab",
        "label": "Поток 1",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "f432e5fc81af4349",
        "type": "ui_chart",
        "z": "3d679b098f700882",
        "name": "",
        "group": "9df7d4a7be7d6ef8",
        "order": 2,
        "width": "3",
        "height": "4",
        "label": "chart 1",
        "chartType": "line",
        "legend": "true",
        "xformat": "HH:mm",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "-1000",
        "ymax": "1000",
        "removeOlder": "25",
        "removeOlderPoints": "",
        "removeOlderUnit": "3600",
        "cutout": 0,
        "useOneColor": false,
        "useUTC": true,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "outputs": 1,
        "useDifferentColor": false,
        "className": "",
        "x": 870,
        "y": 180,
        "wires": [
            []
        ]
    },
    {
        "id": "d75c5d33c107ae92",
        "type": "switch",
        "z": "3d679b098f700882",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "btwn",
                "v": "0",
                "vt": "num",
                "v2": "1000",
                "v2t": "num"
            },
            {
                "t": "btwn",
                "v": "-1",
                "vt": "num",
                "v2": "-1000",
                "v2t": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 550,
        "y": 220,
        "wires": [
            [
                "7f1e9fd1bb40db6f"
            ],
            [
                "3f766a7805a72532"
            ]
        ]
    },
    {
        "id": "7f1e9fd1bb40db6f",
        "type": "change",
        "z": "3d679b098f700882",
        "name": "Good",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "Good",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 690,
        "y": 260,
        "wires": [
            [
                "727b6d365377bfeb",
                "719aebdae335cd28",
                "699627c45ac75fc4"
            ]
        ]
    },
    {
        "id": "727b6d365377bfeb",
        "type": "debug",
        "z": "3d679b098f700882",
        "name": "output",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 910,
        "y": 260,
        "wires": []
    },
    {
        "id": "5b5c67e7787cc708",
        "type": "aggregator",
        "z": "3d679b098f700882",
        "name": "Среднее",
        "topic": "output",
        "intervalCount": "30",
        "intervalUnits": "s",
        "submitIncompleteInterval": false,
        "submitPerTopic": false,
        "aggregationType": "median",
        "x": 380,
        "y": 100,
        "wires": [
            [
                "38eb0bfab172b159",
                "d3c3fcdcb8641288",
                "d19b073e6c3d6918"
            ]
        ]
    },
    {
        "id": "3f766a7805a72532",
        "type": "change",
        "z": "3d679b098f700882",
        "name": "Not Good",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "Not Good",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 660,
        "y": 320,
        "wires": [
            [
                "5b9cd5be87d4f5fa",
                "719aebdae335cd28",
                "699627c45ac75fc4"
            ]
        ]
    },
    {
        "id": "4fb304166996fa19",
        "type": "debug",
        "z": "3d679b098f700882",
        "name": "output 2",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 860,
        "y": 120,
        "wires": []
    },
    {
        "id": "5b9cd5be87d4f5fa",
        "type": "debug",
        "z": "3d679b098f700882",
        "name": "output",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 910,
        "y": 320,
        "wires": []
    },
    {
        "id": "581295137514e162",
        "type": "mqtt in",
        "z": "3d679b098f700882",
        "name": "2",
        "topic": "2",
        "qos": "0",
        "datatype": "auto",
        "broker": "8322a94942cac09c",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 70,
        "y": 60,
        "wires": [
            [
                "23963dfe5cbc3c5d"
            ]
        ]
    },
    {
        "id": "23963dfe5cbc3c5d",
        "type": "json",
        "z": "3d679b098f700882",
        "name": "2",
        "property": "payload",
        "action": "obj",
        "pretty": false,
        "x": 210,
        "y": 60,
        "wires": [
            [
                "5b5c67e7787cc708",
                "542a4ca34125bcdb"
            ]
        ]
    },
    {
        "id": "40ef8f8e077eae1f",
        "type": "mqtt in",
        "z": "3d679b098f700882",
        "name": "5",
        "topic": "5",
        "qos": "0",
        "datatype": "utf8",
        "broker": "8322a94942cac09c",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 70,
        "y": 120,
        "wires": [
            [
                "d95e7d0220225b44"
            ]
        ]
    },
    {
        "id": "d95e7d0220225b44",
        "type": "json",
        "z": "3d679b098f700882",
        "name": "5",
        "property": "payload",
        "action": "obj",
        "pretty": false,
        "x": 110,
        "y": 240,
        "wires": [
            [
                "63751fdcdb3b3f6c"
            ]
        ]
    },
    {
        "id": "542a4ca34125bcdb",
        "type": "debug",
        "z": "3d679b098f700882",
        "name": "output",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 390,
        "y": 40,
        "wires": []
    },
    {
        "id": "38eb0bfab172b159",
        "type": "debug",
        "z": "3d679b098f700882",
        "name": "output 1",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 540,
        "y": 380,
        "wires": []
    },
    {
        "id": "208b4b6f6cb043f4",
        "type": "debug",
        "z": "3d679b098f700882",
        "name": "output",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 150,
        "y": 400,
        "wires": []
    },
    {
        "id": "63751fdcdb3b3f6c",
        "type": "calculator",
        "z": "3d679b098f700882",
        "name": "умножил на -1",
        "inputMsgField": "payload",
        "outputMsgField": "payload",
        "operation": "mult",
        "constant": "-1",
        "round": false,
        "decimals": 0,
        "x": 120,
        "y": 320,
        "wires": [
            [
                "5b5c67e7787cc708",
                "208b4b6f6cb043f4"
            ]
        ]
    },
    {
        "id": "d3c3fcdcb8641288",
        "type": "calculator",
        "z": "3d679b098f700882",
        "name": "умножил на 0,063612",
        "inputMsgField": "payload",
        "outputMsgField": "payload",
        "operation": "mult",
        "constant": "0.063612",
        "round": true,
        "decimals": "1",
        "x": 600,
        "y": 100,
        "wires": [
            [
                "4fb304166996fa19",
                "f432e5fc81af4349",
                "d75c5d33c107ae92",
                "7ef0507ce6063230"
            ]
        ]
    },
    {
        "id": "719aebdae335cd28",
        "type": "ui_text",
        "z": "3d679b098f700882",
        "group": "9df7d4a7be7d6ef8",
        "order": 18,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "text",
        "format": "{{msg.payload}}",
        "layout": "row-left",
        "className": "",
        "x": 910,
        "y": 380,
        "wires": []
    },
    {
        "id": "699627c45ac75fc4",
        "type": "mqtt out",
        "z": "3d679b098f700882",
        "name": "air quality =airq",
        "topic": "airq",
        "qos": "0",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "8322a94942cac09c",
        "x": 900,
        "y": 480,
        "wires": []
    },
    {
        "id": "7ef0507ce6063230",
        "type": "mqtt out",
        "z": "3d679b098f700882",
        "name": "n air quality=nairq",
        "topic": "nairq",
        "qos": "0",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "8322a94942cac09c",
        "x": 890,
        "y": 40,
        "wires": []
    },
    {
        "id": "d19b073e6c3d6918",
        "type": "range",
        "z": "3d679b098f700882",
        "minin": "-10000",
        "maxin": "15000",
        "minout": "0",
        "maxout": "1000",
        "action": "scale",
        "round": true,
        "property": "payload",
        "name": "",
        "x": 400,
        "y": 500,
        "wires": [
            [
                "852613ab49f4fc27",
                "bd51a0068ec3e690"
            ]
        ]
    },
    {
        "id": "852613ab49f4fc27",
        "type": "debug",
        "z": "3d679b098f700882",
        "name": "output 3",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 580,
        "y": 560,
        "wires": []
    },
    {
        "id": "bd51a0068ec3e690",
        "type": "ui_chart",
        "z": "3d679b098f700882",
        "name": "",
        "group": "9df7d4a7be7d6ef8",
        "order": 2,
        "width": "3",
        "height": "4",
        "label": "chart 2",
        "chartType": "line",
        "legend": "true",
        "xformat": "HH:mm",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "0",
        "ymax": "1000",
        "removeOlder": "25",
        "removeOlderPoints": "",
        "removeOlderUnit": "3600",
        "cutout": 0,
        "useOneColor": false,
        "useUTC": true,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "outputs": 1,
        "useDifferentColor": false,
        "className": "",
        "x": 570,
        "y": 500,
        "wires": [
            []
        ]
    },
    {
        "id": "ad1092c976db347b",
        "type": "ui_spacer",
        "z": "3d679b098f700882",
        "name": "spacer",
        "group": "9df7d4a7be7d6ef8",
        "order": 1,
        "width": 1,
        "height": 1
    },
    {
        "id": "19b83f32e01c752e",
        "type": "ui_spacer",
        "z": "3d679b098f700882",
        "name": "spacer",
        "group": "9df7d4a7be7d6ef8",
        "order": 1,
        "width": 1,
        "height": 1
    },
    {
        "id": "6f2269feee3dfdca",
        "type": "ui_spacer",
        "z": "3d679b098f700882",
        "name": "spacer",
        "group": "9df7d4a7be7d6ef8",
        "order": 1,
        "width": "0",
        "height": "0"
    },
    {
        "id": "9df7d4a7be7d6ef8",
        "type": "ui_group",
        "name": "Air purity",
        "tab": "91885429.d46108",
        "order": 1,
        "disp": true,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "8322a94942cac09c",
        "type": "mqtt-broker",
        "name": "8266server",
        "broker": "192.168.4.1",
        "port": "1883",
        "clientid": "10",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": false,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "sessionExpiry": "",
        "credentials": {
            "user": "",
            "password": ""
        }
    },
    {
        "id": "91885429.d46108",
        "type": "ui_tab",
        "name": "Monitoramento On-Line",
        "icon": "dashboard",
        "order": 1,
        "disabled": false,
        "hidden": false
    }
]