JQ-300 Sensor Read values from cloud to InfluxDB
JQ-300 Sensor Workflow
JQ-300 is a cheap air quality sensor you can find on Aliexpress or similar stores.
It gives you several readings: temperature, humidity, PM2.5, HCHO, TVOC, and eCO2.
This workflow reads and parses sensor data from ypyt cloud for given device token and sends them to an InfluxDB database.
see https://github.com/xoseperez/espurna/issues/1644 for more context extracted from https://gist.github.com/zerog2k/b3afcaf3ff92a60474a159c7044dc8ce
How to get device token
To get a device token, you have to capture traffic between perthings mobile app and the cloud, and look for the response to this request:
GET /ypyt-api/api/app/deviceManager... Host: www.youpinyuntai.com:32086 [ ... ]
On the JSON response, look for the deviceToken parameter.
Additional info
This enumerators serve as pointers to get the meaning of each of the values returned from the cloud:
SEQ_TYPES = [ None, None, None, None, "temp", "hum", "PM2.5", "HCHO", "TVOC", "eCO2", None ] SEQ_UNITS = [ None, None, None, None, "C", "%", "ug/m^3", "mg/m^3", "mg/m^3", "ppm", None ]
Received MQTT packet example:
{ "type": "V", "content": [ { "content": "2", "dptId": 1, "seq": 1, "deviceToken": "XXXXXXXXXXXXXXXXXXXX" }, { "content": null, "dptId": 1, "seq": 2, "deviceToken": "" }, { "content": null, "dptId": 1, "seq": 3, "deviceToken": "" }, { "content": "16", "dptId": 1, "seq": 4, "deviceToken": "" }, { "content": "73", "dptId": 1, "seq": 5, "deviceToken": "" }, { "content": "31", "dptId": 1, "seq": 6, "deviceToken": "" }, { "content": "6.883", "dptId": 1, "seq": 7, "deviceToken": "" }, { "content": "100.002", "dptId": 1, "seq": 8, "deviceToken": "" }, { "content": "1671", "dptId": 1, "seq": 9, "deviceToken": "" }, { "content": "2700", "dptId": 1, "seq": 10, "deviceToken": "" } ], "deviceToken": "XXXXXXXXXXXXXXXXXXXX" }
[{"id":"98dbc86a.74e228","type":"tab","label":"JQ-300","disabled":false,"info":"# JQ-300 Workflow\n\nReads and parses sensor data from ypyt cloud for given device token.\n\nsee https://github.com/xoseperez/espurna/issues/1644 for more context\nextracted from https://gist.github.com/zerog2k/b3afcaf3ff92a60474a159c7044dc8ce\n\n## How to get device token\n\nTo get a device token, you have to capture traffic between perthings mobile app and the cloud, and look for the response to this request:\n\nGET /ypyt-api/api/app/deviceManager...\nHost: www.youpinyuntai.com:32086\n[ ... ]\n\nOn the JSON response, look for the deviceToken parameter.\n\nThis enumerators serve as pointers to get the meaning of each of the values returned from the cloud:\n\nSEQ_TYPES = [ None, None, None, None, \"temp\", \"hum\", \"PM2.5\", \"HCHO\", \"TVOC\", \"eCO2\", None ]\nSEQ_UNITS = [ None, None, None, None, \"C\", \"%\", \"ug/m^3\", \"mg/m^3\", \"mg/m^3\", \"ppm\", None ]\n\nReceived MQTT packet example:\n\n{\n \"type\": \"V\",\n\t \"content\": [\n\t {\n\t \"content\": \"2\",\n\t \"dptId\": 1,\n\t \"seq\": 1,\n\t \"deviceToken\": \"XXXXXXXXXXXXXXXXXXXX\"\n\t },\n\t {\n\t \"content\": null,\n\t \"dptId\": 1,\n\t \"seq\": 2,\n\t \"deviceToken\": \"\"\n\t },\n\t {\n\t \"content\": null,\n\t \"dptId\": 1,\n\t \"seq\": 3,\n\t \"deviceToken\": \"\"\n\t },\n\t {\n\t \"content\": \"16\",\n\t \"dptId\": 1,\n\t \"seq\": 4,\n\t \"deviceToken\": \"\"\n\t },\n\t {\n\t \"content\": \"73\",\n\t \"dptId\": 1,\n\t \"seq\": 5,\n\t \"deviceToken\": \"\"\n\t },\n\t {\n\t \"content\": \"31\",\n\t \"dptId\": 1,\n\t \"seq\": 6,\n\t \"deviceToken\": \"\"\n\t },\n\t {\n\t \"content\": \"6.883\",\n\t \"dptId\": 1,\n\t \"seq\": 7,\n\t \"deviceToken\": \"\"\n\t },\n\t {\n\t \"content\": \"100.002\",\n\t \"dptId\": 1,\n\t \"seq\": 8,\n\t \"deviceToken\": \"\"\n\t },\n\t {\n\t \"content\": \"1671\",\n\t \"dptId\": 1,\n\t \"seq\": 9,\n\t \"deviceToken\": \"\"\n\t },\n\t {\n\t \"content\": \"2700\",\n\t \"dptId\": 1,\n\t \"seq\": 10,\n\t \"deviceToken\": \"\"\n\t }\n\t],\n \"deviceToken\": \"XXXXXXXXXXXXXXXXXXXX\"\n}"},{"id":"33de5d74.fdfee2","type":"mqtt in","z":"98dbc86a.74e228","name":"mqtt get from jq-300 cloud","topic":"XXXXXXXXXXXXXXXXXXXX","qos":"2","datatype":"auto","broker":"3f2b1d65.d18a82","x":230,"y":220,"wires":[["f47cd4fc.16ef9"]]},{"id":"c62d9446.d90438","type":"debug","z":"98dbc86a.74e228","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":870,"y":180,"wires":[]},{"id":"5513769d.fd454","type":"function","z":"98dbc86a.74e228","name":"","func":"var SEQ_TYPES = [ null, null, null, null, \"temp\", \"hum\", \"PM2.5\", \"HCHO\", \"TVOC\", \"eCO2\", null ];\nvar SEQ_UNITS = [ null, null, null, null, \"C\", \"%\", \"ug/m^3\", \"mg/m^3\", \"mg/m^3\", \"ppm\", null ];\nvar i;\nvar newPayload = {};\n\n\nvar sensor = msg.payload.deviceToken;\n\nfor (i=0; i < msg.payload.content.length; i++) {\n var seq = msg.payload.content[i].seq;\n if (SEQ_TYPES[seq] === null) {\n continue\n } else {\n newPayload[SEQ_TYPES[seq]] = msg.payload.content[i].content;\n }\n}\n\nvar newMsg = {payload: [newPayload, {sensor: sensor}]};\nreturn newMsg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":720,"y":220,"wires":[["c62d9446.d90438","427a9c03.be260c"]]},{"id":"f47cd4fc.16ef9","type":"json","z":"98dbc86a.74e228","name":"","property":"payload","action":"","pretty":false,"x":430,"y":220,"wires":[["a9b2f5f7.fcb6"]]},{"id":"a9b2f5f7.fcb6","type":"json","z":"98dbc86a.74e228","name":"","property":"payload.content","action":"","pretty":true,"x":570,"y":220,"wires":[["5513769d.fd454"]]},{"id":"427a9c03.be260c","type":"influxdb out","z":"98dbc86a.74e228","influxdb":"d2400a9b.8fa29","name":"","measurement":"test567","precision":"","retentionPolicy":"","database":"database","precisionV18FluxV20":"ms","retentionPolicyV18Flux":"","org":"organisation","bucket":"bucket","x":930,"y":260,"wires":[]},{"id":"3f2b1d65.d18a82","type":"mqtt-broker","name":"nube jq-300","broker":"mq.youpinyuntai.com","port":"55450","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"d2400a9b.8fa29","type":"influxdb","hostname":"127.0.0.1","port":"8086","protocol":"http","database":"database","name":"influxdb test","usetls":false,"tls":"d50d0c9f.31e858","influxdbVersion":"1.x","url":"http://localhost:8086","rejectUnauthorized":true},{"id":"d50d0c9f.31e858","type":"tls-config","name":"","cert":"","key":"","ca":"","certname":"","keyname":"","caname":"","servername":"","verifyservercert":false}]