Toggle Navigation
Hatchery
Eggs
sensible_card10
README.md
Users
Badges
Login
Register
MCH2022 badge?
go to mch2022.badge.team
README.md
raw
Content
# sensible card10 _Broadcast BME680 sensor readings of your card10 badge as BLE advertisements._ **[on Codeberg](https://codeberg.org/scy/sensible-card10) | [in the badge hatchery](https://badge.team/projects/sensible_card10)** ## What is it? This is an application designed for the [card10 badge](https://card10.badge.events.ccc.de/) that will broadcast the readings of its on-board [BME680 sensor](https://firmware.card10.badge.events.ccc.de/epicardium/api.html#bme680) using Bluetooth Low Energy (BLE) advertisement packets. These readings consist of * Temperature * Relative humidity * Atmospheric pressure * IAQ, a value measuring the indoor air quality * IAQ accuracy (i.e. how well the sensor thinks it’s calibrated) * Estimated CO₂ in the air (derived from the IAQ; the BME680 sensor cannot measure CO₂ directly) * Charge left in your card10’s battery ## Installation Create a folder inside of `apps` on your card10’s USB drive, place the contents of this repository (or at least `__init.py__` and `metadata.json`) there. For details, see [the card10 docs section on app installation](https://card10.badge.events.ccc.de/userguide/general-usage/#installing-apps-via-usb). ## Usage Start the application. Your display will turn off to conserve power (and because it’s an open task for me to display something useful). You’ll notice that the blue rocket (left of the display) will blink faintly about every 3 seconds to let you know that the card10 is broadcasting. If your battery is at 20 % or less, red LEDs will blink every 3 seconds to make you aware of this. The top row of LEDs will show a red “charge left” bar slowly depleting. You can press the menu button as usual to exit the app. ## Status It’s working, but there’s no UI yet. I’d like to display the values on the screen, with a button to turn the screen off. ## Data structure The advertisement packet will contain two things: * The current sensor readings, as an element of type `0x16` (“service data”) with a service UUID of `0x181a` (“environmental sensing”). * A name element (type `0x09`) containing the string `card10` to help you identify the card10 in scan results. Note that Bluetooth values, UUIDs, etc. are transmitted in [little-endian byte order](https://en.wikipedia.org/wiki/Endianness). Also note (if your library doesn’t help you with it) that advertisement data elements are prefixed by their size in bytes. The actual sensor readings in the service data element are all integers, encoded like this: * Magic number `0xccc1`. The `1` may change in the future, should there be a new version of the data structure. * Temperature (16-bit signed) in centidegrees Celsius (`123` meaning 1.23 °C). * Humidity (16-bit unsigned) in centi-percent (`123` meaning 1.23 %). * Pressure (32-bit unsigned) in deci-Pascal (`123` meaning 12.3 Pa). * IAQ accuracy (8-bit unsigned, see also [the API docs](https://firmware.card10.badge.events.ccc.de/epicardium/api.html#c.bsec_sensor_data.accuracy)), with the values meaning * `0`: sensor warm-up (takes about 5 minutes) * `1`: sensor not calibrated, low accuracy (takes about 10 hours initially) * `2`: sensor re-calibrating, medium accuracy (happens occasionally, takes tens of minutes) * `3`: sensor calibrated, high accuracy * `255`: proprietary BSEC library disabled (see [`card10.cfg`](https://firmware.card10.badge.events.ccc.de/card10-cfg.html#card10-cfg)); IAQ and eCO₂ will be unavailable and set to zero. * IAQ (16-bit unsigned) from 0 (best) to 500 (worst), see page 10 of the [BME680 datasheet](https://git.card10.badge.events.ccc.de/card10/hardware/-/blob/master/datasheets/bosch/BST-BME680-DS001.pdf) for a description of these values. * Estimated CO₂ equivalents (16-bit unsigned) in parts per million. * Battery charge left (8-bit unsigned) in percent. Values greater than `100` are reserved for future use (e.g. to signal “plugged in”). I’ve tried to keep the type of each of the values identical or at least similar to the [ESS](https://firmware.card10.badge.events.ccc.de/bluetooth/ess.html#ble-service). ## Integration into ESPHome This is an example of how to access these values from [ESPHome](https://esphome.io/)’s [BLE tracker](https://esphome.io/components/esp32_ble_tracker.html). Note that my C++ skills are rudimentary at best, which is why even the unsigned values will be interpreted as being signed here. Please let me know how to fix this. 🙈 ```yaml esp32_ble_tracker: scan_parameters: active: false # Only listen for advertisements, no active scans. interval: 42ms window: 23ms on_ble_service_data_advertise: - mac_address: CA:4D:10:11:22:33 # Replace with your card10’s Bluetooth MAC address. service_uuid: 181A then: - lambda: |- // TODO: cast uint values to be actually unsigned id(card10_temp).publish_state((x[2] + (x[3]<<8)) / 100.0); id(card10_hum).publish_state((x[4] + (x[5]<<8)) / 100.0); id(card10_press).publish_state((x[6] + (x[7]<<8) + (x[8]<<16) + (x[9]<<24)) / 1000.0); if (x[10] != 0xff) { // BSEC data available id(card10_iaq_acc).publish_state(x[10]); id(card10_iaq).publish_state(x[11] + (x[12]<<8)); id(card10_eco2).publish_state(x[13] + (x[14]<<8)); } id(card10_bat).publish_state(x[15]); sensor: - id: card10_temp name: card10 Temperature platform: template unit_of_measurement: "°C" accuracy_decimals: 2 filters: - throttle_average: 10s - filter_out: nan state_topic: card10/temperature_c - id: card10_hum name: card10 Humidity platform: template unit_of_measurement: "%" accuracy_decimals: 2 filters: - throttle_average: 10s - filter_out: nan state_topic: card10/humidity_pct - id: card10_press name: card10 Pressure platform: template unit_of_measurement: "hPa" accuracy_decimals: 2 filters: - throttle_average: 10s - filter_out: nan state_topic: card10/pressure_hpa - id: card10_iaq_acc name: card10 IAQ Accuracy platform: template unit_of_measurement: "" accuracy_decimals: 0 filters: - throttle: 10s - filter_out: nan state_topic: card10/iaq_accuracy - id: card10_iaq name: card10 IAQ platform: template unit_of_measurement: "" accuracy_decimals: 0 filters: - throttle_average: 10s - filter_out: nan state_topic: card10/iaq - id: card10_eco2 name: card10 eCO₂ platform: template unit_of_measurement: "ppm" accuracy_decimals: 0 filters: - throttle_average: 10s - filter_out: nan state_topic: card10/eco2_ppm - id: card10_bat name: card10 Battery platform: template unit_of_measurement: "%" accuracy_decimals: 0 filters: - throttle: 10s - filter_out: nan state_topic: card10/sensor_battery_pct ``` ## Q & A ### How is this different from the Environmental Sensing Service? The [ESS](https://firmware.card10.badge.events.ccc.de/bluetooth/ess.html) (available on firmware 1.17 and newer) basically exposes the same values. The difference is: * With the ESS, you have to create a bi-directional connection to the card10 in order to retrieve the values. This consumes more battery power on both the card10 and the device you’re connecting from. * You can only use the ESS after pairing. * The ESS is encrypted, as far as I can tell. * Reading the advertisement data provided by _sensible card10_ might be easier to do in the Bluetooth library you’re using than to go through the pairing process and opening a connection. If you’re not too concerned about privacy implications of broadcasting the sensor values, _sensible card10_ might make it easier for you to access the sensor data. ### Why the name? Because SENSors via BLE. So clever of me. ### I have another question or suggestion! Feel free to open an [issue on Codeberg](https://codeberg.org/scy/sensible-card10/issues).