ericklein / air_quality Goto Github PK
View Code? Open in Web Editor NEWdisplays and logs local indoor and outdoor weather and air quality information
License: MIT License
displays and logs local indoor and outdoor weather and air quality information
License: MIT License
screenAlert can accept messages with lengths longer than available space. will need a better wrapping function than provided by .print.
MQTT publish (to Adafruit IO?) requires NTP to be defined?! No idea why.
refactor the code to allow local read and display to occur even if the network connection is not possible
Integrate BME 680 support. Test CO2 values vs SCD40.
use the arduinojson library filtering functions to reduce memory requirements by filtering what JSON data is desired from larger object.
Some devices are not updating their screens and data sources for hours or days at a time, but I do not understand why. The devices have sufficient battery charge. If they can not connect to the Internet, they are supposed to update the screen only and display an error message about the lack of connectivity. This is not happening.
Display temperature and humidity data as whole numbers
Most of the Adafruit ESP32 Feather boards have a technique for monitoring at least battery voltage. Can I create a LUT to determine battery percentage or use the LUT the LC709203 library uses? I think @disquisitioner has explored this idea?
Using the right side of the display. Same concept as the local trend displayed on the left side of the display. The only difference is the comparison of local inside data (from the device) to local outside data from Open Weather.
For both of the trend data features. It will be interesting to figure out what is the right amount of change in data to trigger a trend change. Perhaps we could experiment with 2% as a starting point across the board. Future research on what is meaningful delta could lead to an update of this reference point for different data. For example, 2% change in temperature roughly equates to 1.5*F, which isn't a huge change in a nominal interior of a home. However the same 2% change in CO2 or O2 might have much greater health consequences.
Outside developers can not see the structure of the MQTT feeds as currently are in secrets.h and therefore not published in github. Split non secrets into a config.h file that is published
there are optimizations for code ordering and error handling that are needed/possible for one time run that have an undetermined effect on the continuous loop implementation. It might not be possible to keep both implementations in the same code base with #define selection at compilation.
Suggestion is to create separate branches for both and optimize both branches
display current local weather from API or Adafruit IO on screen
in zuluDateTimeString switch the #ifdef NTP to instead check timeStatus() for timeNotSet
Battery levels displayed on screen are incorrect, appearing lower than they actually are. 18% is being visualized as ~ 10% in the graphic.
Log RSSI on each connection to device data on all data services.
implement deepsleep() for ONETIME implementations using an ARM MCU
Add spark lines to display CO2 history
Integrate PM 2.5 sensor data
Move local MQTT server to DNS named entry instead of IP address so DNS can resolve it if IP address changes
Currently sensor readings are converted to integers as part of acquiring values from the sensors (both attached sensors and through getWeather(). That's probably fine for what's shown on the display, but causes loss of precision given most of our sensors are more accurate than that, the data is now also being shared with other services (e.g., MQTT and Dweet), and we've also talked about adding database support to store values for subsequent analysis, alert triggers, IFTTT, etc.
I propose we store data internally as floating point wherever relevant and convert it to integer or fixed point wherever necessary -- in the code that displays values on the eInk display, before they get sent to other services, etc.
This would require changing the envData typedef/struct to use floats rather than uint16_t, at least for temperature and humidity values. (Our current CO2 sensor returns readings as an integer, so CO2 values could stay uint16_t.) There would be minimal change in readSensor() and getWeather() as in most cases conversion from the floating point sensor values to integers happens implicitly via the compiler through assignment. (The exception here is temperature, which gets converted from C to F and then cast as an integer.) Some change would also be needed to infoScreen() to properly format floats as integers (or fixed precision) for display.
I like the idea that we'd retain whatever values sensors provide as our internal data model and let any code using that data for display, sharing, export, storage, alerts, etc. do the right math at the point of use, whatever that may turn out to be (and which they know best anyhow).
Get time from Adafruit IO: https://io.adafruit.com/blog/feature/2016/06/01/time-utilities/
Move CO2 definitions to config.h
version : influx_v1_v2 that will be promoted to master.
reproduced on two separate installs.
this could be an issue given I've been editing the sensor code in this branch and perhaps I introduced the problem, or it is inherent in this branch. Let's evaluate once we've integrated into master
Most http.get error codes will not return a payload, but aq_network.httpGETRequest() pretends to send something back. aq_network.httpGETRequest() was based on some anemic sample code without error handling, which we need to review or add.
handle MQTT broker errors https://io.adafruit.com/blog/example/2016/07/06/mqtt-error-reporting/
This error condition is not currently handled in the code.
If the LC709203 is not detected, the client code will not run. This should not be FATAL because if the battery runs down but we can't detect it, the backend will not receive sensor values over an extended window causing a different backend error which will alert owner to the underlying issue.
Need a routine to clear nv storage in the case of the value pool being incorrect and there is a need for accurate data to be uploaded. If given enough time, the averages will clean themselves of errant values, but if time to report accurate values is critical, we could add a routine to remove all values and let the code restart building the averages.
Display sample interval (SAMPLE_SIZE*SAMPLE_INTERVAL) to customers so the delta values inside the () on the display make sense
transition all Serial.println to debugMessage()
Add support for dweet.io, which provides a free cloud service for devices to publish messages and information, This would make it easy to see the most recent sensor readings, information about the device itself (e.g., WiFi RSSI and IP address) and even error/status messages. Uploads happen via an HTTP POST and JSON, which is easy to add given we already have HTTP connectivity support in the app.
Move from Arduino official JSON library to library used by almost all developers
Sample size = 1 breaks the averaging logic because /SAMPLE_SIZE is dividing by 1.
OLED screen is on all the time, which could cause OLED burn in, and in dark environments, is very bright. Could be addressed by time based or gesture based dimming function.
Display trend information on display in 12hrs, 24hrs, and 72hrs modes. For the purpose of prototyping, we could use these symbols to represent the data:
"/" trend up - data is trending up compared to the previous time segment
"" trend down - data is trending down compared to the previous time segment
"-" trend even - data is even compared to the previous time segment.
12 segment is all we need at this time. In 12hrs mode, each segment represents average sample data for one hour. In 24hrs mode, each segment represents average sample data for two hours. In 72hrs mode, each segment represents average sample data for six hours.
If we stay with the current three lines format on the display. Using the left side of the display. The top line would be 12hrs mode, the mid line would be 24hrs mode, the bottom line would be 72hr mode.
Delta triggers from [https://github.com//issues/7]
Temp changes by 1 degree F
Humidity changes by 1%
CO2 level changes by 25
Example: Adafruit Feather ESP32S2 board voltage is ~ 3.7v. LC709203F returns 3.71V when no battery is attached but USB power is attached. This leads to an incorrect battery display of ~14% battery life.
I've failed at compressing zuluDateTimeString() twice, what is the issue relative to string buildout?
sensor value = 66.32
averaged value (from total sample set) is 66.52
This is an edge case where subtracting the rounded (+.5) (int) of these values yields -1 even though the temperature did not change 1 degree.
Solution is likely to (int) the base values and look for >1 movement.
Display local, outside air quality (PM 2.5 reading)
Could one use the timezone from OWM data to automatically set the time zone in the NTP set function?
SCD40 is samping ~ 4F higher than external sensor sitting next to it. Need to check with calibrated sensor to determine which sensor is inaccurate, and if SCD40, look for calibration API
days instead of weeks. Correlated in time frame to integration of new code and SCD40
Add a unified message manager that handles debug, alert, and fatal messages across serial monitor, LED, screen, and (mqtt) logging.
When CO2 sensor is not available, AQ uses the convention of setting sensorData.internalCO2 to 10000. DWEET will attempt to push CO2 values even when there is no sensor reading it, so it will push 10000 upstream. Is that the intended behavior?
Routines looking for a missing temp/humidity sensor look for sensorData.internalTemp == 10000, though there is no place in the code that sets this. The code moved to deepSleep() when a sensor is not available (see if the problem goes away on its own) so these ==10000 dependencies need to be addressed.
Only log data (MQTT, SD, etc.) when:
Temp changes by 1 degree F
Humidity changes by 1%
CO2 level changes by 25
post_dweet() has WiFi connection check but not for Ethernet. It might be better to say we need a generic handler to check Internet status?
Need to look at error handling for display.begin()
when the environment sensor is not detected, the screen is updated with an error message, and the device goes to sleep. When it returns from sleep and the sensor is working, sampling starts again, but the screen is not updated to indicate that the device is actually working.
Review the NTP setup code for use of while until loop. NTP should fail through rather than infinitely waiting
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.