Skip to content

Commit

Permalink
Many doc-updates.
Browse files Browse the repository at this point in the history
  • Loading branch information
EricLauber committed Nov 23, 2023
1 parent 610d422 commit acf008f
Show file tree
Hide file tree
Showing 14 changed files with 181 additions and 46 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# AirGradient MQTT for Arduino

<img src="./assets/images/airgradient.png" align="right" width="200">

This is an Arduino software implementation for the AirGradient DIY Air Quality Sensor Pro, PCB version 4.2.

The base configuration for an AirGradient product is for it to log data to AirGradient's servers. This sketch augments that functionality with MQTT capabilities to log data to a server of your choice.
Expand Down
Binary file added docs/assets/images/airgradient.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/images/aqi_meter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/images/arduino_ide_aunit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/images/diypro42kit.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions docs/assets/images/mqtt-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 5 additions & 3 deletions docs/homeassistant.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ mqtt:
## Visualization
Here are two sample visualizations I build for Home Assistant. TODO - add screenshots.
Here are two sample visualizations I build for Home Assistant.
AQI Gauge Card
### AQI Gauge Card
<img src="../assets/images/aqi_meter.png" align="right">
```yaml
type: gauge
Expand All @@ -85,7 +87,7 @@ segments:
color: '#a2064a'
```
Metrics List
### Metrics List
```yaml
type: entities
Expand Down
56 changes: 56 additions & 0 deletions docs/implementation/configstatemachine.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Startup Config State Machine

Typically when the AirGradient is powered on it will cycle through a few general steps:

- Warming up the sensors
- Connecting to a saved WiFi Access Point or hosting its own AP for config purposes
- Beginning operation

If the user holds the push button on the back of the AirGradient while powering it on, it will enter the Config State Machine. A short press (essentially a click) will cycle through the options. A long press (greater than 4 seconds) will select the current option. The display on the front of the AirGradient will indicate which state it is currently in.

## Select an Option

These are the initial states that the AirGradient will run through:

```mermaid
stateDiagram
direction LR
SelectState: Select State
EditConfigState: Edit Display Config State
ClearState: Clear Config and WiFi Data State
RebootState: Reboot State
[*] --> SelectState
SelectState --> EditConfigState
EditConfigState --> ClearState
ClearState --> RebootState
RebootState --> SelectState
```

| State | Description |
| :--- | :--- |
| **Select State** | This state lets the user know they are in the Config State Machine and that they should cycle through and select an option.|
| **Edit Display Config State** | Long-pressing this state will enter the Display Config flow - [see the section below for details](./#edit-the-display-configuration).|
| **Clear Config and WiFi Data State** | Long-pressing this state will clear the local storage, erasing the saved Display Config State, WiFi configuration, and MQTT configuration.|
| **Reboot State** | Long-pressing this state will restart the AirGradient equivalent to disconnecting and reconnecting the power. User should choose this to exit the flow.|

## Edit the Display Configuration

If users long-press the **Edit Display Config State** they will enter this flow. The user may select what the Display should show during regular operation. Short-pressing will cycle through each option. Long-pressing on an option will save that to the local storage, and return the user to the **Select State** from the [previous flow](./#select-an-option).

```mermaid
stateDiagram
direction LR
DisplayConfigTempCμgm3: Celsius and μgm3
DisplayConfigTempFμgm3: Fahrenheit μgm3
DisplayConfigTempCAQI: Celsius and US AQI
DisplayConfigTempFAQI: Fahrenheit and US AQI
[*] --> DisplayConfigTempCμgm3
DisplayConfigTempCμgm3 --> DisplayConfigTempFμgm3
DisplayConfigTempFμgm3 --> DisplayConfigTempCAQI
DisplayConfigTempCAQI --> DisplayConfigTempFAQI
DisplayConfigTempFAQI --> DisplayConfigTempCμgm3
```
8 changes: 8 additions & 0 deletions docs/implementation/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Implementation Details

Todo

- Talk about domain objects
- interfaces and DI
- switchboard file and the few global variables
- how to update or replace components
4 changes: 2 additions & 2 deletions docs/implementationdetails.md → docs/implementation/rtti.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
## Impementation Details - RTTI
# Run-Time Type Information

For this sketch I tried to implement and apply Object Oriented Programming techniques were it made sense. I had thought I might reuse the State Machine concept, and built `MachineBase` and `StateBase` to be extendable.

The different `ConfigStateMachine` states like `ClearState` implement `StateBase` and its references to `MachineBase`, but require awareness of the `ConfigStateMachine` in order to write to the OLED display. To do this, `ClearState` requires Run-time type information (RTTI) so that it can `dynamic_cast<>` a `MachineBase` to `ConfigStateMachine`.
The different `ConfigStateMachine` states like `ClearState` implement `StateBase` and its references to `MachineBase`, but require awareness of the `ConfigStateMachine` in order to write to the OLED display. To do this, `ClearState` requires Run-Time Type Information (RTTI) so that it can `dynamic_cast<>` a `MachineBase` to `ConfigStateMachine`.

Many embedded systems do not support RTTI, and for this reason the Arduino compiler disables it by default. An ESP8266 **can** support RTTI, but to provide Arduino support, the ESP Arduino core implementation avoids its use and implements `TypeConversionFunctions` combined with Enums. Applied to our case, `MachineBase` gets a `MachineType` Enum. Other objects and classes can read the Enum and determine what type the `MachineBase` implementation it is.

Expand Down
15 changes: 14 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
# AirGradient for Arduino using MQTT

<img src="./assets/images/airgradient.png" align="right" width="200">

This is an Arduino software implementation for the AirGradient DIY Air Quality Sensor Pro, PCB version 4.2.

<br/><br/>
<img src="./assets/images/mqtt-logo.svg" align="right" width="200">

The base configuration for an AirGradient product is for it to log data to AirGradient's servers. This sketch augments that functionality with MQTT capabilities to log data to a server of your choice.

I've developed this software to be object oriented. I've applied several modern programming practices such as SOLID and automated testing to a degree that I thought made sense.
With this implementation you get:

- MQTT support with the option to continue using AirGradient's data logging.
- An object-oriented implementation that tries to follow SOLID to make it easier to extend.
- Automated test coverage built with [AUnit](https://github.com/bxparks/AUnit) and run using [EpoxyDuino](https://github.com/bxparks/EpoxyDuino) to simulate the behavior of real hardware and facilitate Continuous Integration.

<img src="./assets/images/diypro42kit.jpg" align="left" width="250">

AirGradient products are professional, accurate, long-lasting air quality monitors that are open-source and open-hardware. Through Arduino sketches like this one, you're free to upgrade your AirGradient's functionality and tweak it how you see fit.
48 changes: 47 additions & 1 deletion docs/setup.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,53 @@
# Getting Started

1. Download and Install the [Arduino IDE](https://www.arduino.cc/en/software), [Arduino CLI](https://arduino.github.io/arduino-cli/0.19/installation/), or [VS Code](https://code.visualstudio.com/) with the [Arduino extension](https://marketplace.visualstudio.com/items?itemName=vsciot-vscode.vscode-arduino) to your system.
## Flashing this firmware to your AirGradient

1. Setup your environment by downloading and installing one or more of the following options:
1. [Arduino IDE](https://www.arduino.cc/en/software)
1. [Arduino CLI](https://arduino.github.io/arduino-cli/0.19/installation/)
1. [VS Code](https://code.visualstudio.com/) with the [Arduino extension](https://marketplace.visualstudio.com/items?itemName=vsciot-vscode.vscode-arduino) to your system.
1. Clone this repo or download the latest release (a zip of the source code).
1. Open `airgradient_mqtt.ino` with your chosen Arduino tools.
1. Install all required Arduino reference libraries.
1. Plug in the microcontroller for your AirGradient (such as an ESP8266 Wemos LOLIN D1 mini) and upload the sketch to the controller.

## Automated Tests

This project leverages [AUnit](https://github.com/bxparks/AUnit) to facilitate building automated tests and [EpoxyDuino](https://github.com/bxparks/EpoxyDuino) to mock an Arduino on a PC and run continuous integration.

### Setting up your environment

I ran tests using Windows Subsystem for Linux (WSL). Follow these steps to get started - you may be able to skip several steps on a standard Linux distro or macOS.

<img src="../assets/images/arduino_ide_aunit.png" align="right">

1. Install the AUnit library within the Arduino environment of your choice.
1. [Setup and configure WSL](https://learn.microsoft.com/en-us/windows/wsl/install).
1. At the time of this running, the provided Ubuntu distro requires an `apt update` before proceeding.
1. EpoxyDuino requires a C++ compiler and make. Add them to your install with `apt install g++` and `apt install make`.
1. Clone the [EpoxyDuino](https://github.com/bxparks/EpoxyDuino) repo and place it within the `user/Documents/Arduino/libraries` folder (this is not a required location, but this project is setup assuming EpoxyDuino is located here).
1. Add a `.env` file to the root of this project with the following format:

```bash
arduino_ide_dir=LOCATION_OF_ARDUINO_IDE
```

### Running tests

You are now ready to build and compile and run the tests. Follow these instructions to run all tests from the root of this project. I prefer to use the WSL terminal within VS Code for this purpose.

```bash
$ make -C tests clean

$ make -C tests tests
$ make -C tests runtests | grep failed
```

Alternatively, you can browse to the subfolder containing a specific subset of tests and run those directly.

```bash
$ make clean

$ make
$ make run
```
37 changes: 0 additions & 37 deletions docs/tests.md

This file was deleted.

8 changes: 6 additions & 2 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ theme:

# - navigation.tabs.sticky

- toc.follow

# Extensions
markdown_extensions:
- pymdownx.superfences:
Expand All @@ -52,8 +54,10 @@ nav:

- Implementation:
- Getting Started: setup.md
- Details: implementationdetails.md
- Automated Tests: tests.md
- Details:
- implementation/index.md
- Run-Time Type Information: implementation/rtti.md
- Startup State Machine: implementation/configstatemachine.md

- Integrations:
- 'Home Assistant': homeassistant.md
Expand Down

0 comments on commit acf008f

Please sign in to comment.