SGP40 VOC Gas sensor project

Hello, its been some time since last i was in here.
This time i want to share my latest work.
its a rpi3b with a gas sensor logging the level of volatile organic compunds in the air.
this project is to be installe in a local factory, however, you can use it at home to manage your hvac or what not.
added realtime display on top, and also the possibility for replay whatever it looked like in the data that is logged.
Enjoy :slight_smile:

[
    {
        "id": "6853f0ac528a909d",
        "type": "inject",
        "z": "edb67b270919ddcd",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": "5",
        "topic": "",
        "payload": "1",
        "payloadType": "str",
        "x": 70,
        "y": 20,
        "wires": [
            [
                "dfa00e68a1a1e242"
            ]
        ]
    },
    {
        "id": "dfa00e68a1a1e242",
        "type": "exec",
        "z": "edb67b270919ddcd",
        "command": "python3 /home/pi/Sensirion_SGP40-master/example_sgp40_voc_index.py",
        "addpay": "",
        "append": "",
        "useSpawn": "true",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "run_sensor",
        "x": 230,
        "y": 40,
        "wires": [
            [
                "a3159d04582037b2"
            ],
            [],
            []
        ]
    },
    {
        "id": "a3159d04582037b2",
        "type": "function",
        "z": "edb67b270919ddcd",
        "name": "format_data",
        "func": "msg = msg.payload.split(\":\").slice(1, 4).map(e => { return { payload: parseFloat(e) } });\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 230,
        "y": 100,
        "wires": [
            [
                "1afdc931c92d6a9a",
                "cb51da9339906215",
                "26933c4ce1586207"
            ]
        ]
    },
    {
        "id": "1afdc931c92d6a9a",
        "type": "ui_chart",
        "z": "edb67b270919ddcd",
        "name": "trend",
        "group": "2c6cfd085b3f9f40",
        "order": 1,
        "width": "18",
        "height": "6",
        "label": "VOC level 24h",
        "chartType": "line",
        "legend": "false",
        "xformat": "HH:mm:ss",
        "interpolate": "bezier",
        "nodata": "",
        "dot": false,
        "ymin": "0",
        "ymax": "500",
        "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": 450,
        "y": 140,
        "wires": [
            []
        ]
    },
    {
        "id": "cb51da9339906215",
        "type": "function",
        "z": "edb67b270919ddcd",
        "name": "log_data",
        "func": "var str = msg.payload;\nmsg.topic = \"INSERT INTO VOCDATA (voc) VALUES ('\" + str +\"')\";\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 240,
        "y": 140,
        "wires": [
            [
                "1033564e0d655f61"
            ]
        ]
    },
    {
        "id": "1033564e0d655f61",
        "type": "mysql",
        "z": "edb67b270919ddcd",
        "mydb": "500ed4569796efb2",
        "name": "",
        "x": 230,
        "y": 200,
        "wires": [
            []
        ]
    },
    {
        "id": "23527118c4e86aea",
        "type": "ui_date_picker",
        "z": "edb67b270919ddcd",
        "name": "stop",
        "label": "To",
        "group": "68a6973f444db8dd",
        "order": 3,
        "width": "5",
        "height": "1",
        "passthru": false,
        "topic": "stop",
        "topicType": "str",
        "className": "",
        "x": 130,
        "y": 360,
        "wires": [
            [
                "102767a995708cc1"
            ]
        ]
    },
    {
        "id": "03081d373fcf0db4",
        "type": "ui_date_picker",
        "z": "edb67b270919ddcd",
        "name": "start",
        "label": "From",
        "group": "68a6973f444db8dd",
        "order": 2,
        "width": "5",
        "height": "1",
        "passthru": false,
        "topic": "start",
        "topicType": "str",
        "className": "",
        "x": 130,
        "y": 320,
        "wires": [
            [
                "08822362d0ae7a33"
            ]
        ]
    },
    {
        "id": "08822362d0ae7a33",
        "type": "moment",
        "z": "edb67b270919ddcd",
        "name": "",
        "topic": "start",
        "input": "payload",
        "inputType": "msg",
        "inTz": "Europe/Amsterdam",
        "adjAmount": 0,
        "adjType": "days",
        "adjDir": "add",
        "format": "",
        "locale": "en_GB",
        "output": "payload",
        "outputType": "msg",
        "outTz": "Europe/Amsterdam",
        "x": 250,
        "y": 320,
        "wires": [
            [
                "6c85e8628292641f"
            ]
        ]
    },
    {
        "id": "102767a995708cc1",
        "type": "moment",
        "z": "edb67b270919ddcd",
        "name": "",
        "topic": "stop",
        "input": "payload",
        "inputType": "msg",
        "inTz": "Europe/Amsterdam",
        "adjAmount": 0,
        "adjType": "days",
        "adjDir": "add",
        "format": "",
        "locale": "en_GB",
        "output": "payload",
        "outputType": "msg",
        "outTz": "Europe/Amsterdam",
        "x": 250,
        "y": 360,
        "wires": [
            [
                "6c85e8628292641f"
            ]
        ]
    },
    {
        "id": "6c85e8628292641f",
        "type": "function",
        "z": "edb67b270919ddcd",
        "name": "sql",
        "func": "context.start = context.start || \"2000-01-01\"\ncontext.stop = context.stop || \"2099-01-01\"\ncontext.group = context.group || \"0\"\n\nif (msg.topic == \"start\")\n    context.start = msg.payload.slice(0,10) + \"T00:00:00.000Z\";\nif (msg.topic == \"stop\")\n    context.stop =  msg.payload.slice(0,10) + \"T23:59:59.999Z\";\nif (msg.topic == \"datasource\")\n    context.group =  msg.payload;    \n  \n\n\nvar sql = \"\";\nvar outputs = [];\n\n////, curdate(), DATE_FORMAT(TIMESTAMP,' %d/%m %H:%i') AS shortdate\n\n//sql = \"SELECT TIMESTAMP AS x, voc as y from VOCDATA WHERE  timestamp BETWEEN '\" + context.start + \"' AND '\"+context.stop+\"' group by timestamp desc\";\nsql = \"SELECT timestamp, voc from VOCDATA WHERE  timestamp BETWEEN '\" + context.start + \"' AND '\" + context.stop + \"' group by timestamp desc\";\n\noutputs.push({topic:sql});\n\nmsg.payload = [context.group, context.start, context.stop]\n\nreturn [ outputs ];\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 370,
        "y": 340,
        "wires": [
            [
                "cf1915d0daa3e46c",
                "0912aeb92890291f"
            ]
        ]
    },
    {
        "id": "cf1915d0daa3e46c",
        "type": "delay",
        "z": "edb67b270919ddcd",
        "name": "",
        "pauseType": "delay",
        "timeout": "500",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "outputs": 1,
        "x": 550,
        "y": 280,
        "wires": [
            [
                "d549ac9c6276d53d"
            ]
        ]
    },
    {
        "id": "d549ac9c6276d53d",
        "type": "mysql",
        "z": "edb67b270919ddcd",
        "mydb": "500ed4569796efb2",
        "name": "gaslog",
        "x": 530,
        "y": 320,
        "wires": [
            [
                "a6f9a157ec4aa242"
            ]
        ]
    },
    {
        "id": "0912aeb92890291f",
        "type": "function",
        "z": "edb67b270919ddcd",
        "name": "empty",
        "func": "msg.payload = [];\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 530,
        "y": 400,
        "wires": [
            [
                "41c445ea4ef57e61"
            ]
        ]
    },
    {
        "id": "8656853660fd5247",
        "type": "ui_template",
        "z": "edb67b270919ddcd",
        "group": "2c6cfd085b3f9f40",
        "name": "background/banner/time",
        "order": 8,
        "width": "0",
        "height": "0",
        "format": "<style>\n    \n    body {\n        background-image: url(\"/gass.jpg\");\n        background-size: 100% 100%;\n    }\n     md-toolbar {\n        background-image: url(\"/logo_banner.png\");\n        background-size: 100% 100%;\n    }\n</style>\n<script id=\"clockScript\" type=\"text/javascript\">\n    var clockInterval;\n    $(function () {\n        $('#clockScript').parent().hide();\n        if(clockInterval) return;\n        var toolbar = $('.md-toolbar-tools');\n        var div = $('<div/>');\n        var p = $('<p/>');\n        div.append(p);\n        div[0].style.margin = '5px 5px 5px auto';\n        function displayTime() {\n            p.text(new Date().toLocaleString('en-GB')); \n        }\n        toolbar.append(div);\n        clockInterval = setInterval(displayTime, 1000);\n    });\n</script>",
        "storeOutMessages": false,
        "fwdInMessages": false,
        "resendOnRefresh": false,
        "templateScope": "local",
        "className": "",
        "x": 550,
        "y": 20,
        "wires": [
            []
        ]
    },
    {
        "id": "41c445ea4ef57e61",
        "type": "ui_chart",
        "z": "edb67b270919ddcd",
        "name": "trend",
        "group": "68a6973f444db8dd",
        "order": 4,
        "width": "20",
        "height": "6",
        "label": "VOC level historical",
        "chartType": "line",
        "legend": "false",
        "xformat": "HH:mm:ss",
        "interpolate": "bezier",
        "nodata": "",
        "dot": false,
        "ymin": "0",
        "ymax": "500",
        "removeOlder": 1,
        "removeOlderPoints": "",
        "removeOlderUnit": "86400",
        "cutout": 0,
        "useOneColor": false,
        "useUTC": false,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "outputs": 1,
        "useDifferentColor": false,
        "className": "",
        "x": 710,
        "y": 340,
        "wires": [
            []
        ]
    },
    {
        "id": "a6f9a157ec4aa242",
        "type": "function",
        "z": "edb67b270919ddcd",
        "name": "chartformat",
        "func": "//var data = [[{\"x\":1537348236000,\"y\":2493},{\"x\":1537348326000,\"y\":2493}]];\n//\nvar series = [\"VOC Gas Log\"];\nvar labels = [\"Labels\"];\nvar data = [];\n\nvar i, len, string;\n\nfor (i = 1, len = msg.payload.length, string = \"\"; i < len; i++) {\n    data.push({ \"x\": Date.parse(msg.payload[i].timestamp) + 2 * 60 * 60, \"y\": Number(msg.payload[i].voc) });\n}\n\ndata = [data];\n\nmsg.payload = [{ series, data, labels }];\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 550,
        "y": 360,
        "wires": [
            [
                "41c445ea4ef57e61"
            ]
        ]
    },
    {
        "id": "26933c4ce1586207",
        "type": "ui_chart",
        "z": "edb67b270919ddcd",
        "name": "",
        "group": "2c6cfd085b3f9f40",
        "order": 2,
        "width": "2",
        "height": "6",
        "label": "PPM",
        "chartType": "bar",
        "legend": "false",
        "xformat": "HH:mm:ss",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "0",
        "ymax": "500",
        "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": 450,
        "y": 180,
        "wires": [
            []
        ]
    },
    {
        "id": "2c6cfd085b3f9f40",
        "type": "ui_group",
        "name": "Live gas monitor level",
        "tab": "462952f9c42eb84e",
        "order": 1,
        "disp": true,
        "width": "20",
        "collapse": false,
        "className": ""
    },
    {
        "id": "500ed4569796efb2",
        "type": "MySQLdatabase",
        "name": "",
        "host": "127.0.0.1",
        "port": "3306",
        "db": "GasMonitor",
        "tz": "",
        "charset": "UTF8"
    },
    {
        "id": "68a6973f444db8dd",
        "type": "ui_group",
        "name": "Historical gas monitor level",
        "tab": "462952f9c42eb84e",
        "order": 2,
        "disp": true,
        "width": "20",
        "collapse": false,
        "className": ""
    },
    {
        "id": "462952f9c42eb84e",
        "type": "ui_tab",
        "name": "Home",
        "icon": "dashboard",
        "disabled": false,
        "hidden": false
    }
]```
3 Likes