{"id":21112499,"url":"https://github.com/illuusio/voccer","last_synced_at":"2026-05-19T11:32:43.770Z","repository":{"id":71257275,"uuid":"177383975","full_name":"illuusio/voccer","owner":"illuusio","description":"Small Python3 based utility to send tVOC, eCO2 and Particulate Matter to MQTT server","archived":false,"fork":false,"pushed_at":"2023-09-26T07:59:38.000Z","size":56,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-14T10:11:24.467Z","etag":null,"topics":["air-quality","bme680","eco2","fluentd","gas","monitor-tvoc","mqtt","plantower","plantower-sensor","pms5003","sgp30","tvoc","voc"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/illuusio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2019-03-24T07:33:06.000Z","updated_at":"2023-09-26T07:59:44.000Z","dependencies_parsed_at":"2023-10-02T05:15:00.164Z","dependency_job_id":null,"html_url":"https://github.com/illuusio/voccer","commit_stats":{"total_commits":32,"total_committers":2,"mean_commits":16.0,"dds":0.03125,"last_synced_commit":"0d32a4c61e9bce85b6e9289ab84e88252d5e6d61"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/illuusio/voccer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illuusio%2Fvoccer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illuusio%2Fvoccer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illuusio%2Fvoccer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illuusio%2Fvoccer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/illuusio","download_url":"https://codeload.github.com/illuusio/voccer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illuusio%2Fvoccer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33214317,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-19T07:54:09.561Z","status":"ssl_error","status_checked_at":"2026-05-19T07:54:08.508Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["air-quality","bme680","eco2","fluentd","gas","monitor-tvoc","mqtt","plantower","plantower-sensor","pms5003","sgp30","tvoc","voc"],"created_at":"2024-11-20T01:29:38.022Z","updated_at":"2026-05-19T11:32:43.751Z","avatar_url":"https://github.com/illuusio.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Voccer\nSmall Python3 based utility to send tVOC, eCO2, Particulate Matter with Bosch BME680, AMS CCS811, Sensirion SGP30 and Plantower PMS5003\nmeasurements to MQTT server\n\nFirst of all read this:\n**Please note, this sensor, like all VOC/gas sensors, has variability and to\nget precise measurements you will want to calibrate it against known sources!**\n\nThis means that you can monitor as much as you can but if you don't know your\nbaseline then you can't get any good measurements. Project is bit HaX0ur so\nthere is rough points that you need to fill and everyone is free to commit\nPull Requests to full fill this README.md documentation.\n\nCurrently Voccer is work in process and it can change every commit\n\nIt's tested with these break-out boards and sensors\n\n * [Adafruit SGP30 Air Quality Sensor Breakout - VOC and eCO2](https://www.adafruit.com/product/3709)\n * [BME680 Breakout - Air Quality, Temperature, Pressure, Humidity Sensor BME680 Breakout - Air Quality, Temperature, Pressure, Humidity Sensor](https://shop.pimoroni.com/products/bme680-breakout)\n * [SparkFun Air Quality Breakout - CCS811](https://www.sparkfun.com/products/14193)\n * [PMS5003 Particulate Matter Sensor Breakout](https://shop.pimoroni.com/products/particulate-matter-sensor-breakout) and [PMS5003 Particulate Matter Sensor with Cable](https://shop.pimoroni.com/products/pms5003-particulate-matter-sensor-with-cable)\n\nAs noticed they both I2C based so one has to have skills to make them work\nwith Raspberry Pi you need to have module *i2c-dev* loaded before using\nPython libraries. If you can see them in I2C-bus with *i2c-detect* then they\nshould work.\n\nMost of the python libraries can be found with Python pip package manager\n**CCS811 doesn't play well with Raspberry Pi. You need Arduino UNO to use CCS811**\n\n**As said earlier: it's up to you make sensors work**\n\n## Commandline args\n | Arg | what                       | preset    |\n |-----|----------------------------|-----------|\n | -h  | Help                       |           |\n | -s  | Sensor ID                  | 1         |\n | -t  | Temp offset for BME680     | 0         |\n | -e  | Enable sensor              | Nothing   |\n | -m  | MQTT server address        | localhost |\n | -p  | MQTT server port           | 1883      |\n\n## Commandline example \n```\npython3 voccer.py --enable=bme680:2,bme680:4,sgp30:2,pms5003:1,css811:5\n```\nWhich enables first address BME680 (0x76) with ID 2, second address BME680 (0x77) with ID 4, SGP30 with ID 2\nand PMS5003 with ID 1\n\n## Getting started with BME680\n\n * [Getting Started with BME680 Breakout](https://learn.pimoroni.com/tutorial/sandyj/getting-started-with-bme680-breakout)\n * [Pimoroni BME680 Github](https://learn.pimoroni.com/tutorial/sandyj/getting-started-with-bme680-breakout)\n\n## Getting started with SGP30\n\n * [Python library for reading co2 and TVOC from the Sensirion SGP30 ](https://pypi.org/project/sgp30/)\n\n## Getting started with CCS811\n\nIn subdirecotory ccs811_arduino is application which you need to compile and upload to Arduino UNO.\nAfter that your Arduino UNO has to be attached to Raspberry Pi (or machine you like use) with USB cable.\nThen it should work. It outputs CSV so if you just log CCS811 (or two of them) then you can just log\nserial port to file and analyze with Libreoffice or similar.\n\nPlease note that it takes 2 IDs from MQTT if you use two CSS811 sensors.\n\n**NOTE! You have to have correct rights to read serial port in your machine.**\n\n## Getting started with PMS5003\n\n * [PMS5003 Particulate Sensor](https://github.com/pimoroni/pms5003-python)\n\n## JSON\nJSON that script outputs to MQTT looks like this\n```\n{\"timestamp\": 1553413797.78, \"id\": 1, \"value\": 19.23, \"type\": \"temperature\", \"typeid\": 100, \"unitid\": 100}\n```\n\n## Types\nAll those numbers in typeid and unitid are just numbers started from 100.\n \n | ID  | Type                            | Unit    | UnitID |\n |-----|---------------------------------|---------|--------|\n | 100 | temperature                     | Celsius | 100    |\n | 101 | humidity                        | RH%     | 101    |\n | 102 | pressure                        | hPa     | 102    |\n | 103 | AiQ                             | AiQ     | 103    |\n | 104 | Resistance                      | Gas     | 104    |\n | 105 | tVOC                            | ppm     | 105    |\n | 106 | eCO2                            | ppm     | 105    |\n | 107 | Particle PM1                    | ug/m3   | 107    |\n | 108 | Particle PM2.5                  | ug/m3   | 107    |\n | 109 | Particle PM10                   | ug/m3   | 107    |\n | 110 | Atmospheric particle PM1        | ug/m3   | 107    |\n | 111 | atmospheric particle PM2.0      | ug/m3   | 107    |\n\n## Listening JSON from MQTT server\nand you can listen them with for example [Mosquitto MQTT-project](http://mosquitto.org/) tool *mosquitto_sub*\n```\nmosquitto_sub -t /sensor/voccer/2.0/+\n```\n\n# Setting up Fluentd\nThere is several servers which can log these into database like [Fluentd](https://www.fluentd.org/) and\n[Telegraf](https://github.com/influxdata/telegraf) for example.\nIf you choose to use Fluentd you need [Fluent plugin for MQTT Input/Output](https://github.com/toyokazu/fluent-plugin-mqtt-io) and if\nyou like to log to database like MySQL or MariaDB then you need [SQL input/output plugin for Fluentd](https://github.com/fluent/fluent-plugin-sql)\n**As Raspbian doesn't support Ruby very you are mostly out of luck just use Pure Raspberry Pi solution**\n\n## MySQL table setup\nProject doen't currently provice SQL-statement to create table but it's like this\n\n| Field      | Type \t           | Null |  Key | Default | Extra          |\n|------------|---------------------|------|------|---------|----------------|\n| id         | bigint(20)          | NO   | PRI  | NULL    | auto_increment |\n| unitType   | tinyint(4) unsigned | NO   |      | 0       |                |\t\n| sensorId   | tinyint(4) unsigned | NO   |      | 0 \t   |                |\n| sensorType | tinyint(4) unsigned | NO   |      | 0 \t   |                |\n| time       | int(11)             | NO   |      | 0       |                |\n| value      | double              | NO   |      | 0       |                |\n\n## Fluentd setup\nThere is good documentation for Fluentd configuration but this is simple config file\nto get Voccer logging working\n```\n# In v1 configuration, type and id are @ prefix parameters.\n# @type and @id are recommended. type and id are still available for backward compatibility\n\n\u003csource\u003e\n  @type mqtt\n  host 127.0.0.1\n  port 1883\n  topic /sensor/voccer/2.0/+\n  \u003cparse\u003e\n    @type json\n  \u003c/parse\u003e\n\u003c/source\u003e\n\n\u003cmatch .sensor.voccer.2.0.**\u003e\n  @type sql\n  host localhost\n  port 3306\n  database voccer\n  adapter mysql2\n  username voccer\n  password voccer\n  remove_tag_prefix .sensor.voccer.2.0\n\n  \u003ctable\u003e\n    table measurement\n    column_mapping 'timestamp:time,unitid:unitType,id:sensorId,typeid:sensorType,value:value'\n  \u003c/table\u003e\n\u003c/match\u003e\n```\n\n# Grafana setup\n[Grafana](https://grafana.com/) is state of art visualition tool and suits to this purpose very well\nafter installing and creating dashboard with MySQL connector one can create SQL query statement for Panel\nlike this\n```\nSELECT\n  time AS \"time\",\n  value AS value\nFROM measurement\nWHERE\n  $__unixEpochFilter(time) AND\n  sensorType = 100 AND\n  sensorId = 1\nORDER BY time\n```\nAnd it will start drawing temperature panel for sensor 1.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filluusio%2Fvoccer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Filluusio%2Fvoccer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filluusio%2Fvoccer/lists"}