{"id":537,"date":"2021-08-22T17:13:46","date_gmt":"2021-08-22T15:13:46","guid":{"rendered":"https:\/\/www.petersplanet.nl\/?p=537"},"modified":"2021-08-29T14:38:14","modified_gmt":"2021-08-29T12:38:14","slug":"airquality-with-raspberry-pi","status":"publish","type":"post","link":"https:\/\/www.petersplanet.nl\/index.php\/2021\/08\/22\/airquality-with-raspberry-pi\/","title":{"rendered":"Airquality with Raspberry Pi"},"content":{"rendered":"\n<p>I have been experimenting with the Raspberry Pi and the Bosch BME680 and Plantower PMS5003. With the BME680 you can measure temperature, air pressure, humidity, and VOC gas (Volatile Organic Compunds). With the PMS5003 particles can be measured. Also used a Telegraf agent,  Influxdb2 and Grafana.<\/p>\n\n\n\n<!--more-->\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/IMG_1265-1024x768.jpg\" alt=\"\" class=\"wp-image-555\" srcset=\"https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/IMG_1265-1024x768.jpg 1024w, https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/IMG_1265-300x225.jpg 300w, https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/IMG_1265-768x576.jpg 768w, https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/IMG_1265-1140x855.jpg 1140w, https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/IMG_1265.jpg 1215w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>A picture of the experimental setup.<\/p>\n\n\n\n<p>A screenshot of the result in Grafana.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"724\" src=\"https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/airquality-grafana-1024x724.jpg\" alt=\"\" class=\"wp-image-552\" srcset=\"https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/airquality-grafana-1024x724.jpg 1024w, https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/airquality-grafana-300x212.jpg 300w, https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/airquality-grafana-768x543.jpg 768w, https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/airquality-grafana-1140x806.jpg 1140w, https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/airquality-grafana.jpg 1277w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The sensors are being read by a program in Python every 30 seconds. The results are then being written to CSV-files. The CSV-files are being read by a Telegraf agent on the Raspberry Pi. The Telegraf agent then sends the data to an Influxdb database which is being read by the Grafana program. The Influxdb and Grafana are running on a server in AWS.<\/p>\n\n\n\n<p>The queries in Flux in Grafana can be created with the Data Explorer in InfluxDB 2.0. <br>Example for a query is: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from(bucket: \"airquality\")\n  |&gt; range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |&gt; filter(fn: (r) =&gt; r&#91;\"_measurement\"] == \"file\")\n  |&gt; filter(fn: (r) =&gt; r&#91;\"_field\"] == \"humidity\")\n  |&gt; filter(fn: (r) =&gt; r&#91;\"host\"] == \"raspberrypi\")\n  |&gt; aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |&gt; yield(name: \"mean\")<\/code><\/pre>\n\n\n\n<p>The aggregateWindow() function is important to prevent the following error:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>A query returned too many datapoints and the results have been truncated at 4191 points to prevent memory issues. At the current graph size, Grafana can only draw 419. Try using the aggregateWindow() function in your query to reduce the number of points returned.<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>Screenshots of the .CSV files on the Raspberry Pi.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"479\" height=\"169\" src=\"https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/bme680.jpg\" alt=\"\" class=\"wp-image-557\" srcset=\"https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/bme680.jpg 479w, https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/bme680-300x106.jpg 300w\" sizes=\"auto, (max-width: 479px) 100vw, 479px\" \/><figcaption>bme680 sensor (timestamp UTC, temperature, air pressure, humidity %, voc gas value)<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"475\" height=\"184\" src=\"https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/pms5003.jpg\" alt=\"\" class=\"wp-image-558\" srcset=\"https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/pms5003.jpg 475w, https:\/\/www.petersplanet.nl\/wp-content\/uploads\/2021\/08\/pms5003-300x116.jpg 300w\" sizes=\"auto, (max-width: 475px) 100vw, 475px\" \/><figcaption>PMS5003 (timestamp UTC, pm2.5, pm10) <\/figcaption><\/figure>\n\n\n\n<p>Python snippet to create the CSV-file.<br>Without the flush() the data will not be written directly to the CSV-file but cached. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>f_pms5003 = open(\"\/opt\/airquality-pi\/pms5003.csv\", mode='a+t')\npms.readData()\nif pms.data:\n    nowutc = datetime.datetime.utcnow()\n    date_time = nowutc.strftime('%Y-%m-%dT%H:%M:%SZ')  \n    pms_output = '{0},{1},{2}'.format(date_time,pms.getPM2_5(),pms.getPM10())\n    f_pms5003.write(pms_output + \"\\n\")\n    f_pms5003.flush()<\/code><\/pre>\n\n\n\n<p>Telegraf is running as a systemd service on the Raspberry Pi. <br>Created a file airquality-pi.service for this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Unit]\nDescription=Airquality Pi\nAfter=network.target\n\n&#91;Service]\nType=simple\nUser=pi\nWorkingDirectory=\/opt\/airquality-pi\nExecStart=\/opt\/airquality-pi\/airquality-pi.sh\n\n&#91;Install]\nWantedBy=multi-user.target\n<\/code><\/pre>\n\n\n\n<p>airquality-pi.sh<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/bash\n\n# Start the airquality script\necho \"$(date)\"\necho \"... Starting airquality ...\"\npython3 airquality-pi.py<\/code><\/pre>\n\n\n\n<p>Telegraf file input example. Snippet from the \/etc\/telegraf.conf<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;&#91;inputs.file]]\n  files = &#91;\"\/opt\/airquality-pi\/bme680.csv\"]\n\n  data_format = \"csv\"\n  csv_header_row_count = 0\n  csv_column_names = &#91;\"timestamp\",\"temperature\",\"pressure\",\"humidity\",\"gas\"]\n  csv_skip_rows = 0\n  csv_skip_columns = 0\n  csv_delimiter = \",\"\n  csv_comment = \"#\"\n  csv_trim_space = true\n  csv_tag_columns = &#91;\"\"]\n  csv_measurement_column = \"\"\n  csv_timestamp_column = \"timestamp\"\n  csv_timestamp_format = \"2006-01-02T15:04:05Z\"\n<\/code><\/pre>\n\n\n\n<p>Also created a logrotate configuration for the CSV-files. Example for bme680.csv.<br>Create file \/etc\/logrotate.d\/bme680<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/opt\/airquality-pi\/bme680.csv\n{\n    rotate 5\n    daily\n    missingok\n    dateext\n    copytruncate\n    notifempty\n    compress\n}\n<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>Version of the used software:<br>Grafana version: 8.1.1<br>Influxdb2: 2.0.8<br>Telegraf: 1.19.2<br>Raspberry Pi 1B: Raspbian Linux v10<\/p>\n\n\n\n<p>There seem to be quite some projects about measuring airquality with a Raspberry Pi. It appears that the Nova Fitness SDS011 appears the more popular sensor.<br><\/p>\n\n\n\n<p>References:<br>\n<a href=\"https:\/\/learn.pimoroni.com\/tutorial\/sandyj\/getting-started-with-bme680-breakout\">https:\/\/learn.pimoroni.com\/tutorial\/sandyj\/getting-started-with-bme680-breakout<\/a><br>\n<a href=\"https:\/\/shop.pimoroni.com\/products\/pms5003-particulate-matter-sensor-with-cable\" data-type=\"URL\" data-id=\"https:\/\/shop.pimoroni.com\/products\/pms5003-particulate-matter-sensor-with-cable\">https:\/\/shop.pimoroni.com\/products\/pms5003-particulate-matter-sensor-with-cable<\/a><br>\n<a href=\"https:\/\/www.raspberrypi.org\/blog\/monitor-air-quality-with-a-raspberry-pi\/\" data-type=\"URL\" data-id=\"https:\/\/www.raspberrypi.org\/blog\/monitor-air-quality-with-a-raspberry-pi\/\">https:\/\/www.raspberrypi.org\/blog\/monitor-air-quality-with-a-raspberry-pi\/<\/a><br>\n<a href=\"https:\/\/www.samenmetenaanluchtkwaliteit.nl\/\">https:\/\/www.samenmetenaanluchtkwaliteit.nl\/<\/a><br> \n<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have been experimenting with the Raspberry Pi and the Bosch BME680 and Plantower PMS5003. With the BME680 you can measure temperature, air pressure, humidity, and VOC gas (Volatile Organic Compunds). With the PMS5003 particles can be measured. Also used a Telegraf agent, Influxdb2 and Grafana.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,9],"tags":[],"class_list":["post-537","post","type-post","status-publish","format-standard","hentry","category-linux","category-programming"],"_links":{"self":[{"href":"https:\/\/www.petersplanet.nl\/index.php\/wp-json\/wp\/v2\/posts\/537","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.petersplanet.nl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.petersplanet.nl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.petersplanet.nl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.petersplanet.nl\/index.php\/wp-json\/wp\/v2\/comments?post=537"}],"version-history":[{"count":29,"href":"https:\/\/www.petersplanet.nl\/index.php\/wp-json\/wp\/v2\/posts\/537\/revisions"}],"predecessor-version":[{"id":586,"href":"https:\/\/www.petersplanet.nl\/index.php\/wp-json\/wp\/v2\/posts\/537\/revisions\/586"}],"wp:attachment":[{"href":"https:\/\/www.petersplanet.nl\/index.php\/wp-json\/wp\/v2\/media?parent=537"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.petersplanet.nl\/index.php\/wp-json\/wp\/v2\/categories?post=537"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.petersplanet.nl\/index.php\/wp-json\/wp\/v2\/tags?post=537"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}